- ago
Hi, this is my attempt to calculate an average overnight percentage change ( no trading rules yet ). This approach seems to be very inefficient, i have to loop through all the previous n bars to get the average for each new bar. The other problem is taht i cannot find a way to plot this value. I would appreciate any ideas on how to improve. Thanks!
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript1 {    public class MyStrategy : UserStrategyBase    {       //create indicators and other objects here, this is executed prior to the main trading loop       // dayCount - the bars used for calculating the average overnight delta       public override void Initialize(BarHistory bars)       {          dayCount = 20;       }       //execute the strategy rules here, this is executed once for each bar in the backtest history       public override void Execute(BarHistory bars, int idx)       {          if (!HasOpenPosition(bars, PositionType.Long))          {             //start process on dayCount bar             if (idx > dayCount)             {                //get average overnight percentage delta over the past dayCount days                int days = 1;                                double sum = (bars.Open[idx] - bars.Close[idx - 1]) / bars.Close[idx - 1] * 100;                for (int backIdx = idx - 1; backIdx >= 0; backIdx--)                {                                  days++;                      sum += (bars.Open[backIdx] - bars.Close[backIdx - 1]) / bars.Close[backIdx - 1] * 100;                    // WriteToDebugLog((bars.Open[backIdx] - bars.Close[backIdx - 1]) / bars.Close[backIdx - 1] * 100);                      if (days >= dayCount)                         break;                            }                if (days >= dayCount)                {                   double avg = sum / days;                   WriteToDebugLog("avg= " + avg + " idx= " + idx);                   //DrawDot(idx, avg, WLColor.Red, 4, "Volume");                                   }             }          }          else          {             //sell conditions here          }       }       //declare private variables below       private int dayCount;    } }
1
98
Solved
4 Replies

Reply

Bookmark

Sort
Cone8
 ( 6.07% )
- ago
#1
This should help. (Assumes Daily data.)

CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; using System.Collections.Generic; using Steema.TeeChart.WPF.Data; namespace WealthScript1 {    public class MyStrategy : UserStrategyBase    {       //create indicators and other objects here, this is executed prior to the main trading loop       // dayCount - the bars used for calculating the average overnight delta       public override void Initialize(BarHistory bars)       {          dayCount = 20;                    // do this only once with a TimeSeries operation          TimeSeries overnitePct = 100 * (bars.Open / (bars.Close >> 1) - 1);                    // now find the average          _avgOvernight = SMA.Series(overnitePct, 20);          // plot it          PlotTimeSeriesMountain(_avgOvernight, "Overnight Avg %", "O/N", WLColor.NeonRed);       }       //execute the strategy rules here, this is executed once for each bar in the backtest history       public override void Execute(BarHistory bars, int idx)       {          if (!HasOpenPosition(bars, PositionType.Long))          {             // this isn't the right place to create indicators          }          else          {             //sell conditions here          }       }       //declare private variables below       private int dayCount;       private TimeSeries _avgOvernight;    } }
0
Best Answer
- ago
#2
Thanks Cone! This is the line that I did not know how to create:
CODE:
// do this only once with a TimeSeries operation TimeSeries overnitePct = 100 * (bars.Open / (bars.Close >> 1) - 1);
1
- ago
#3
I hardly/don't know what I'm doing with c# coding so go easy on me. Below are some custom indicators I set up a while ago. They appear to work as intended and can be used for what your looking to do.

ROC_O, Overnight Rate of Change. This is a ROC from closing to opening bars. Only really intended for daily bars, but can give info on smaller time frames. Dont change source start or end, and adjust ROC period as needed.

CODE:
using System; using Alternet.Editor.Wpf; using TeeChart.Xaml.WPF.Series; using WealthLab.Core; using WealthLab.Indicators; using WealthLab.WPF; namespace WealthLab.MyIndicators {    public class ROC_O : IndicatorBase    {       //parameterless constructor       public ROC_O() : base()       {       }       //for code based construction       public ROC_O(TimeSeries sourceS, TimeSeries sourceE, Int32 period)          : base()       {          Parameters[0].Value = sourceS;          Parameters[1].Value = sourceE;          Parameters[2].Value = period;          Populate();       }       public override string Name => "ROC Overnight";       public override string Abbreviation => "ROC_O";       public override string HelpDescription => "ROC Overnight. ROC based on overnight Close to Open only.";       public override string PaneTag => "ROC";       public override WLColor DefaultColor => WLColor.Maroon;       public override PlotStyle DefaultPlotStyle => PlotStyle.Line;       public override bool IsPrivate => false;       public override void Populate()       {          TimeSeries sourceS = Parameters[0].AsTimeSeries;          TimeSeries sourceE = Parameters[1].AsTimeSeries;          Int32 period = Parameters[2].AsInt;          DateTimes = sourceS.DateTimes;          if (period <= 0 || sourceS.Count == 0)             return;          var rocS = SMA.Series(sourceS, 1);          var rocE = SMA.Series(sourceE, 1);          var calc1 = new TimeSeries(DateTimes);          for (int bar = period; bar < sourceS.Count; bar++)          {             calc1[bar] = (((rocE[bar] - rocS[bar - 1]) / rocS[bar - 1] * 100));          }          var calc2 = SMA.Series(calc1, period) * period;          for (int bar = period; bar < sourceS.Count; bar++)          {             Values[bar] = calc2[bar];          }          PrefillNan(period + 1);       }       protected override void GenerateParameters()       {          AddParameter("Source Start", ParameterType.TimeSeries, PriceComponent.Close);          AddParameter("Source End", ParameterType.TimeSeries, PriceComponent.Open);          AddParameter("ROC Period", ParameterType.Int32, 1);       }    } }


GROC_O, Graphical Overnight Rate of Change. This is an Additive % Graphical ROC from closing to opening bars only. Only really intended for daily bars. Dont change start, end or period. Is additive of all bar data on chart or backtest period.

CODE:
using System; using System.Threading; using Alternet.Editor.Wpf; using TeeChart.Xaml.WPF.Series; using WealthLab.Core; using WealthLab.DataExtensions; using WealthLab.Indicators; using WealthLab.WPF; namespace WealthLab.MyIndicators {    public class GROC_O : IndicatorBase    {       //parameterless constructor       public GROC_O() : base()       {       }       //for code based construction       public GROC_O(TimeSeries sourceS, TimeSeries sourceE, Int32 period)          : base()       {          Parameters[0].Value = sourceS;          Parameters[1].Value = sourceE;          Parameters[2].Value = period;          Populate();       }       public override string Name => "GROC Overnight";       public override string Abbreviation => "GROC_O";       public override string HelpDescription => "GROC Overnight. % GROC based on overnight Close to Open only.";       public override string PaneTag => "Percent";       public override WLColor DefaultColor => WLColor.Maroon;       public override PlotStyle DefaultPlotStyle => PlotStyle.Line;       public override bool IsPrivate => false;       public override void Populate()       {          TimeSeries sourceS = Parameters[0].AsTimeSeries;          TimeSeries sourceE = Parameters[1].AsTimeSeries;          Int32 period = Parameters[2].AsInt;          DateTimes = sourceS.DateTimes;          if (period <= 0 | sourceS.Count == 0)             return;          var grocS = SMA.Series(sourceS, 1);          var grocE = SMA.Series(sourceE, 1);          var calc1 = new TimeSeries(DateTimes);          double sum = 0;          for (int bar = period; bar < sourceS.Count; bar++)          {             calc1[bar] = (((grocE[bar] - grocS[bar - 1]) / grocS[bar - 1] * 100));          }          var calc2 = SMA.Series(calc1, period) * period;          for (int bar = period; bar < sourceS.Count; bar++)          {             sum += calc2[bar];             Values[bar] = sum;          }          PrefillNan(period + 1);       }       protected override void GenerateParameters()       {          AddParameter("Source Start", ParameterType.TimeSeries, PriceComponent.Close);          AddParameter("Source End", ParameterType.TimeSeries, PriceComponent.Open);          AddParameter("GROC Period", ParameterType.Int32, 1);       }    } }


I have these two above, two for day time only, and two for standard close to close (which is slightly different than normal ROC data where these are additive and not absolute).
0
- ago
#4
mrjonj, thank you for sharing your work. I will take a look.
0

Reply

Bookmark

Sort