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

C# Newbie - Please Help Me Understand Using Bar Data

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

    C# Newbie - Please Help Me Understand Using Bar Data

    ES Dec 2022 30Min Chart

    EDIT -- DO NOT USE ADD DATA SERIES if you don't need it!! This was causing OnBarUpdate() to execute more than once, which may trip you up if you're not expecting it. I am a total n00b and was using it, even though there wasn't a good reason to. Thanks, bltdavid!!

    ----------

    Given the above instrument/time period -- I'm trying to deal with bar data (Open/High/Low/Close) within a given interval window for making a custom indicator. When I've queried the Count of a loaded chart, I'll get a number like 114 -- but if I try to reference the Close[114] using that index, its out of range. So I'm struggling to get what is going on here.

    Essentially, given a bar chart and time period, and knowing the number of bars loaded - how do you access the furthest back in time, iterating using the interval window to make some calculations, all the way to the Bar 1?

    I used to do NinjaTrader, but an ancient version - so none of the old code I have will work directly, so I'm porting it to Ninjatrader 8. I just find the Series/Bars documentation a bit confusing, and using Print statements hasn't helped much. I can get prices, but for instance Close[1] doesn't match what I have on my chart for the time period, even if I do some debug statements confirming the instrument time period, etc...

    I don't know if it has anything to do with working with the EOD data that was available (My full ticker subscription isn't set up yet - my funding wire is in progress.).

    Just looking for some newbie help and staring at the API isn't it.

    Anything is appreciated, thanks.
    Last edited by TallTim; 12-18-2022, 11:58 AM.

    #2
    BarsAgo index numbers are zero-based.

    So, if CurrentBar is 114, those 114 bars are
    accessible as [0] through [113], if you try to
    access [114] you will get an out of range error.

    Code:
    Print("Bar="+CurrentBar);
    for (int BarsAgo = 0; BarsAgo < CurrentBar; ++BarsAgo)
        Print(string.Format(" BarsAgo={0}: Open={1} High={2} Low={3} Close={4}",
                BarsAgo, Open[BarsAgo], High[BarsAgo], Low[BarsAgo], Close[BarsAgo]));
    The above code is untested.
    Last edited by bltdavid; 12-12-2022, 06:24 AM.

    Comment


      #3
      Also, your screenshot shows 'Bar[0] = Current'.
      Let's talk about that. You're new, right?

      Using the word 'Current' like that ... whoa whoa whoa,
      that word is too loaded -- be careful with that word.

      I mean, you shouldn't really think like that. The word
      'Current' is actually too imprecise, let's discuss.

      Is Bar[0] really the current bar?
      That depends.

      Why?
      Because it depends on the Calculate setting.

      When Calculate is OnBarClose, then Bar[0] is
      'the most recently closed bar' -- meaning the active
      bar under construction is effectively inaccessible,
      since you have to wait for the bar close event
      to see the active bar's final OHLC values. Here,
      the Bar[1] values are the 2nd most recently closed
      bar, and Bar[2] is the 3rd most recent, etc, all the
      way back to Bar[CurrentBar-1].

      Btw, the '0' in 'Bar[0]' is known as the 'BarsAgo index', because
      you typically access bars in a backwards context. That is,
      the OHLC values at Bar[0] change every time a bar closes,
      indexes get shifted backwards to the next higher number, so
      that the newly closed bar always occupies the slots at Bar[0].
      (Also, using the expression 'Bar[0]' is pseudo code, since that's
      not really a valid NinjaScript thing, whereas Close[0], or High[0],
      etc, is valid NinjaScript.)

      Does that make sense?
      The concept of 'most recently closed bar' is very critical.

      Ok, now let's say you'd like access to the OHLC values of the
      active bar under construction? Well, sure, that's possible. You
      would also do this using the Calculate setting. Yep.

      When Calculate is OnEachTick, then Bar[0] becomes
      'the active bar under construction' -- which means
      every tick is reflected in the OHLC values of Bar[0],
      and Bar[1] is shifted to mean the most recently closed
      bar, and Bar[2] is the 2nd most recent, etc, all the way
      back to Bar[CurrentBar].

      ​So, my point is, saying 'Bar[0] = Current' and using that to
      describe the right most bar on the chart, which is usually
      the active bar under construction, well, an old fart like
      me says your wording/thinking/paradigm is wrong. At
      least in the world of NinjaScript, I mean.

      In Summary:
      The right most bar on the chart is available in code -- if you
      use Calculate.OnEachTick -- and everything is adjusted so
      that the OHLC values at [0] reflect the current values of the
      active bar under construction. In this mode, the OHLC values
      of the most recently closed bar is always at [1].

      But most technical analysis doesn't care about the active bar under
      construction, they only deal with closed bars. This mode is the
      normal mode, and you get that with Calculate.OnBarClose, and
      everything is adjusted so that the OHLC values at [0] reflect the
      value of the most recently closed bar.

      See that?
      Saying 'Bar[0] = Current' is very imprecise, and just gets your
      mind in trouble. Don't say it that way.

      Bar[0] is either the 'most recently closed bar' or the 'active bar
      under construction' -- these are the best terms and offer the most
      precision -- saying Bar[0] is the 'current' bar is ambiguous, since
      the definition of the 'current' bar can change (because it depends
      on the Calculate setting).

      Make sense?

      Just my 2˘.

      Comment


        #4
        Thank you bitdavid - you gave me a lot to chew on, so I'm going to retreat into the ninjatrader editor and try a few things. What you're saying about "current" bar makes sense to me, and I'll have to construct some experiments just to verify that I am referencing the proper bar.

        I'll update this post when I have more, appreciate the input.

        Comment


          #5
          @bltdavid ​First of all, apologies for contacting you here, but I didn't know how else to do it.
          I really love your Blttriggerlines, but I had a suggestion/question?

          Would it be possible for the MAs to calculate the top MA line by bar high and the bottom MA line by bar low? e.g.
          Code:
                                     TopLine1 = DEMA(High, Period)[0];
                                     BottomLine1 = DEMA(Low, Period)[0];
          Whether or not you reply, thanks for gifting this valuable indicator to the community. I use it everyday!

          Comment


            #6
            Originally posted by davydhnz View Post
            Would it be possible for the MAs to calculate the top MA line by bar high and the bottom MA line by bar low? e.g.
            Code:
             TopLine1 = DEMA(High, Period)[0];
            BottomLine1 = DEMA(Low, Period)[0];
            Whether or not you reply, thanks for gifting this valuable indicator to the community. I use it everyday!
            Thank you for your kind words.

            That is an excellent suggestion!

            Indeed, BltTriggerLines needs some love and is overdue for an update.

            Comment


              #7
              Originally posted by davydhnz View Post
              First of all, apologies for contacting you here, but I didn't know how else to do it.
              Yeah, this should have been a brand new topic.

              See the attached screenshots, they will show you
              how it's done.

              Attached Files

              Comment


                #8
                I thought of posting a new topic, but I didn't know if you'd see it, that's why I apologized in advance.
                I didn't actually want to derail this thread. I appreciate that it's a rude thing to do, so sorry to you and the op for that.

                Thanks for your reply!​

                Comment


                  #9
                  No problem.

                  Try this -- type the '@' followed by a username, like bltdavid or davydhnz, you
                  should see a little tiny popup/dropdown box appear, positioned right there as you type, it will
                  show matching usernames as you type each letter -- select the name in the tiny dropdown
                  and that will insert what you see above.

                  The point is, that little trick ensures that I (or whomever) gets an email -- the forum software
                  automatically sends email to folks saying something like 'you were mentioned in a forum post'.

                  That's how you make sure a specific username sees your question.

                  I'm pretty sure you can 'mention' your own username and you'll still get an email.
                  (I'm about to find out with this post -- I never tried that before.)

                  Comment


                    #10
                    Originally posted by davydhnz View Post
                    I thought of posting a new topic, but I didn't know if you'd see it, that's why I apologized in advance.
                    I didn't actually want to derail this thread. I appreciate that it's a rude thing to do, so sorry to you and the op for that.

                    Thanks for your reply!​
                    We've all been there -- I'm just glad to get useful responses and such. And now, I learned more about the forum too! I'm going to dive into my bar problem and see if I can make more sense of this. Thanks again, bitdavid.

                    Comment


                      #11
                      So, armed with my newfound information I tried a simple test. It didn't go well. Here's the chart - BTCUSD (Coinbase) 30 minute: Click image for larger version  Name:	Coinbase_BTCUSD_30min.png Views:	0 Size:	21.4 KB ID:	1227334
                      Here's the output log:
                      Click image for larger version  Name:	BarHighOutputLog.png Views:	0 Size:	27.4 KB ID:	1227335
                      Here's the code where I'm making the call to access bar High data:
                      Click image for larger version  Name:	BarHighAccessCode.png Views:	0 Size:	11.1 KB ID:	1227336
                      So if I'm accessing the High at Count - 1, and it errors out -- what am I doing wrong here? Is it because my "Interval" is a period shorter than the total loaded bars? Wouldn't the price be accessible if it loaded 499 bars anyway? I'm just totally confused here.

                      And it doesn't help that the High it is reporting makes zero sense looking at the chart -- if its the bar before the one being 'built' why is the price so low?

                      Any help appreciated.

                      Comment


                        #12
                        EDIT -- DO NOT USE ADD DATA SERIES if you don't need it!! This was causing OnBarUpdate() to execute more than once, which may trip you up if you're not expecting it. I am a total n00b and was using it, even though there wasn't a good reason to. Thanks, bltdavid!!

                        I feel like I'm taking crazy pills. I specify it to print index values, I get the proper number but they all repeat twice with a single Print statement. I'm at the point where I'd pay someone just to code up a simple demo of taking a given study interval of 'n' bars and applying it to the entire loaded history to derive an indicator plot. I don't recall absolute bar data referencing being so difficult, but that was a few versions ago.
                        Last edited by TallTim; 12-18-2022, 11:57 AM.

                        Comment


                          #13
                          Hello TallTim,

                          if we assume the CurrentBar is greater than Interval by 1 that would be the max index that you could look up at that point in processing.

                          If we assume interval is 3 and the CurrentBar is now 4 you could use a max of High[4]. Using Count - 1 will result in an index error because the CurrentBar is not yet equal to Count - 1.

                          You could use High[CurrentBar] if you wanted to look at the furthest back data at that point in time.

                          JesseNinjaTrader Customer Service

                          Comment


                            #14
                            Originally posted by NinjaTrader_Jesse View Post
                            Hello TallTim,

                            if we assume the CurrentBar is greater than Interval by 1 that would be the max index that you could look up at that point in processing.
                            <snip>
                            Okay, so if I have an Interval for my indicator of 10 I would have a sliding window of indexes like:

                            [9] [8] [7] [6] [5] [4] [3] [2] [1 - most recent closed bar] [0 - bar still yet to close]

                            So what I was missing is its all relative to that interval?

                            I guess what is killing me here is picking out certain bar data irrespective of the interval -- if ninjatrader says I loaded 511 bars, why does Close[510] fail as an index?

                            Comment


                              #15
                              Hello TallTim,

                              When you run a script it processes all bars meaning it starts at bar 0 and moves forward. The Count is known ahead of time, that is the count of the historical bars but you haven't processed those bars yet.

                              If your Interval is 10 then the Prints you posted would only work starting at bar 11. You would have access to any data for the current bar or previous bars:

                              [11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0 - Current bar close]

                              In realtime after the bars have processed you can use [0] bars ago to access the current price assuming you ae using OnEachTick or OnPriceChange. If you use OnBarClose [0] always represents the most recent Closed bar.


                              I guess what is killing me here is picking out certain bar data irrespective of the interval -- if ninjatrader says I loaded 511 bars, why does Close[510] fail as an index?
                              Because you have to let the script process the 510 bars before you can access that many BarsAgo. The BarsAgo is to find data previous to now in processing. Lets assume you just applied the script, its going to process bar 0 so the max BarsAgo from now you can access is 0. After it processes 10 bars (10 OnBarUpdates) you could access a max of 10 bars, you are on bar 10 in processing so you can look backwards in time 10 bars. You cant look 510 bars in the past if 510 bars have not been processed yet, if you are on bar 10 and checked 510 bars ago that doesn't exist and will cause the index error.

                              The term index is used loosely with that error, we are really referring to a number of BarsAgo exceeding the processed bars in that use case.

                              JesseNinjaTrader Customer Service

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by Brevo, Today, 01:45 AM
                              0 responses
                              3 views
                              0 likes
                              Last Post Brevo
                              by Brevo
                               
                              Started by aussugardefender, Today, 01:07 AM
                              0 responses
                              3 views
                              0 likes
                              Last Post aussugardefender  
                              Started by pvincent, 06-23-2022, 12:53 PM
                              14 responses
                              239 views
                              0 likes
                              Last Post Nyman
                              by Nyman
                               
                              Started by TraderG23, 12-08-2023, 07:56 AM
                              9 responses
                              384 views
                              1 like
                              Last Post Gavini
                              by Gavini
                               
                              Started by oviejo, Today, 12:28 AM
                              0 responses
                              6 views
                              0 likes
                              Last Post oviejo
                              by oviejo
                               
                              Working...
                              X