Announcement

Collapse

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

Collapse

Need help with understanding what certain lines of code represent.

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

    Need help with understanding what certain lines of code represent.

    Hello,

    Can you please explain what these lines of code mean/represent. They are the first items that appear under OnBarUpdate().

    protected override void OnBarUpdate()
    {
    if (BarsInProgress != 0)
    return;


    if (CurrentBars[0] < 1
    || CurrentBars[1] < 0)
    return;




    #2
    Hello Don22Trader1,

    Thank you for your post.

    if (BarsInProgress != 0)
    return;


    This means if we are trying to process any additional data series other than the primary data series, we will instead exit On Bar Update instead of calculating the code below on that series. So, for example, if I am running my strategy on a 5 minute data series and I have added an additional 15 minute data series to the script, it will not calculate anything past this when the 15 minute series is updated but will exit OnBarUpdate instead.

    if (CurrentBars[0] < 1
    || CurrentBars[1] < 0)


    This is checking that we have at least 2 bars (the first and second bars all the way to the left of the chart would be CurrentBar == 0 and CurrentBar == 1 respectively) in the primary data series to calculate on, OR that there is at least 1 bar of the secondary data series.

    Please let us know if we may be of further assistance to you.
    Kate W.NinjaTrader Customer Service

    Comment


      #3
      Originally posted by Don22Trader1 View Post
      Hello,

      Can you please explain what these lines of code mean/represent. They are the first items that appear under OnBarUpdate().

      Code:
      protected override void OnBarUpdate()
      {
      [B][COLOR=#e74c3c]if (BarsInProgress != 0)
              return;[/COLOR][/B]
      
          if (CurrentBars[0] < 1 [COLOR=#e74c3c][B]|| CurrentBars[1] < 0[/B][/COLOR])
              return;
      First, this kind of code is called a 'guard'.
      [Guard code is a very common thing in the world of software engineering.
      It serves to protect code from execution until certain required conditions
      have been met.]

      When you see the code in red, it's a clue that AddDataSeries() is probably
      being called from OnStateChange.

      What does AddDataSeries do?
      AddDataSeries will add an additional bar series to your chart -- these are
      known as 'secondary data series' and are invisible to the chart. That is, only
      the primary data series is visually represented on the chart, any secondary
      data series are not. Secondary data series are programming aids only.

      Each call to AddDataSeries adds one additional secondary data series.
      You can add as many as you like.

      A secondary data series is just a supplementary bars series available to
      you, the programmer, inside your NinjaScript.

      Why do that?
      Well, because, if for some reason, you're wanting to look at multiple time
      frames, that's how you do it -- you add a secondary data series for the
      additional time frame you wish to monitor.

      The primary data series as well as all secondary data series end up calling
      your OnBarUpdate -- so how do you tell them apart?

      Ah-hah!
      That's what BarsInProgress (abbreviated BIP) is for. BarsInProgress is an
      internal property maintained by NinjaScript. A value of '0' always means
      your primary data series.

      Each time you call AddDataSeries, the maximum value of BarsInProgress
      is incremented by one. If you call AddDataSeries 100 times, then your
      OnBarUpdate will be called whenever a bar closes, for the primary bar series
      and for each secondary data series. [EDIT: How often OnBarUpdate is really
      called is controlled via the Calculate property.]

      Here's the cool thing.
      NInjaTrader will automatically pre-set the BarsInProgress property to a
      value between '0' and '100' -- this is how you tell you which data series
      is being processed.

      So, when you see guard code at the top of OnBarUpdate, like this,

      Code:
      [B][COLOR=#e74c3c]if (BarsInProgress != 0)
          return;[/COLOR][/B]
      This guard tells you one or more secondary data series may be employed
      by the script -- how many it doesn't matter -- because this guard guarantees
      that all of them will be ignored by OnBarUpdate.

      The primary data series is always BIP=0, so any other BIP value means it
      must be a secondary data series -- so this code stands guard to filter out
      all bars from all secondary data series -- because, by definition, when
      BIP > 0, it is a secondary data series.

      Why have OnBarUpdate filter out all bars from secondary data series?
      Because, presumably, the meat of OnBarUpdate processing code doesn't
      care about the BarClose event on those secondary bars. [EDIT: I mean,
      usually, when processing multiple time frames, the usual technique is to
      process bar close events on the primary bar series only. Then, as needed,
      you just inspect the current values of secondary bars. That means reacting
      to the bar close on the secondary data series can be skipped entirely.]

      After you guard against processing unwanted bar close events, the next thing
      to guard against is having too few bars for processing.

      That's what CurrentBars[0] and CurrentBars[1] is doing.
      Did you notice it was plural?

      CurrentBars[n] gives you current bar number for the nth data series.

      When 'n' is '0' it means your primary data series.

      When 'n' is '1' it means the 1st secondary data series (which refers to the
      1st call to AddDataSeries).

      When 'n' is '2' it means the 2nd secondary data series (which refers to the
      2nd call to AddDataSeries).

      And so on.

      So, what is this code doing?

      Code:
      if (CurrentBars[0] < 1 [COLOR=#e74c3c][B]|| CurrentBars[1] < 0[/B][/COLOR])
          return;
      Yep, it's another guard, and it protects the parts of your calculations that
      need to reference prior bars.

      Just like Kate said, that code is checking how many bars exist, so that
      in the very beginning stages of your chart, where the very first historical
      bars appear, the code guarantees that enough bars have arrived before
      it allows the rest of the code to execute.

      This code is saying it needs 2 bars on the primary data series, but only
      1 bar on the secondary data series. If either of the guard conditions is
      true, we don't have enough bars to continue, and we return -- and wait
      for the next OnBarUpdate.

      Think it through. CurrentBars[0] is 1 on the 2nd bar, so that means the
      guard succeeds, because 1 < 1 is false, so we know we have 2 bars, and
      only then does C# evaluate the condition on the right of the OR operator.

      But, looking at the OR condition, you start to think ... wait a minute.
      How can CurrentBars[1] ever be less than 0?
      That makes no sense. (Well, sure, no visual sense.)

      I know, I know, negative bars on a chart, right?
      How can that happen? Who would a thunk?

      That's a very good question.
      It turns out the bars from the secondary data series may not yet exist
      while the first few primary bars are being processed.

      Yep. Consider a 1-minute primary series. At the very start of the chart,
      you'll have 5 primary bars arrive before a single secondary bar arrives on
      a 5-minute secondary data series. Look at the table below. For the first
      six primary bars, the guard code will see these values,

      Code:
      [FONT=Courier New]1-minute bars   5-minute bars
      CurrentBars[0]  CurrentBars[1]
      ---------------------------------------
           0              -1
           1              -1
           2              -1
           3              -1
           4              -1
           5               0[/FONT]
      That means, for this example, the guard code allows OnBarUpdate to
      continue its processing only after the 6th primary bar arrives -- because
      that's how many 1-minute primary bars it takes before we get the first
      required secondary bar on the 5-minute secondary data series.

      And so why the '-1' value?
      There are no bars, why not just use '0' to mean 'no bars'?

      Because, CurrentBars[n] provides the current bar number of the bar being
      being processed. It does not mean total bars in the data series, so you
      can' t think like that. Think like this: each bar that is processed during the
      call to OnBarUpdate is identified by a bar number. All bar numbers for all
      primary and secondary data series start at '0'. So, when CurrentBars[1]
      is '0', is doesn't mean no bars exist -- '0' is the bar number of the first bar.

      That means NinjaScript can't use '0' to mean no bars.
      So, they use the '-1' value to mean no bars.

      Thus, when CurrentBars[1] < 0 is true, that means no bars exist yet
      on BIP=1. And if no bars exist on BIP=1, then we can't look at things like
      Closes[1][0], because the first bar at index '[0]' on BIP=1 doesn't exist yet.

      If we did try to access Closes[1][0], we'd get a runtime error similar to a
      'index out of range' error -- because you can't access the '[0]' index for the
      first bar until there is a first bar.

      So, there ya go, the ultimate purpose of that guard code is to protect us
      against that 'index out of range' error. QED.

      Make sense?
      Last edited by bltdavid; 12-23-2021, 06:09 PM. Reason: More emphasis on what the guard code is protecting against.

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by Waxavi, Today, 02:10 AM
      0 responses
      3 views
      0 likes
      Last Post Waxavi
      by Waxavi
       
      Started by TradeForge, Today, 02:09 AM
      0 responses
      8 views
      0 likes
      Last Post TradeForge  
      Started by Waxavi, Today, 02:00 AM
      0 responses
      2 views
      0 likes
      Last Post Waxavi
      by Waxavi
       
      Started by elirion, Today, 01:36 AM
      0 responses
      4 views
      0 likes
      Last Post elirion
      by elirion
       
      Started by gentlebenthebear, Today, 01:30 AM
      0 responses
      4 views
      0 likes
      Last Post gentlebenthebear  
      Working...
      X