Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90


Very confused on how to loop through the bars correctly

  • Filter
  • Time
  • Show
Clear All
new posts

    Very confused on how to loop through the bars correctly

    I'm coming from MT4/MT5 and am trying to convert an indicator.
    Finding the Ninjascript documentation to be very confusing and thin to be honest. I'm not finding the examples to be very helpful. Referencing bars seems more complicated than what it should be.

    I'm getting out-of range errors and have been trying to change the "CurrentBar < X" values to make it work without luck.

    Since Ninjatrader reads from left to right is there a way to skip all the bars from the left and only work with for example the most recent 50 bars from the right?
    Like doing something like "If CurrentBar == MostRecentBar"

    In MT5 there is a way to "copy rates" into an array and reverse it so that your last rates (Ninjatraders most recent bar to the right) will be the first in the array. You can then work with that array from the right side. It makes things so much easier. Is there a way to do this in Ninjascript? I rather not scan through the entire chart just to work with the most recent bars. Is there something like "Close[LastBar]" to make things easier to work from the right side of the chart?

    If I wanted to store the swing highs/lows from this picture below, with some simple pseudo code, would Close[100] be the bar to the left of the top and Close[101] be the downbar?
    If so, then a for-loop would need to count down to go through the bars to the left correct? If these bars were the most recent ones to the right side of the chart instead, what would be the best way to loop through them?

    Click image for larger version

Name:	looping.png
Views:	613
Size:	45.3 KB
ID:	1203210

    A NinjaScript Series is not the same as an Array.

    A Series grows differently than an array. Every time a new bar is added
    to the chart, by definition, that bar becomes the most recently closed bar.

    Series are 'read' from right to left -- the index '0' is always on the right.

    [Even when populating 10 days of historical bars on the chart, the bars
    are added one at a time, and for a small brief period each of those
    historical bars is considered the 'most recently closed bar' -- and then
    a new bar is added, and that title moves to the new bar. Each new
    bar is always added to the right.]

    How do you access the OHLC values of the most recently closed
    bar? Remember, the concept of the 'most recently closed' is self
    adjusting, because each new bar inherits the title.

    In NinjaTrader, the 0th index always represents the most recently closed
    bar. The OHLC values are stored in a set of parallel series,


    The index value in a Series has a special name, it's actually called the
    'BarsAgo index' -- which is an attempt to help you remember just how
    far back into the chart you are accessing bars.

    Close[1] is the previous recently closed bar, and is always 1 bar to the
    left of the most recently closed bar. Close[2] is the next most recent,
    and so on.

    Whereas Array indexes grow to the right, the BarsAgo index in a
    Series grows to the left.

    Consider 1,000 bars on a chart. The bar on the far right, which is the
    most recently closed bar, is accessed with BarsAgo index of 0. The
    oldest bar at the far left has BarsAgo index of 999.

    That is, the close values are accessible,
    Close[0] - newest bar - on far right
    Close[999] - oldest bar -- on far left

    When the 1001st bar closes, all the indexes for all the bars shift by
    one so that the newly closed bar remains accessible at BarsAgo of 0.
    The oldest bar at the far left is still accessible, but it's BarsAgo index
    has changed to 1000.


    Think about a moving average with a period of 10. You need to access
    the 10 most recently closed bars, and this moving 'window' shifts for
    each new bar added to the chart.

    In NinjaScript, the 10 most recently closed bars can be accessed in
    a loop, and a simple moving average can be calculated like this,

    double Sum = 0;
    for (int i = 0; i < 10; ++i)
        Sum = Sum + Close[i];
    Print("Simple moving average = " + Sum/10);
    You must understand that because the BarsAgo index of 0 is always
    updated to represent the most recently closed bar, the moving 'window'
    of the 10 most recently closed bars is precisely what the loop looks at.

    That is, the moving window of close values are accessible,
    Close[0] - newest bar - on far right
    Close[9] - 10th oldest bar - to the left
    and this moving window adjusts accordingly each time a bar closes.

    Ah, but we have a problem.
    The above loop needs to be protected during the creation of the first
    10 bars, so that it doesn't access a bar that doesn't yet exist. That is,
    we want the code to wait for 10 bars to arrive before it executes the
    for loop. [Eg, when only 2 bars exist, accessing Close[5] is an error]

    That's why you might see guard code like this,

    if (CurrentBar < 10)
    just before that for loop.

    Make sense?

    Last edited by bltdavid; 05-29-2022, 11:10 AM.


      Thank you @bltdavid for that great explanation. Far better than what I could find in the documentation. I think what is most confusing coming from coding for Metatrader is the CurrentBar value seeing as that starts from the very left and moves to the right. Metatrader code doesn't care about CurrentBar, so reading the bars series is far easier.

      The terminology of having Bar index starting from left and Bars Ago from the right doesn't make Ninjascript any less confusing either. What one would like to refer to as "Bar index" in Metatrader starts from the right, so when referring to Bar index of 10 and the Close value to that bar it would be 10 bars from the right, while in Ninjascript those things are on opposite sides.

      It doesn't help when Ninjatrader reference guide has text like this:

      "On the very first bar (think of the 1st bar on the chart from left to right) the value of "close of 1 bar ago" (Close[1]) does not yet exist and your indicator/strategy will not work and throw an exception to the Control Center Log tab "Index was out of range...".

      I'm still having some really strange errors where values are way off (Plots showing dots nowhere near a Bar) when looping through the Series after setting values on the first run, so I'll have to continue troubleshooting. Ninjatrader really should rewrite a lot of the documentation though, it is hard to search as well as find clear information. They have poorly written examples that are not very useful etc. Metatrader is far better in showing what you can actually do with the language. Thanks once again!
      Last edited by PMitchum; 05-28-2022, 12:35 PM.


        Hello PMitchum,

        The indexes for series being reversed is to try and make access easier for new programmers. Using an index of 0, like Close[0] or Time[0] would always refer to the most recently updated bar without having to know the count or how in programming collections start at 0 and not 1, which can be confusing.

        However, if that is your personal preference, you can use Bars.GetClose() or Bars.GetTime() with an absolute bar index that starts from 0 and counts forward is not a barsAgo index.

        Regarding the error messages, what is the full error message your have received?

        Regarding the objects appearing on incorrect bars, are these being drawn 0 bars ago when the condition is true?
        Are you trying to draw on previous bars?
        Are you looping from the current bar (0 bars ago) to the first bar (CurrentBar 's ago)?
        Chelsea B.NinjaTrader Customer Service


          Ironically the way Ninjascript documentation is written it will probably make new programmers confused instead. I'm not new to coding indicators and I am. Reading through the forum it seems more people are as well. Even very experienced programmers. I'm used to having Bar index be the same as the OHLC index, but it's not in Ninjascript so no wonder the terminology is confusing.

          About the errors I had. I had a series where I set values at the very same time as the Plot series, just so I would visually be able to see them. But when I tried to get the values out they weren't the same as the plot values. Seing as the documentation claimed series to be synchronized to the primary data series, it didn't make much sense. I did however solve it by just referencing to the plot values instead so I got it working now.


          Latest Posts


          Topics Statistics Last Post
          Started by Matt Skinner, Today, 01:55 AM
          0 responses
          Last Post Matt Skinner  
          Started by visasimple, Today, 01:40 AM
          0 responses
          Last Post visasimple  
          Started by Caspersky_, Yesterday, 12:22 PM
          4 responses
          Last Post Caspersky_  
          Started by SDaCosta30, Yesterday, 11:31 PM
          0 responses
          Last Post SDaCosta30  
          Started by kingsteven, Yesterday, 08:34 PM
          2 responses
          Last Post kingsteven