• If this is your first visit, you will have to register before you can post. To view messages, please scroll below and select the forum that you would like to visits. Questions? Be sure to check out the Forum FAQ.

Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Synchronization problems in indicator with multiple data called from other indicator

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Synchronization problems in indicator with multiple data called from other indicator

    I've created an indicator that calculates it's values based on a secondary 1 tick data series which works ok. But during real time calculations in a second indicator that uses the data of the first the values become inaccurate because the tick data set is not properly synced.
    Example:
    Code:
        public class SupportingIndicator : Indicator
        {
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"SupportingIndicator";
                    Name                                        = "SupportingIndicator";
                    Calculate                                    = Calculate.OnBarClose;
                    IsOverlay                                    = false;
                    DisplayInDataBox                            = true;
                    DrawOnPricePanel                            = false;
                    DrawHorizontalGridLines                        = true;
                    DrawVerticalGridLines                        = true;
                    PaintPriceMarkers                            = true;
                    ScaleJustification                            = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                    //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                    //See Help Guide for additional information.
                    IsSuspendedWhileInactive                    = true;
                    AddPlot(Brushes.Red, "SupportingPlot");
                }
                else if (State == State.Configure)
                {
                    AddDataSeries(Data.BarsPeriodType.Tick, 1);
                }
            }
    
            protected override void OnBarUpdate()
            {
                if(BarsInProgress != 0 || State != State.Realtime) return;
                Value[0] = Close[0];
                Print("Sup Last bar: " + CurrentBars[1] + " Time: " + Time[0]);
            }
    Code:
        public class PrimaryIndicator : Indicator
        {
            private SupportingIndicator supportingIndicator;
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"";
                    Name                                        = "PrimaryIndicator";
                    Calculate                                    = Calculate.OnBarClose;
                    IsOverlay                                    = false;
                    DisplayInDataBox                            = true;
                    DrawOnPricePanel                            = true;
                    DrawHorizontalGridLines                        = true;
                    DrawVerticalGridLines                        = true;
                    PaintPriceMarkers                            = true;
                    ScaleJustification                            = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                    //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                    //See Help Guide for additional information.
                    IsSuspendedWhileInactive                    = true;
                    AddPlot(Brushes.Red, "PrimaryPlot");
                }
                else if (State == State.Configure)
                {
                    AddDataSeries(Data.BarsPeriodType.Tick, 1);
                } else if(State == State.DataLoaded) {
                    supportingIndicator = SupportingIndicator();
                }
            }
    
            protected override void OnBarUpdate()
            {
                if(BarsInProgress != 0 || State != State.Realtime) return;
                Value[0] = supportingIndicator[0];
                Print("Pri Last bar: " + CurrentBars[1] + " Time: " + Time[0]);
            }
    On my volume based chart this produces following output:

    Code:
    Sup Last bar: 1226965 Time: 19/02/2020 11:23:28
    Pri Last bar: 1227331 Time: 19/02/2020 11:23:28
    Sup Last bar: 1227332 Time: 19/02/2020 11:23:37
    Pri Last bar: 1227593 Time: 19/02/2020 11:23:37
    Sup Last bar: 1227594 Time: 19/02/2020 11:23:59
    Pri Last bar: 1227938 Time: 19/02/2020 11:23:59
    Sup Last bar: 1227939 Time: 19/02/2020 11:24:36
    Pri Last bar: 1228297 Time: 19/02/2020 11:24:36
    Sup Last bar: 1228298 Time: 19/02/2020 11:25:06
    Pri Last bar: 1228635 Time: 19/02/2020 11:25:06
    The tick data series in the supporting indicator is running one bar behind.

    My solution is to use a helper class instead and use it to calculate the data without calling a secondary indicator;

    Example:
    Code:
    namespace NinjaTrader.NinjaScript.Indicators.Helper
    {
            public class CalculationHelper {
                private TimeSeries[] Times;
                private int[] CurrentBars;
                private int SeriesIndex;
                private int MasterIndex;
                private Bars Bars;
                private Series<double> OutputSeries;
    
                public CalculationHelper(
                   Bars bars
                , TimeSeries[] times
                , Series<double> outputSeries
                , int[] currentBars
                , int seriesIndex
                , int masterIndex
                    ) {
                this.Bars = bars;
                this.Times = times;
                this.OutputSeries = outputSeries;
                this.CurrentBars = currentBars;
                this.SeriesIndex = seriesIndex;
                this.MasterIndex = masterIndex;
            }
            public void OnBarUpdate() {
                //do something
                OutputSeries[0] = whatever
            }
    }
    Code:
        public class PrimaryIndicator : Indicator
        {
            private Series<double> supportingSeries;
            private NinjaTrader.NinjaScript.Indicators.Helper.CalculationHelper calculationHelper = null;
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"";
                    Name                                        = "PrimaryIndicator";
                    Calculate                                    = Calculate.OnBarClose;
                    IsOverlay                                    = false;
                    DisplayInDataBox                            = true;
                    DrawOnPricePanel                            = true;
                    DrawHorizontalGridLines                        = true;
                    DrawVerticalGridLines                        = true;
                    PaintPriceMarkers                            = true;
                    ScaleJustification                            = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                    //Disable this property if your indicator requires custom values that cumulate with each new market data event.
                    //See Help Guide for additional information.
                    IsSuspendedWhileInactive                    = true;
                    AddPlot(Brushes.Red, "PrimaryPlot");
                }
                else if (State == State.Configure)
                {
                    AddDataSeries(Data.BarsPeriodType.Tick, 1);
                } else if(State == State.DataLoaded) {
                    supportingSeries = new Series<double>(this, MaximumBarsLookBack.TwoHundredFiftySix);
                    calculationHelper = new NinjaTrader.NinjaScript.Indicators.Helper.CalculationHelper(BarsArray[1], Times, supportingSeries, CurrentBars, 1, 0);
                }
            }
    
            protected override void OnBarUpdate()
            {
                if(BarsInProgress != 0 || State != State.Realtime) return;
                calculationHelper.OnBarUpdate();
                Value[0] = supportingSeries[0];
            }
    Is this a well known problem, or is there a proper way to deal with synchronization?
    Unfortunately I'm not well versed in NinjaScript but I'd like to at least save time for other people facing the same issue.
    Last edited by MojoJojo; 02-19-2020, 10:59 AM.

    #2
    Hello MojoJojo,

    Thanks for your post.

    Our OrderFlowCumulativeDelta HelpGuide documentation gives a hint for how this case can be handled.

    OrderFlowCumulativeDelta NinjaScript reference - https://ninjatrader.com/support/help...ive_delta2.htm

    When I test the following, I get CurrentBar indexes in alignment.

    Code:
    protected override void OnBarUpdate()
    {
        if (BarsInProgress == 1)
        {
            supportingIndicator.Update(supportingIndicator.BarsArray[1].Count - 1, 1);
        }
    
        if(BarsInProgress != 0 || State != State.Realtime) return;
        Value[0] = supportingIndicator[0];
        Print("Pri Last bar: " + CurrentBars[1] + " Time: " + Time[0]);
    }
    Pri Last bar: 1183616 Time: 2/19/2020 12:53:33 PM
    Sup Last bar: 1183617 Time: 2/19/2020 12:53:36 PM
    Pri Last bar: 1183617 Time: 2/19/2020 12:53:36 PM
    Sup Last bar: 1183620 Time: 2/19/2020 12:53:39 PM
    Pri Last bar: 1183620 Time: 2/19/2020 12:53:39 PM
    Sup Last bar: 1183621 Time: 2/19/2020 12:53:42 PM
    Pri Last bar: 1183621 Time: 2/19/2020 12:53:42 PM
    Sup Last bar: 1183759 Time: 2/19/2020 12:53:45 PM
    Pri Last bar: 1183759 Time: 2/19/2020 12:53:45 PM
    Sup Last bar: 1183761 Time: 2/19/2020 12:53:51 PM
    Pri Last bar: 1183761 Time: 2/19/2020 12:53:51 PM
    Please let us know if we can be of further assistance.
    JimNinjaTrader Customer Service

    Comment


      #3
      Hello Jim,

      thanks for quick and excellent solution!
      I tried Update() before, too bad that I didn't read the reference more carefully.

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by bertochi, Today, 07:25 AM
      1 response
      2 views
      0 likes
      Last Post bertochi  
      Started by Kentoes, Today, 07:06 AM
      0 responses
      0 views
      0 likes
      Last Post Kentoes
      by Kentoes
       
      Started by third monkey, Today, 06:33 AM
      0 responses
      1 view
      0 likes
      Last Post third monkey  
      Started by xfbrq, Today, 05:41 AM
      0 responses
      3 views
      0 likes
      Last Post xfbrq
      by xfbrq
       
      Started by alcmvd, Today, 03:02 AM
      0 responses
      4 views
      0 likes
      Last Post alcmvd
      by alcmvd
       
      Working...
      X