Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Error on getting values with indexes 1 and or 2 on a strategy

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

    Error on getting values with indexes 1 and or 2 on a strategy

    Hi everyone,

    I am trying to create a simple strategy using BSTVolume indicator ( publicly available on user share ).

    I want to use renko bars ( ninzarenko or Unirenko ), and since the BSTVolume indicator needs to be used on each tick, i set my strategy that way.

    The problem is that I can not read the values from 1 or 2 bars ago, i printed the values and i always get 0.
    If i set the data series to tick replay, the strategy works in the history, but on real market conditions, it doesn't work, regardless if I use tick replay or not.

    You can see in the screenshot ( both the strategy and the indicator were loaded more than 10 bars ago ) that the indicator plots values, but my strategy can't read them.

    What am I doing wrong here?


    Code:
    namespace NinjaTrader.NinjaScript.Strategies
    {
    public class BSTStrategy : Strategy
    {
    private BSTVolume BSTVolume1;
    
    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Enter the description for your new custom Strategy here.";
    Name = "BSTStrategy";
    Calculate = Calculate.OnEachTick;
    EntriesPerDirection = 1;
    EntryHandling = EntryHandling.AllEntries;
    IsExitOnSessionCloseStrategy = true;
    ExitOnSessionCloseSeconds = 30;
    IsFillLimitOnTouch = false;
    MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
    OrderFillResolution = OrderFillResolution.Standard;
    Slippage = 0;
    StartBehavior = StartBehavior.WaitUntilFlat;
    TimeInForce = TimeInForce.Gtc;
    TraceOrders = false;
    RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
    StopTargetHandling = StopTargetHandling.PerEntryExecution;
    BarsRequiredToTrade = 20;
    // Disable this property for performance gains in Strategy Analyzer optimizations
    // See the Help Guide for additional information
    IsInstantiatedOnEachOptimizationIteration = true;
    Contracts = 1;
    Stop = 9;
    Target = 4;
    
    }
    else if (State == State.Configure)
    {
    AddDataSeries(Data.BarsPeriodType.Tick, 1);
    }
    else if (State == State.DataLoaded)
    {
    BSTVolume1 = BSTVolume(Close, true, true, 2);
    SetStopLoss("", CalculationMode.Ticks, Stop, false);
    SetProfitTarget("", CalculationMode.Ticks, Target);
    }
    }
    
    protected override void OnBarUpdate()
    {
    if (BarsInProgress != 0)
    return;
    
    if (CurrentBars[0] < 4)
    return;
    
    Print(
    Time[1]
    + " Buys 1:" + BSTVolume1.Buys[1]
    + " Buys 2:" + BSTVolume1.Buys[2]
    );
    
    
    // Set 1
    if (
    
    IsFirstTickOfBar &&
    BSTVolume1.Sells[1] > BSTVolume1.Sells[2] &&
    Close[1] > Open[1]
    )
    {
    EnterLongLimit(Convert.ToInt32(Contracts), Close[1], "");
    }
    
    
    
    
    
    // Set 2
    
    if (
    
    IsFirstTickOfBar &&
    BSTVolume1.Buys[1] > BSTVolume1.Buys[2] &&
    Close[1] < Open[1]
    )
    {
    EnterShortLimit(Convert.ToInt32(Contracts), Close[1], "");
    }
    
    }
    ​​
    Attached Files

    #2
    Hello gyilaoliver,

    It looks like the indicator you mentioned is a modified buy sell volume indicator, the same code that comes with NinjaTraders BuySellVolume with some additions. With that indicator it uses OnMarketData to build the ask and bid data so it cannot be used historically without tick replay. That will however perform differently than in realtime because tick replay is only a snapshot of the ask and bid price during the last event, not the full ask and bid data that you would otherwise see in realtime.

    Due to how the indicator plots its data I would suggest to avoid calling the indicator and instead incorporate the indicators logic directly into the strategy. That will let you read the values when needed before they are reset during bar closes. The strategy would need to be tested in realtime to confirm your strategy conditions work as expected, backtesting with this type of logic will have differences so it may not be an accurate display of how the strategy works. Renko bars also generally perform differently when backtested so using playback or realtime would be necessary to actually test the strategy with these considerations.

    Comment


      #3
      Hi Jesse, thanks for your suggestion.

      I tried to implement the logic of the standard BuySellVolume indicator to my strategy, it compiles without errors, but when trying to enable it, I get an error :

      Strategy 'BSTStrategy': Error on calling 'OnBarUpdate' method on bar 21: Index was outside the bounds of the array.​

      do you have any idea where that 21st candle comes from? i don't see any reference in my code to the 20th candle.
      Or did I miss soething? ( Sorry if these are newbie questions, i am just learning Ninjascript )

      Code:
      namespace NinjaTrader.NinjaScript.Strategies
      {
      public class BSTStrategy : Strategy
      {
      private BSTVolume BSTVolume1;
      
      private double buys;
      private double sells;
      private int activeBar = 0;
      
      protected override void OnStateChange()
      {
      if (State == State.SetDefaults)
      {
      Description = @"Enter the description for your new custom Strategy here.";
      Name = "BSTStrategy";
      Calculate = Calculate.OnEachTick;
      EntriesPerDirection = 1;
      EntryHandling = EntryHandling.AllEntries;
      IsExitOnSessionCloseStrategy = true;
      ExitOnSessionCloseSeconds = 30;
      IsFillLimitOnTouch = false;
      MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
      OrderFillResolution = OrderFillResolution.Standard;
      Slippage = 0;
      StartBehavior = StartBehavior.WaitUntilFlat;
      TimeInForce = TimeInForce.Gtc;
      TraceOrders = false;
      RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
      StopTargetHandling = StopTargetHandling.PerEntryExecution;
      BarsRequiredToTrade = 256;
      // Disable this property for performance gains in Strategy Analyzer optimizations
      // See the Help Guide for additional information
      IsInstantiatedOnEachOptimizationIteration = true;
      Contracts = 1;
      Stop = 9;
      Target = 4;
      
      }
      else if (State == State.Configure)
      {
      //AddDataSeries(Data.BarsPeriodType.Tick, 1);
      }
      else if (State == State.DataLoaded)
      {
      
      
      SetStopLoss("", CalculationMode.Ticks, Stop, false);
      SetProfitTarget("", CalculationMode.Ticks, Target);
      }
      }
      
      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 (BarsInProgress != 0)
      return;
      
      if (CurrentBars[0] < 4)
      return;
      */
      if (CurrentBar < activeBar || CurrentBar <= BarsRequiredToTrade)
      return;
      
      // New Bar has been formed
      // - Assign last volume counted to the prior bar
      // - Reset volume count for new bar
      if (CurrentBar != activeBar)
      {
      Sells[1] = sells;
      Buys[1] = buys ;
      buys = 0;
      sells = 0;
      activeBar = CurrentBar;
      }
      
      Sells[0] = sells;
      Buys[0] = buys ;
      
      
      Print(
      Time[1]
      + " Buys 1:" + Buys[1]
      + " Buys 2:" + Buys[2]
      );
      
      
      // Set 1
      if (
      
      IsFirstTickOfBar &&
      Sells[1] > Sells[2] &&
      Close[1] > Open[1]
      )
      {
      EnterLongLimit(Convert.ToInt32(Contracts), Close[1], "");
      }
      
      
      
      
      
      // Set 2
      
      if (
      
      IsFirstTickOfBar &&
      Buys[1] > Buys[2] &&
      Close[1] < Open[1]
      )
      {
      EnterShortLimit(Convert.ToInt32(Contracts), Close[1], "");
      }
      
      }
      
      [HASHTAG="t3322"]region[/HASHTAG] Properties
      [NinjaScriptProperty]
      [Range(1, int.MaxValue)]
      [Display(Name="Contracts", Order=1, GroupName="Parameters")]
      public int Contracts
      { get; set; }
      
      [NinjaScriptProperty]
      [Range(1, int.MaxValue)]
      [Display(Name="Stop", Order=2, GroupName="Parameters")]
      public int Stop
      { get; set; }
      
      [NinjaScriptProperty]
      [Range(1, int.MaxValue)]
      [Display(Name="Target", Order=3, GroupName="Parameters")]
      public int Target
      { get; set; }
      
      [Browsable(false)]
      [XmlIgnore]
      public Series<double> Sells
      {
      get { return Values[1]; }
      }
      
      [Browsable(false)]
      [XmlIgnore]
      public Series<double> Buys
      {
      get { return Values[0]; }
      }
      
      
      #endregion
      
      }
      }

      Comment


        #4
        Hello gyilaoliver,

        That is because the plots you are referencing are not added, you missed the AddPlot code in the indicators OnStateChange.

        If you are going to use the code from the bts indicator you need all 3 plots and the remainder of its logic from OnBarUpdate and public properties to make it work the same. If you don't need the additions that bts has you can also reference the code in the BuySellVolume indicator which is a little more simple.

        Comment


          #5
          Hi Jesse,
          I added the plots, now my strategy is running in historical and real time mode, but after a while I get this error and my chart freezes :
          Click image for larger version

Name:	image.png
Views:	57
Size:	33.0 KB
ID:	1305430

          Comment


            #6
            Hello gyilaoliver,

            Do you have a small sample of the code being used when you see that error? Unfortunately that is a generic error that doesn't tell us what the problem may be, we would need to know what specific code was used when you got that to get a direction on a solution.

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by NullPointStrategies, Today, 05:17 AM
            0 responses
            44 views
            0 likes
            Last Post NullPointStrategies  
            Started by argusthome, 03-08-2026, 10:06 AM
            0 responses
            124 views
            0 likes
            Last Post argusthome  
            Started by NabilKhattabi, 03-06-2026, 11:18 AM
            0 responses
            65 views
            0 likes
            Last Post NabilKhattabi  
            Started by Deep42, 03-06-2026, 12:28 AM
            0 responses
            42 views
            0 likes
            Last Post Deep42
            by Deep42
             
            Started by TheRealMorford, 03-05-2026, 06:15 PM
            0 responses
            46 views
            0 likes
            Last Post TheRealMorford  
            Working...
            X