Example Session Indicators framework

novaleaf
Posts: 49
Joined: 17 Apr 2014
Has thanked: 9 times
Been thanked: 4 times

Example Session Indicators framework

Postby novaleaf » 04 May 2015

code I wrote for constructing session-level indicators. can be the starting point for your own more elaborate stuff.

Code: Select all

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;

namespace PowerLanguage.Indicator
{
   /// <summary>
   /// our custom indicators for the current and previous sessions
   ///
   /// </summary>
   public class SLE_Session_Indicators : IndicatorObject
   {


      public class SessionData
      {
         public double high;
         public double low;
         public double open;
         public double close;
         public double volume;
         public DateTime startTime;
         public DateTime endTime;

         public SessionData(DateTime startTime, double open, double volume)
         {
            this.open = open;
            this.startTime = startTime;
            this.volume = volume;

            //fill in initial (placeholder) values
            this.high = this.open;
            this.low = this.open;
            this.close = this.open;

            this.endTime = default(DateTime);
         }
      }

      public SLE_Session_Indicators(object _ctx) : base(_ctx) { }

      private DateTime _prevBarTime;

      /// <summary>
      /// index to map a bar to it's session values.
      /// example:  var yesterdaySession = sesInd.dailyData[sesInd.sessionIndex[0]-1];
      /// example: var currentSession = sesInd.dailyData[sesInd.sessionIndex[0]];
      /// example: var dayBeforeYesterdaySession = sesInd.dailyData[sesInd.sessionIndex[0]-2];
      /// </summary>
      public VariableSeries<Int32> sessionIndex;
      public List<SessionData> sessionData;

      //charting of values

      private IPlotObject p_currentVolume;
      private IPlotObject p_currentLow;
      private IPlotObject p_lastVolume;
      private IPlotObject p_lastLow;


      protected override void Create()
      {
         this.sessionIndex = new VariableSeries<int>(this);
         //test plotting: volume
         p_currentVolume =
            AddPlot(new PlotAttributes("CurrentVolume", EPlotShapes.LeftTick,
                                 Color.DarkGoldenrod, Color.Empty, 2,
                                 0,
                                 true));
         p_lastVolume =
            AddPlot(new PlotAttributes("LastVolume", EPlotShapes.LeftTick,
                                 Color.Yellow, Color.Empty, 2,
                                 0,
                                 true));
         //test plotting: low
         p_currentLow =
            AddPlot(new PlotAttributes("CurrentLow", EPlotShapes.LeftTick,
                                 Color.MediumAquamarine, Color.Empty, 2,
                                 0,
                                 true));
         p_lastLow =
            AddPlot(new PlotAttributes("LastLow", EPlotShapes.LeftTick,
                                 Color.Aqua, Color.Empty, 2,
                                 0,
                                 true));
      }
      protected override void StartCalc()
      {
         // reset variables
         this.sessionData = new List<SessionData>();
         this._prevBarTime = default(DateTime);

         //at start calculation, need to retroactively walk our history to do calcs to it, starting with the furthest bar back.
         for (var i = this.ExecInfo.MaxBarsBack; i > 0; i--)
         {
            this.DoCalc(i);
         }
      }

      protected override void CalcBar()
      {
         //do calc for the current bar (barIndex=0)
         this.DoCalc(0);
      }

      private void DoCalc(int barIndex)
      {
         //only compute if daily or finer.
         EResolution resolution = Bars.Info.Resolution.Type;
         if (resolution == EResolution.Quarter ||
            EResolution.Week <= resolution && resolution <= EResolution.Year) return;

         var barTime = this.Bars.Time[barIndex];
         var prevBarEndedSession = this._prevBarTime.Date.Equals(barTime.Date) ? false : true;
         //var barSessionIndex = Math.Max((int)barTime.DayOfWeek - 1, 0);         

         //Output.WriteLine("SI: {0} @ {1}, lbis={2}, pbes={3}", this.Bars.Info.Name, this.Bars.Time[barIndex].ToString(), this.Bars.LastBarInSession.ToString(), this._prevBarEndedSession.ToString());

         //create current bar if new session
         if (this.sessionData.Count == 0 || prevBarEndedSession == true)
         {
            if (this.sessionData.Count >= 1)
            {
               //set the end time for last session
               var lastSession = this.sessionData.Last();
               lastSession.endTime = this._prevBarTime;


               //verify we set end time for last session properly
               SLE_Utils.Assert(lastSession.endTime > lastSession.startTime, "appear to not set endTime!!   starTime={0}, endTime={1}, currentTime={2}, barIndex={3}", lastSession.startTime.ToString(), lastSession.endTime.ToString(), this.Bars.Time[barIndex], barIndex);
               if (lastSession.startTime == lastSession.endTime)
               {
                  Output.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! session only 1 frame!   {0} @ {1}", this.Bars.Info.Name, lastSession.startTime);
               }

            }
            //create new bar
            this.sessionData.Add(new SessionData(this.Bars.Time[barIndex], this.Bars.Open[barIndex], this.Bars.Volume[barIndex]));

         }


         //get current
         var currentSession = this.sessionData.Last();




         //update values
         currentSession.high = currentSession.high >= this.Bars.High[barIndex] ? currentSession.high : this.Bars.High[barIndex];
         currentSession.low = currentSession.low <= this.Bars.Low[barIndex] ? currentSession.low : this.Bars.Low[barIndex];
         currentSession.close = this.Bars.Close[barIndex];
         //currentSession.volume += this.Bars.Volume[barIndex]; //doesn't work with ascii mappings
         //currentSession.volume += this.Bars.Ticks[barIndex];
         currentSession.volume += this.Bars.TrueVolume()[barIndex]; //works when "build volume on --> trade volume" is set.

         //write back (over list last index)
         var currentIndex = this.sessionData.Count - 1;
         this.sessionData[currentIndex] = currentSession;

         //link our bar's dayIndex to the dailyData
         this.sessionIndex.Value = currentIndex;


         //test plotting: volume
         //p_currentVolume.Set(0, this.sessionData[this.sessionIndex.Value].volume, Color.DarkGoldenrod);
         //p_currentLow.Set(0, this.sessionData[this.sessionIndex.Value].low, Color.MediumAquamarine);
         //Output.WriteLine("{0} vol={1}",this.Bars.Info.Name,this.Bars.VolumeValue * 10000000 );
         //p_currentVolume.Set(0, 22.22, Color.DarkGoldenrod);
         if (this.sessionData.Count > 1)
         {
            p_lastVolume.Set(0, this.sessionData[this.sessionIndex.Value - 1].volume, Color.Yellow);
            p_lastLow.Set(0, this.sessionData[this.sessionIndex.Value - 1].low, Color.Aqua);
         }

         //update our "previous" bar variables
         this._prevBarTime = barTime;
      }

   }
}
Last edited by novaleaf on 21 May 2015, edited 2 times in total.

novaleaf
Posts: 49
Joined: 17 Apr 2014
Has thanked: 9 times
Been thanked: 4 times

Re: Example Session Indicators framework

Postby novaleaf » 07 May 2015

fyi I modified the above code: as I use a List<T> I needed to clear it during StartCalc().

also added a sample plot of volume for example and debugging purposes. (comment out the startCalc() lines and then jump back and backtest to see the issue)

novaleaf
Posts: 49
Joined: 17 Apr 2014
Has thanked: 9 times
Been thanked: 4 times

Re: Example Session Indicators framework

Postby novaleaf » 21 May 2015

modified to improve:

1) now takes MaxBarsBack into account (walks and does calc on history bars)

2) fixed volume calculation so it works with ascii mapped or streaming instruments.

3) added a bunch of debug output. comment them if you don't like it.


Return to “User Contributed Studies”