Essentially we are trying to calculate and indicator using the partial bar. I set this up as follows:
a) I was using continuous futures with the CME RTH session ( 405 minute )
b) Strategy adds a 400 minute series ( more efficient than using a 5 minute as the code iterates less)
c) Create a DataSeries aligned with the 405 minute session but offset by 1 where the last entry is the close of the FirstBarOfSession of 400 minute bar series.
d) I tried doing calculations on the modified dataseries ( named PartialClose ) but the value is incorrect. Probably because I correct the prior element with the actual close of the 405 minute bar. My guess is there is some cacheing of the values when using an indicator. Is there a way to correct this?
The below strategy will plot the value of
a) sma using the 405 minute bar
b) sma using the partial close dataseries (some how calculated wrong)
c) manually calculate it by using SUM function and adding the most recent partial close and dividing by the length of the average (verified correct calculation)
I was trying to figure out a clean way to achieve an entry or exit on close that leverages all of the indicators code base instead of creating a series of partial bar calculations for every indicator but I haven't figured out a way to make it work.
Any thoughts?
#region Using declarations using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Data; using NinjaTrader.Indicator; using NinjaTrader.Gui.Chart; using NinjaTrader.Strategy; #endregion // This namespace holds all strategies and is required. Do not change it. namespace NinjaTrader.Strategy { /// <summary> /// /// </summary> [Description("")] public class TestOnClose : Strategy { #region Variables double p0 = 0, p1 = 0; private DataSeries PartialClose; // Wizard generated variables private int fastLength = 10; // Default setting for FastLength private int slowLength = 30; // Default setting for SlowLength // User defined variables (add any user defined variables below) #endregion /// <summary> /// This method is used to configure the strategy and is called once before any strategy method is called. /// </summary> protected override void Initialize() { // ALIGNED WITH MAIN SESSION BUT DISPLACED BY ONE PartialClose = new DataSeries(this); Add(PeriodType.Minute, 400); // ACTUAL 405M CLOSE Add(SMA(fastLength)); SMA(fastLength).Plots[0].Pen.Color = Color.Cyan; Add(StrategyPlot(0)); Add(StrategyPlot(1)); StrategyPlot(0).Plots[0].Pen.Color = Color.Magenta; StrategyPlot(1).Plots[0].Pen.Color = Color.Red; StrategyPlot(0).PanelUI = 1; StrategyPlot(1).PanelUI = 1; CalculateOnBarClose = true; } /// <summary> /// Called on each bar update event (incoming tick) /// </summary> protected override void OnBarUpdate() { // FULL SESSION SERIES if(BarsInProgress == 0) { // UPDATE PARTIAL CLOSE SERIES WITH FINAL CLOSE if(PartialClose.Count > 1) PartialClose.Set(1,Closes[0][1]); StrategyPlot(0).Value.Set(p0); StrategyPlot(1).Value.Set(p1); } // PARTIAL SESSION SERIES else if(BarsInProgress == 1) { // USING A BAR SETTING OF 5 MINUTE LESS RESULTS IN 2 BARS PER SESSION, SO FIRSTBAROFSESSION WORKS if(BarsArray[1].FirstBarOfSession) { // UPDATE PARTIAL CLOSE SERIES WITH PARTIAL CLOSE if(PartialClose.Count > 0) PartialClose.Set(0, Closes[1][0]); // ENSURE YOU HAVE ENOUGH BARS if(PartialClose.Count < slowLength) return; // CALCULATE USING PARTIALCLOSE SERIES AND EXECUTE ORDER ON SECOND SERIES double fastAvg = SMA(PartialClose,fastLength)[0]; double slowAvg = SMA(PartialClose,slowLength)[0]; p0 = (SUM(PartialClose,fastLength - 1)[1] + Closes[1][0]) / fastLength; p1 = fastAvg; if(Position.MarketPosition == MarketPosition.Flat && fastAvg > slowAvg) EnterLong(1,1,"LE"); if(Position.MarketPosition == MarketPosition.Long && fastAvg < slowAvg) ExitLong(1,1,"LX","LE"); } } } #region Properties [Description("")] [GridCategory("Parameters")] public int FastLength { get { return fastLength; } set { fastLength = Math.Max(1, value); } } [Description("")] [GridCategory("Parameters")] public int SlowLength { get { return slowLength; } set { slowLength = Math.Max(1, value); } } #endregion } }
Comment