Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Can you operate on secondary bars series within OnRender()?

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

    Can you operate on secondary bars series within OnRender()?

    Hello.

    Assuming you've added a secondary time series in State.Configure like so:
    Code:
    AddDataSeries(BarsPeriodType.Minute, 60);        //S1 or Series 1, BarsArray[1]
    Looking at the ChartBars definition, it says:
    The ChartBars class provides GUI access related methods and properties to the primary bars series configured on the Chart through the Data Series menu. For data access information related to the NinjaScript input's bars series, please use the Bars Series object (or the BarsArray for multi-series input)
    With that in mind, a common loop in onRender() would look like the following, where you get the start/end bars of the PRIMARY bar series. Here, it's just looping over the PRIMARY series, and would do some stuff after to draw.
    Code:
            protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
            {
                int rightMostBar = ChartBars.ToIndex;                     //Note:First bar on chart is 0
                int leftMostBar = ChartBars.FromIndex;                     //Note:First bar on chart is 0
    
                SharpDX.Direct2D1.SolidColorBrush solidColorBrush;
    
                for (int i=leftMostBar; i <= rightMostBar; i++) //Start at necessary List position
                {        
                    float currentX = chartControl.GetXByBarIndex(ChartControl.BarsArray[0], i);
                    ...    
                    ...
                    ...
                }​
    Question is, can you create a loop that will run over a secondary series, within OnRender(). I.e., setting the leftmost visible bar, the rightmost visible bar of the secondary series and then loop over it in the same way you can the PRIMARY?

    I see you could change the "BarsArray" to get the XbyBarIndex, but that is only a piece of it.

    Thanks,
    FP

    #2
    Hello forrestang,

    That would not be possible, the OnRender properties all link to the primary bars where the script is applied for rendering purposes. While you technically can use items like Closes[1].GetValueAt() that will likely have errors because the indexing won't match up with the primary series unless the secondary series was an identical type series.

    The best solution would be to create a Series<double> that is associated with the primary series and then assign values to that from the secondary series in OnBarUpdate. That way the series indexing matches the primary bars.

    mySeries[0] = Closes[1][0];

    And then in OnRender

    mySeries.GetValueAt()

    Comment


      #3
      Originally posted by NinjaTrader_Jesse View Post

      The best solution would be to create a Series<double> that is associated with the primary series and then assign values to that from the secondary series in OnBarUpdate. That way the series indexing matches the primary bars.

      mySeries[0] = Closes[1][0];

      And then in OnRender

      mySeries.GetValueAt()
      THanks.

      I have another question on that line.

      If I am working within a secondary series, in OBU, like this:
      Code:
                  if ( BarsInProgress == 6 )    //M1440, S6
                  {​
                     .....
                  }​
      I have a TIME, from the SECONDARY series, "BarsInProgress==6", I would like take this time, and find the corresponding index on the PRIMARY bar series.

      So I have this tutorial on my PC, "Calculating the highest high or lowest low for a specified time range," but that is on the primary series.

      The issue is one of syntax.

      I believe this will give you the absolute index of the bar?
      Code:
      int startBarsAgo = Bars.GetBar(startDateTime);
      However, if working WITHIN a secondary code block, how do you modify the GetBar to reference the primary bar series?

      THanks,
      FP

      Comment


        #4
        I was trying to do something like this, but this obviously won't work. I.e, making an assignment INTO the primary series, while being in the secondary series event.

        Code:
        _fnd[  CurrentBar -ChartBars.GetBarIdxByTime(ChartControl.BarsArray[0], Times[bigTFndx][i])  ] =1;
        Where "Times[bigTFndx][i])" represents the DateTime I have, where I want to find the bar index of that DateTime, from the PRIMARY bar series. "_fnd" represents the primary series I am trying to assign soemthing to.

        I can make the above work, by:
        Code:
        _fnd[  CurrentBar -ChartBars.GetBarIdxByTime(ChartControl, Times[bigTFndx][i])  ] =1;


        But this is the CurrentBar of the SECONDARY series.
        Last edited by forrestang; 08-03-2024, 09:53 AM.

        Comment


          #5
          Just an update.

          So I managed to get the assignment to the PRIMARY to work using GetBarIdxByTime and using CurrentBars instead of CurrentBar.

          Code:
          if (BarsInProgress == 6 )    //M1440, S6
          {
            ...
            ...
            _fnd[CurrentBars[0] -ChartBars.GetBarIdxByTime(ChartControl, Times[smallTFndx][i])] =1;​
          The above seems to place the proper index location on the PRIMARY series.

          However, I am using this inside OnBarUpdate(). I see the following on the ChartBars class.
          Note: A ChartBars object will ONLY exist should the hosting NinjaScript type be loaded through a Chart. For example, a Strategy would have access to a ChartBars property when running on a Chart, but would NOT when loaded through the Strategies Grid or Strategy analyzer.

          Warning: It is crucial to check for object references before accessing the ChartBars otherwise possible null reference errors can be expected depending on where the NinjaScript object was started. See example below


          Is this not an advisable way to do this? I am not worried about the STRATEGY PART mentioned above, but the potential for NULL references... could this be code breaking?

          Thanks,
          FP

          Comment


            #6
            Hello forrestang,

            The ChartBars class is only relevant for when a strategy exists in a chart, because strategies can run in multiple locations, some without charts, that is what that note is for. If your logic relies on that then you will not be able to backtest the strategy and it will be required to run only in a chart. ChartBars is primarily only used for rendering purposes which is the reason that it works like that.

            The note mentions checking for null which is advisable in C# in general for any object that you use which can be null. That is just a condition like this:

            if(ChartBars != null)
            {
            //do something because its not null
            }

            Regarding getting the time and index, that will work as long as that time exists on the series being checked.

            Comment

            Latest Posts

            Collapse

            Topics Statistics Last Post
            Started by Geovanny Suaza, 02-11-2026, 06:32 PM
            0 responses
            589 views
            0 likes
            Last Post Geovanny Suaza  
            Started by Geovanny Suaza, 02-11-2026, 05:51 PM
            0 responses
            342 views
            1 like
            Last Post Geovanny Suaza  
            Started by Mindset, 02-09-2026, 11:44 AM
            0 responses
            103 views
            0 likes
            Last Post Mindset
            by Mindset
             
            Started by Geovanny Suaza, 02-02-2026, 12:30 PM
            0 responses
            555 views
            1 like
            Last Post Geovanny Suaza  
            Started by RFrosty, 01-28-2026, 06:49 PM
            0 responses
            552 views
            1 like
            Last Post RFrosty
            by RFrosty
             
            Working...
            X