Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Indicator plots for historical data but not plot in real-time

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

    Indicator plots for historical data but not plot in real-time

    I have a simple indicator that calls upon two other indicators which calculate on each tick. The simple indicator plots perfectly for all the historical bars but does not continue to plot in real-time. It only calculates once per bar at first tick.

    I cannot figure out how an indicator can plot for historical bars but never plot again after it is added. If I right click and Reload Ninjascript at any time it will plot up to that point in time but after that, it will not plot again. Please help!


    Code:
    public class SpoofFinder : Indicator
        {
            private NetVolDelta NetVolDelta1;
            private NinjaTrader.NinjaScript.Indicators.CSI.DeltaTickLine DeltaTickLine1;
            
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"Looks for Spoofs near swing highs and lows.";
                    Name                                        = "Spoof Finder";
                    Calculate                                    = Calculate.OnEachTick;
                    IsOverlay                                    = true;
                    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                    = false;
                    MinUpDelta        = 15 ;
                    MinDnDelta        = -15 ;
                    OffsetTicks                    = 5;
                    NumTicksfromHighLow = 7;
                    NumBarsSwingHighLow = 20;
                    AddPlot(new Stroke(Brushes.Red, 8), PlotStyle.TriangleDown, "Plot0");
                    AddPlot(new Stroke(Brushes.Lime, 8), PlotStyle.TriangleUp, "Plot1");
                }
                
                else if (State == State.Configure)
                {
                    
                }
                else if (State == State.DataLoaded)
                {                
                    NetVolDelta1 = NetVolDelta(Close);
                    DeltaTickLine1    = DeltaTickLine(Close);
                }
            }
    
            protected override void OnBarUpdate()
            {
                if (CurrentBar < NumBarsSwingHighLow || CurrentBar < BarsRequiredToPlot)
                    return;
                
                if (IsFirstTickOfBar)
                {
    
                int highestBarsAgo = HighestBar(High, NumBarsSwingHighLow);
                int lowestBar = LowestBar(Low, NumBarsSwingHighLow);
                double highestPrice = High[highestBarsAgo];
                double lowestPrice = Low[lowestBar];
                double SwingHigh = High[1] + (NumTicksfromHighLow * TickSize);
                double SwingLow = Low[1] - (NumTicksfromHighLow * TickSize);
                    
                
                if (SwingHigh >= highestPrice)
                {
                if (Close[1] > Open[1] && // Price UP
                    DeltaTickLine1.DeltaClose[2] > DeltaTickLine1.DeltaClose[1] && // Tick Delta DOWN
                    NetVolDelta1.Buys[1] < MinDnDelta) // Vol Delta DOWN
                {
                    Values[0][1] = (High[1] + (OffsetTicks * TickSize));
                    Print(string.Format("Down Arrow"));
                }
                }
                
                if (SwingLow <= lowestPrice)
                {
                if (Open[1] > Close[1] && // Price DOWN
                    DeltaTickLine1.DeltaClose[2] < DeltaTickLine1.DeltaClose[1] && // Tick Delta UP
                    NetVolDelta1.Buys[1] > MinUpDelta) // Vol Delta UP
                {
                    Values[1][1] = (Low[1] - (OffsetTicks * TickSize));
                    Print(string.Format("Up Arrow"));
                }
                }
                }
            }​

    #2
    Hello HarvOS,

    It looks like the script is designed to only run logic on the first tick of a new bar.

    In the script I am seeing:

    if (IsFirstTickOfBar)

    If this is unintentional you may want to remove this condition.
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Originally posted by NinjaTrader_ChelseaB View Post
      Hello HarvOS,

      It looks like the script is designed to only run logic on the first tick of a new bar.

      In the script I am seeing:

      if (IsFirstTickOfBar)

      If this is unintentional you may want to remove this condition.
      It is intentional. I actually tried to calculate of BarClose but it did not work because the two indicator called upon need tick data. So I made this one also use tick data but only calculate once per bar which ends up being the same as BarClose, I think. The way it is will plot just fine for all historical bars up to the present, but it will not continue to plot going forward as the chart develops. That is the problem I am having. Thanks.

      Comment


        #4
        Hello HarvOS,

        To understand why no plot value is being assigned print the values in the condition one line above the condition and print the value being assigned one line above the assignment.
        Print the time of the bar and include labels for all values and comparison operators.

        Below is a link to a support article on adding debugging prints to understand behavior.


        As an example of the output we are looking for:

        Print(string.Format("{0} | State: {1} | SwingHigh: {2} >= highestPrice: {3}", Time[0], State, SwingHigh, highestPrice));

        if (SwingHigh >= highestPrice)
        {

        Print(string.Format("{0} | State: {1} | Close[1]: {2} > Open[1]: {3} && DeltaTickLine1.DeltaClose[2]: {4} > DeltaTickLine1.DeltaClose[1]: {5}", Time[0], State, Close[1], Open[1], DeltaTickLine1.DeltaClose[2], DeltaTickLine1.DeltaClose[1])); // this print is incomplete and the last condition with NetVolDelta1 needs to be added

        if (Close[1] > Open[1] && // Price UP
        DeltaTickLine1.DeltaClose[2] > DeltaTickLine1.DeltaClose[1] && // Tick Delta DOWN
        NetVolDelta1.Buys[1] < MinDnDelta)​
        {

        Print(string.Format("{0} | State: {1} | assigning value to plot (High[1] + (OffsetTicks * TickSize)): {2}", Time[0], State, (High[1] + (OffsetTicks * TickSize)));

        Values[0][1] = (High[1] + (OffsetTicks * TickSize));
        }
        }

        // create a print for this condition
        if (SwingLow <= lowestPrice)
        {
        // create a print for this condition
        if (Open[1] > Close[1] && // Price DOWN
        DeltaTickLine1.DeltaClose[2] < DeltaTickLine1.DeltaClose[1] && // Tick Delta UP
        NetVolDelta1.Buys[1] > MinUpDelta) // Vol Delta UP
        {
        // print the calculated value being assigned
        Values[1][1] = (Low[1] - (OffsetTicks * TickSize));
        Print(string.Format("Up Arrow"));
        }
        }
        }


        Open the output window and rerun the script.
        Save the output to a text file (right-click > Save as) and attach this to your reply.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Originally posted by NinjaTrader_ChelseaB View Post
          Hello HarvOS,

          To understand why no plot value is being assigned print the values in the condition one line above the condition and print the value being assigned one line above the assignment.
          Print the time of the bar and include labels for all values and comparison operators.

          Below is a link to a support article on adding debugging prints to understand behavior.


          As an example of the output we are looking for:



          Open the output window and rerun the script.
          Save the output to a text file (right-click > Save as) and attach this to your reply.
          I applied the prints as you suggested and I see that the data from the other two indicators stop working after the script is loaded. (DeltaTickLine goes to infinity and VolDeltas go to zero. Both require tick data) I just don't understand how the data can be called perfectly while loading the script for all historical bars, but then fail to call the data as each new bar is created. This should be quite simple but I seem to be missing something. Below is the code and output text you requested.

          Code:
          public class SpoofFinder : Indicator
              {
                  private NetVolDelta2 NetVolDelta21;
                  private NinjaTrader.NinjaScript.Indicators.CSI.DeltaTickLine DeltaTickLine1;
                  
                  protected override void OnStateChange()
                  {
                      if (State == State.SetDefaults)
                      {
                          Description                                    = @"Looks for Spoofs near swing highs and lows.";
                          Name                                        = "Spoof Finder";
                          Calculate                                    = Calculate.OnEachTick;
                          IsOverlay                                    = true;
                          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                    = false;
                          MinUpDelta        = 15 ;
                          MinDnDelta        = -15 ;
                          OffsetTicks          = 5;
                          NumTicksfromHighLow = 7;
                          NumBarsSwingHighLow = 20;
                          AddPlot(new Stroke(Brushes.Red, 8), PlotStyle.TriangleDown, "Plot0");
                          AddPlot(new Stroke(Brushes.Lime, 8), PlotStyle.TriangleUp, "Plot1");
                      }
                      
                      else if (State == State.Configure)
                      {
                          
                      }
                      else if (State == State.DataLoaded)
                      {                
                          NetVolDelta21    = NetVolDelta2(Close);
                          DeltaTickLine1    = DeltaTickLine(Close);
                      }
                  }
          
                  protected override void OnBarUpdate()
                  {
                      if (CurrentBar < NumBarsSwingHighLow || CurrentBar < BarsRequiredToPlot)
                          return;
                      
                      if (IsFirstTickOfBar)
                      {
          
                      int highestBarsAgo = HighestBar(High, NumBarsSwingHighLow);
                      int lowestBar = LowestBar(Low, NumBarsSwingHighLow);
                      double highestPrice = High[highestBarsAgo];
                      double lowestPrice = Low[lowestBar];
                      double SwingHigh = High[1] + (NumTicksfromHighLow * TickSize);
                      double SwingLow = Low[1] - (NumTicksfromHighLow * TickSize);
                          
                      Print(string.Format("{0} | SwingHigh: {1} > highestPrice: {2}", Time[0], SwingHigh, highestPrice));
                      if (SwingHigh >= highestPrice)
                      {
                          Print(string.Format("{0} | Close[1]: {1} > Open[1]: {2} && DeltaTickLine[2]: {3} >= DeltaTickLine[1]: {4} && DnVolDelta: {5} <= MnDnDelta: {6}", Time[0], Close[1], Open[1], DeltaTickLine1.DeltaClose[2], DeltaTickLine1.DeltaClose[1], NetVolDelta21.Plot1[1], MinDnDelta));
                      if (Close[1] > Open[1] && // Price UP
                          DeltaTickLine1.DeltaClose[2] >= DeltaTickLine1.DeltaClose[1] && // Tick Delta DOWN
                          NetVolDelta21.Plot1[1] <= MinDnDelta) // Vol Delta DOWN
                      {
                          Print(string.Format("{0} | (High[1] + (OffsetTicks * TickSize)): {1}", Time[0], (High[1] + (OffsetTicks * TickSize))));
                          Values[0][1] = (High[1] + (OffsetTicks * TickSize));
                          Print(string.Format("Down Arrow"));
                      }
                      }
                      
                      Print(string.Format("{0} | SwingLow: {1} <= lowestPrice: {2}", Time[0], SwingLow, lowestPrice));
                      if (SwingLow <= lowestPrice)
                      {
                          Print(string.Format("{0} | Open[1]: {1} > Close[1]: {2} && DeltaTickLine[2]: {3} <= DeltaTickLine[1]: {4} && UpVolDelta: {5} >= MinUpDelta: {6}", Time[0], Open[1], Close[1], DeltaTickLine1.DeltaClose[2], DeltaTickLine1.DeltaClose[1], NetVolDelta21.Plot0[1], MinUpDelta));
                      if (Open[1] > Close[1] && // Price DOWN
                          DeltaTickLine1.DeltaClose[2] <= DeltaTickLine1.DeltaClose[1] && // Tick Delta UP
                          NetVolDelta21.Plot0[1] >= MinUpDelta) // Vol Delta UP
                      {
                          Print(string.Format("{0} | (Low[1] - (OffsetTicks * TickSize)): {1}", Time[0], (Low[1] + (OffsetTicks * TickSize))));
                          Values[1][1] = (Low[1] - (OffsetTicks * TickSize));
                          Print(string.Format("Up Arrow"));
                      }
                      }
                      }
                  }​
          Attached Files

          Comment


            #6
            Hello HarvOS,

            Thank you for the output.

            So the issue appears to be with the indicators being called.

            The next step is to debug the indicator to find out why these are not longer setting values.
            Are these indicators you have written yourself that you are able to debug?

            Are the plot values being assigned from inside of a condition?

            If so, in each indicator print the values in the condition one line above the condition and print the calculated value one line above the assignment.

            Are these scripts calling AddDataSeries(BarsPeriodType.Tick, 1); in OnStateChange() when State is State.Configure?

            If you print the Time[0] and BarsInProgress, are you seeing output for BarsInProgress 1?

            Please also include the State property in the prints in OnBarUpdate() so that we can see when the real-time data starts processing.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Originally posted by NinjaTrader_ChelseaB View Post
              Hello HarvOS,

              Thank you for the output.

              So the issue appears to be with the indicators being called.

              The next step is to debug the indicator to find out why these are not longer setting values.
              Are these indicators you have written yourself that you are able to debug?

              Are the plot values being assigned from inside of a condition?

              If so, in each indicator print the values in the condition one line above the condition and print the calculated value one line above the assignment.

              Are these scripts calling AddDataSeries(BarsPeriodType.Tick, 1); in OnStateChange() when State is State.Configure?

              If you print the Time[0] and BarsInProgress, are you seeing output for BarsInProgress 1?

              Please also include the State property in the prints in OnBarUpdate() so that we can see when the real-time data starts processing.
              I wrote one of two indicators but I can access both in the editor. Both indicators set values just fine on their own, calculating as expected. I use both of them on the same chart I am trying to use the new indicator on and even after the new one fails to get any new values, the two others being called are still working just fine individually. There has to be some reason the new one stops getting values. Both indicators are below.

              Code:
              namespace NinjaTrader.NinjaScript.Indicators
              {
                  public class NetVolDelta2 : Indicator
                  {
                      private double    buys;
                      private double    sells;
                      private int activeBar = 0;
                      private Series<double> Buys;
              
                      protected override void OnStateChange()
                      {
                          if (State == State.SetDefaults)
                          {
                              Description                                    = @"Enter the description for your new custom Indicator here.";
                              Name                                        = "Net Vol Delta 2";
                              Calculate                                    = Calculate.OnEachTick;
                              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                    = false;
                              AddPlot(new Stroke(Brushes.Lime, 2), PlotStyle.Bar, "Plot0");
                              AddPlot(new Stroke(Brushes.Red, 2), PlotStyle.Bar, "Plot1");
                              AddPlot(Brushes.DarkGray, "Plot2");
                          }
                          else if (State == State.Historical)
                          {
                              if (Calculate != Calculate.OnEachTick)
                              {
                                  Draw.TextFixed(this, "NinjaScriptInfo", string.Format(NinjaTrader.Custom.Resource.NinjaScriptOnBarCloseError, Name), TextPosition.BottomRight);
                                  Log(string.Format(NinjaTrader.Custom.Resource.NinjaScriptOnBarCloseError, Name), LogLevel.Error);
                              }
                          }
                          else if (State == State.Configure)
                          {
                          }
                          else if (State == State.DataLoaded)
                          {                
                              Buys = new Series<double>(this);
                          }
                      }
              
                      protected override void OnMarketData(MarketDataEventArgs e)
                      {
                          if(e.MarketDataType == MarketDataType.Last)
                          {
                              if(e.Price >= e.Ask)
                                  buys += (Instrument.MasterInstrument.InstrumentType == Cbi.InstrumentType.CryptoCurrency ? Core.Globals.ToCryptocurrencyVolume(e.Volume) : e.Volume);
                              else if (e.Price <= e.Bid)
                                  sells += (Instrument.MasterInstrument.InstrumentType == Cbi.InstrumentType.CryptoCurrency ? Core.Globals.ToCryptocurrencyVolume(e.Volume) : e.Volume);
                          }
                      }
              
                      protected override void OnBarUpdate()
                      {
                          if (CurrentBar < activeBar || CurrentBar <= BarsRequiredToPlot)
                              return;
              
                          if (CurrentBar != activeBar)
                          {
                              Buys[1] = (buys - sells);
                              buys = 0;
                              sells = 0;
                              activeBar = CurrentBar;
                          }
              
                          Buys[0] = ((buys - sells)) ;
                          
                          Plot2[0] = 0;    
                          
                          if (Buys[0] >= 0)
                          { Plot0[0] = Buys[0] + 0.5 ;
                              Plot1[0] = -0.5; }
                          
                          if (Buys[0] < 0)
                          { Plot1[0] = Buys[0] - 0.5 ;
                              Plot0[0] = 0.5; }
                      }
              
                      #region Properties
              
                      [Browsable(false)]
                      [XmlIgnore]
                      public Series<double> Plot0
                      {
                          get { return Values[0]; }
                      }
              
                      [Browsable(false)]
                      [XmlIgnore]
                      public Series<double> Plot1
                      {
                          get { return Values[1]; }
                      }
              
                      [Browsable(false)]
                      [XmlIgnore]
                      public Series<double> Plot2
                      {
                          get { return Values[2]; }
                      }
                      #endregion
              
                  }
              }​
              Code:
              namespace NinjaTrader.NinjaScript.Indicators.CSI
              {
                  public class DeltaTickLine : Indicator
                  {
                      #region InitializeVariables
              
              
                      private double buys;
                      private double sells;
                      private double deltaClose;
                      bool upTick, downTick;
              
                      double currentPrice, lastPrice;
              
                      private int activeBar = 0;
              
                      private Series<double> calculatedValue;
                      private double deltaLine, minValue, maxValue;
              
                      #endregion
              
                      #region OnStateChange
              
                      protected override void OnStateChange()
                      {
                          if (State == State.SetDefaults)
                          {
                              Description = @"Tick Calculation: if uptick then delt plus volume if down tick delta
                                              neg if equal go with last directional bar for adding volume to delta";
                              Name = "DeltaTickLine";
                              Calculate = Calculate.OnEachTick;
                              BarsRequiredToPlot = 1;
                              IsOverlay = true;
                              DisplayInDataBox = true;
                              DrawOnPricePanel = false;
                              PaintPriceMarkers = false;
                              ArePlotsConfigurable = true;
                              ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Overlay;
                              IsSuspendedWhileInactive = false;
              
                              AddPlot(new Stroke(Brushes.Orange, 3), PlotStyle.Line, "DeltaTickLine");
              
                          }
                          else if (State == State.Configure)
                          {
                              calculatedValue = new Series<double>(this, MaximumBarsLookBack.Infinite);
                              currentPrice = lastPrice = 0;
                          }
                          else if (State == State.Historical)
                          {
                              if (Calculate != Calculate.OnEachTick)
                              {
                                  Draw.TextFixed(this, "NinjaScriptInfo", string.Format(NinjaTrader.Custom.Resource.NinjaScriptOnBarCloseError, Name), TextPosition.BottomRight);
                                  Log(string.Format(NinjaTrader.Custom.Resource.NinjaScriptOnBarCloseError, Name), LogLevel.Error);
                              }
              
                          }
                          else if (State == State.DataLoaded)
                          {
                          }
                      }
                      #endregion
              
                      #region DeltaCalculations
              
                      protected override void OnMarketData(MarketDataEventArgs e)
                      {
                          if (CurrentBar < activeBar || CurrentBar <= BarsRequiredToPlot)
                              return;
                          if (e.MarketDataType == MarketDataType.Last)
                          {
                              if (currentPrice == 0 && lastPrice == 0)
                              {
                                  currentPrice = e.Price;
                                  lastPrice = e.Price;
                                  upTick = false;
                                  downTick = false;
                              }
                              if (currentPrice > 0 && lastPrice > 0)
                              {
                                  currentPrice = e.Price;
                                  if (currentPrice > lastPrice)
                                  {
                                      buys += e.Volume;
                                      upTick = true;
                                      downTick = false;
                                  }
                                  else if (currentPrice < lastPrice)
                                  {
                                      sells += e.Volume;
                                      downTick = true;
                                      upTick = false;
                                  }
                                  else if (currentPrice == lastPrice)
                                  {
                                      if (upTick)
                                          buys += e.Volume;
                                      if (downTick)
                                      {
                                          sells += e.Volume;
                                      }
              
                                  }
                                  lastPrice = currentPrice;
                              }
              
                              deltaClose = buys - sells;
              
                              DeltaClose[0] = deltaClose;
                          }
                      }
                      #endregion
              
                      #region OnBarUpdate
              
                      protected override void OnBarUpdate()
                      {
                          if (CurrentBars[0] < BarsRequiredToPlot)
                              return;
              
                          if (ScaleJustification == ScaleJustification.Overlay)
                          {
                              calculatedValue[0] = deltaClose;
                              DeltaClose[0] = Normalize(deltaClose, minValue, maxValue);
                          }
                          else
                          {
                              DeltaClose[0] = deltaClose;
                          }
                      }
                      #endregion
              
                      #region OnCalculateMinMax
              
                      public override void OnCalculateMinMax()
                      {
                          if (ScaleJustification == ScaleJustification.Overlay)
                          {
                              MinValue = 0.00;
                              MaxValue = 1000.00;
                          }
                          else
                          {
                              base.OnCalculateMinMax();
                          }
                      }
              
                      #endregion
              
                      #region OnRender
              
                      protected override void OnRender(ChartControl ChartControl, ChartScale ChartScale)
                      {
                          // make sure there are bars displayed on the chart and the chart control is ready before running
              
                          if (Bars == null || ChartControl == null) return;
              
                          Vector2 startPoint;
                          Vector2 endPoint;
              
                          AntialiasMode originaldAntialiasMode = RenderTarget.AntialiasMode;
              
                          if (ScaleJustification == ScaleJustification.Overlay)
                          {
                              // Calculate Min and Max raw values on chart for use in data normalization
                              minValue = double.MaxValue;
                              maxValue = double.MinValue;
                              for (int barIndex = ChartBars.FromIndex; barIndex <= ChartBars.ToIndex; barIndex++)
                              {
                                  double barValue = calculatedValue.GetValueAt(barIndex);
                                  // don't include bars in calculation where raw value = 0
                                  if (barValue != 0)
                                  {
                                      minValue = Math.Min(barValue, minValue);
                                      maxValue = Math.Max(barValue, maxValue);
                                  }
                              }
              
                              RenderTarget.AntialiasMode = AntialiasMode.PerPrimitive;
                              for (int barIndex = ChartBars.FromIndex + 1; barIndex <= ChartBars.ToIndex; barIndex++)
                              {
                                  try
                                  {
                                      int startX = ChartControl.GetXByBarIndex(ChartBars, barIndex - 1);
                                      double startPrice = Normalize(calculatedValue.GetValueAt(barIndex - 1), minValue, maxValue);
                                      int startY = ChartScale.GetYByValue(startPrice);
                                      startPoint = new Vector2(startX, startY);
              
                                      int endX = ChartControl.GetXByBarIndex(ChartBars, barIndex);
                                      double endPrice = Normalize(calculatedValue.GetValueAt(barIndex), minValue, maxValue);
              
                                      // don't plot normalized values if less than zero, i.e. the raw value = 0;
                                      if (startPrice >= 0 && endPrice >= 0)
                                      {
                                          // using TriggerCustomEvent to set the plot value so the price marker prints at the last normalized price
                                          TriggerCustomEvent(o =>
                                          {
                                              Value[0] = endPrice;
                                          }, null);
                                          int endY = ChartScale.GetYByValue(endPrice);
                                          endPoint = new Vector2(endX, endY);
              
                                          RenderTarget.DrawLine(startPoint, endPoint, Plots[0].BrushDX, Plots[0].Width, Plots[0].StrokeStyle);
                                      }
                                  }
                                  catch (Exception ex)
                                  {
                                      Print("OnRender Error: " + ex.ToString());
                                  }
                              }
                          }
                          else
                          {
                              base.OnRender(ChartControl, ChartScale);
                          }
                          RenderTarget.AntialiasMode = originaldAntialiasMode;
                      }
              
                      #endregion
              
                      #region Normalize
                      private double Normalize(double Value, double MinValue, double MaxValue)
                      {
                          if (Value == 0)
                          {
                              // cant go without a zero value as some indicators will return zero and then plot blank if we just return on a 0 value.
                              Value = 0.00001;
                          }
                          double normalizedValue = (Value - MinValue) / (MaxValue - MinValue) * 1000;
                          return normalizedValue;
                      }
              
                      #endregion
              
                      #region Hide parameter List from Name
                      // Hide the parameter list
                      public override string DisplayName
                      {
                          get { return Name; }
                      }
                      #endregion
              
                      #region Properties
              
                      [Browsable(false)]
                      [XmlIgnore]
                      public Series<double> DeltaClose
                      {
                          get { return Values[0]; }
                      }
              
                      [Browsable(false)]
                      [XmlIgnore]
                      public Series<double> BaseValue
                      {
                          get { return calculatedValue; }
                      }
                      //[NinjaScriptProperty]
                      //[Display(Name = "Delta Line Up", Description = "Set colour and opacity for increasing delta line \n here .Set Thickness and style below.", Order = 1, GroupName = "Colour/Opacity Settings \n SetStyle/Width @ bottom")]
                      //public Stroke DeltaLineUp
                      //{get; set;}
              
                      //[NinjaScriptProperty]
                      //[Display(Name = "Delta Line Down", Description = "Set colour for decreasing delta line \n here. Set Thickness and style below.", Order = 2, GroupName = "Colour/Opacity Settings \n SetStyle/Width @ bottom")]
                      //public Stroke DeltaLineDown
                      //{get; set;}
              
                      #endregion
              
                  }
              }​

              Comment


                #8
                Hello HarvOS,

                You will need to use debugging prints to understand what is causing the issue.

                I see DeltaClose[0] can be assigned on 3 different lines. Which one of these assignments is the one assigning the unexpected value?

                Is the value assigned at the bottom of OnMarketData() the assignment in question?

                DeltaClose[0] = deltaClose;

                Print the marketDataUpdate.Time, the State, and value of deltaClose. Is this value what you expect?

                Try printing the time, the State, and buys, sells, and buys minus sells. Are these values what you expect?
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  The two indicators being called both require tick data. Is there a way to create another indicator that calls both of the other indicators but only calculates on bar close? That might be the easiest solution since they both work just fine.

                  Comment


                    #10
                    Hello HarvOS,

                    The Calculate setting of the host and hosted symbiote indicator must use the same Calculate setting; the symbiote Calculate setting will be imposed from the host (and will use whatever setting the host has).
                    The hosted symbiote would be getting the same OnBarUpdate() updates for each tick as the host does.

                    However, it looks like this script is processing market updates in OnMarketUpdate() and not from ticks processed in OnBarUpdate().
                    This would be fine to do, but the plot series should be assigned from OnbarUpdate() and .Update() should be called on the indicator on each tick (not just on the first bar of a new tick). The BuySellVolume indicator provides an example.
                    Below is a link to a video demonstrating.


                    In historical TickReplay would need to be enabled and historical tick data would be need to be available from the connected provider. The NinjaTrader connection provides 1 years of historical tick data for the most popular futures.


                    Chelsea B.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                    0 responses
                    556 views
                    0 likes
                    Last Post Geovanny Suaza  
                    Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                    0 responses
                    324 views
                    1 like
                    Last Post Geovanny Suaza  
                    Started by Mindset, 02-09-2026, 11:44 AM
                    0 responses
                    101 views
                    0 likes
                    Last Post Mindset
                    by Mindset
                     
                    Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                    0 responses
                    545 views
                    1 like
                    Last Post Geovanny Suaza  
                    Started by RFrosty, 01-28-2026, 06:49 PM
                    0 responses
                    547 views
                    1 like
                    Last Post RFrosty
                    by RFrosty
                     
                    Working...
                    X