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

Mode from a Series double

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

    #76
    Hi Chelsea, I noticed some new indexing errors
    Time Category Message
    21/03/2022 19:09:49 Default Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 301: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.

    Time Category Message
    21/03/2022 16:16:29 Default Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 602: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.


    Time Category Message
    21/03/2022 15:50:26 Default Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 201: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.

    Time Category Message
    21/03/2022 15:43:11 Default Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 201: Index was outside the bounds of the array.
    when increasing the BarsBack value for the mode snippets only (as usual, instead of using the prints straightaway, I proceeded first by commenting out a large portion of the script, then uncommenting successive parts of the large commented portion until I reached the few at fault lines (elimination process to isolate the offending lines prior to trying to guess what element to print (if you can't foresee what the offending element would likely be)), uncommenting first lines that wouldn't make sense being at fault/would make the least sense being at fault progressively to more likely to be at fault lines if you can make sense of them.

    The offending lines were
    PHP Code:
    double var4_0 = modes[0];
    double var4_1 = modes[1];
    double var4_2 = modes[2];
    double var4_3 = modes[3];
    
    double var4_01 = Instrument.MasterInstrument.RoundToTickSize(modes[0] / TickSize);
    double var4_02 = Instrument.MasterInstrument.RoundToTickSize(modes[1] / TickSize);
    double var4_03 = Instrument.MasterInstrument.RoundToTickSize(modes[2] / TickSize);
    double var4_04 = Instrument.MasterInstrument.RoundToTickSize(modes[3] / TickSize); 
    

    But those lines were necessary so after more trial I finally found
    I could solve the errors by commenting the unnecessary part of the foreach loop (I found out I didn't needed it while I thought I did need it prior to finding out I didn't) as
    PHP Code:
    // if (count.Value > max)
    // {
    // // Update the mode
    // mode = count.Key;
    // max = count.Value;
    // // Print("count.Key1 : " + count.Key);
    // }else 
    

    Now it works for all BarsBack value with the complete snippet as
    PHP Code:
    // Mode Code Starts Here
    
          // Initialize the return value
        double mode = 1;
        double max = 1;
    
        if (listOfSeriesValuesBarsBack != null && listOfSeriesValuesBarsBack.Count() > 0)
        {
    //         for (int element = 0; element < listOfSeriesValuesBarsBack.Count(); element++)
    //         {
    //           Print("CurrentBar : " + CurrentBar);
    ////           Print("listOfSeriesValuesBarsBack[element] : " + listOfSeriesValuesBarsBack[element]);
    //           Print("listOfSeriesValuesBarsBack.Count() : " + listOfSeriesValuesBarsBack.Count());
    //         }
    
      // Store the number of occurrences for each element
          // Key = Double value from listOfSeriesValuesBarsBack
          // Value = The frequency of the Double value from listOfSeriesValuesBarsBack
      Dictionary<double, double> counts = new Dictionary<double, double>();
      // Add one to the count for the occurence of a character
      foreach (double element in listOfSeriesValuesBarsBack)
      {
            if (counts.ContainsKey(element))
      counts[element]++;
            else
      counts.Add(element, 1);
      }
    
      // Loop through the counts of each element and find the
      // element that occurred most often
      foreach (KeyValuePair<double, double> count in counts)
      {
    //         if (count.Value > max)
    //         {
    //           // Update the mode
    //           mode = count.Key;
    //           max = count.Value;
    //           // Print("count.Key1 : " + count.Key);
    //         }else
            if (count.Value == max)
            {
              // Collect the doubles modes and the ints values
              modes.Add(count.Key);
              modesValues.Add(count.Value);
              // Print("count.Key2 : " + count.Key);
            }
          }
        }
    
    
    
        double var4_0 = modes[0];
        double var4_1 = modes[1];
        double var4_2 = modes[2];
        double var4_3 = modes[3];
    
        double var4_01 = Instrument.MasterInstrument.RoundToTickSize(modes[0] / TickSize);
        double var4_02 = Instrument.MasterInstrument.RoundToTickSize(modes[1] / TickSize);
        double var4_03 = Instrument.MasterInstrument.RoundToTickSize(modes[2] / TickSize);
        double var4_04 = Instrument.MasterInstrument.RoundToTickSize(modes[3] / TickSize); 
    

    Thanks again!

    Comment


      #77
      Hello PaulMohn,

      I'm not sure I'm following the specific issue.

      You are calling modes[0] and this is causing an indexing error?

      What is the .Count of modes?
      Chelsea B.NinjaTrader Customer Service

      Comment


        #78
        Thanks Chelsea for the correction hint.

        I just checked the modes.Count() and got 10070 as last count


        using those prints
        PHP Code:
        Print("Modes.Count() : " + modes.Count() + " Time[0] : " + Time[0]); 
        

        now i'm not sure about

        PHP Code:
        double var4_0 = modes[0];
        double var4_1 = modes[1];
        double var4_2 = modes[2];
        double var4_3 = modes[3]; 
        

        Do the indexes (modes[0]/[1]/[2]/[3]) get the 4 lasts or the 4 firsts modes.Values from the modes list (private List<double> modes, modesValues; )?

        i tested with

        PHP Code:
        double var4_0 = modes[modes.Count()];
        double var4_1 = modes[modes.Count()-1];
        double var4_2 = modes[modes.Count()-2];
        double var4_3 = modes[modes.Count()-3]; 
        

        but that returns those errors
        Modes.Count() : 3 Time[0] : 18/03/2022 04:00:00
        Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
        Modes.Count() : 1 Time[0] : 18/03/2022 04:00:00
        Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
        Modes.Count() : 5 Time[0] : 18/03/2022 04:00:00
        Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
        Modes.Count() : 5 Time[0] : 18/03/2022 04:00:00
        Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
        Modes.Count() : 3 Time[0] : 18/03/2022 04:00:00
        Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
        Modes.Count() : 1 Time[0] : 18/03/2022 04:00:00
        Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
        Thanks!

        Comment


          #79
          Hello PaulMohn,

          List indexes start at 0 and count up. [0] would be the first element. [1] would be the second element. [2] would be the third element, etc.

          Are you certain that the error is occurring with modes[0] when the modes.Count is 10070?

          That would not cause this error.

          To confirm, you have 100% isolated this line of code to the be the issue?

          Printing:
          Print(Time[0] + " modes.Count: " + modes.Count().ToString());
          Print(Time[0] + " modes[0]: " + modes[0].ToString());

          This causes an error right after the count appears and the print of the modes never appears because the error appears, is this correct?

          I wouldn't see how that would be possible, and I would need an exported reduced test script that only has the lines of code with those prints and the lines of code that add the elements to the list to test on my end.

          No other logic or prints should be in the script. Everything else needs to be removed.

          To export a NinjaTrader 8 NinjaScript so this can be shared and imported by the recipient do the following:
          1. Click Tools -> Export -> NinjaScript...
          2. Click the 'add' link -> check the box(es) for the script(s) and reference(s) you want to include
          3. Click the 'Export' button
          4. Enter a unique name for the file in the value for 'File name:'
          5. Choose a save location -> click Save
          6. Click OK to clear the export location message
          By default your exported file will be in the following location:
          • (My) Documents/NinjaTrader 8/bin/Custom/ExportNinjaScript/<export_file_name.zip>
          Below is a link to the help guide on Exporting NinjaScripts.
          http://ninjatrader.com/support/helpG...-us/export.htm


          As a tip, I would recommend doing investigation before making more changes. Making changes without understanding the issue, makes it hard for anyone to assist because the code is constantly changing.

          Further, clear the output window before each test so you are not confusing when the error is appearing.
          Chelsea B.NinjaTrader Customer Service

          Comment


            #80
            This
            PHP Code:
                double var4_0 = modes[0]; 
            
            works fine and returns
            Modes.Count() : 7096 Time[0] : 21/03/2022 21:30:00
            But that
            PHP Code:
                double var4_0 = modes[modes.Count()]; 
            
            returns

            Modes.Count() : 58 Time[0] : 18/03/2022 04:00:00
            Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
            Modes.Count() : 57 Time[0] : 18/03/2022 04:00:00
            Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
            Modes.Count() : 68 Time[0] : 18/03/2022 04:00:00
            Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
            Modes.Count() : 68 Time[0] : 18/03/2022 04:00:00
            Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
            Modes.Count() : 67 Time[0] : 18/03/2022 04:00:00
            Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
            Modes.Count() : 51 Time[0] : 18/03/2022 04:00:00
            Indicator 'Testa': Error on calling 'OnBarUpdate' method on bar 101: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
            The complete at fault snippet
            PHP Code:
            // Mode Code Starts Here
            
                  // Initialize the return value
                double mode = 1;
                double max = 1;
            
                if (listOfSeriesValuesBarsBack != null && list OfSeriesValuesBarsBack.Count() > 0)
                {
            //         for (int element = 0; element < listOfSer iesValuesBarsBack.Count(); element++)
            //         {
            //           Print("CurrentBar : " + CurrentBar);
            ////           Print("listOfSeriesValuesBarsBack[element] : " + listOfSeriesValuesBarsBack[element]);
            //           Print("listOfSeriesValuesBarsBack.Count () : " + listOfSeriesValuesBarsBack.Count());
            //         }
            
              // Store the number of occurrences for each element
                  // Key = Double value from listOfSeriesValuesBarsBac k
                  // Value = The frequency of the Double value from li stOfSeriesValuesBarsBack
              Dictionary<double, double> counts = new Dictiona ry<double, double>();
              // Add one to the count for the occurence of a chara cter
              foreach (double element in listOfSeriesValuesBar sBack)
              {
                    if (counts.ContainsKey(element))
              counts[element]++;
                    else
              counts.Add(element, 1);
              }
            
              // Loop through the counts of each element and find  the
              // element that occurred most often
              foreach (KeyValuePair<double, double> count in c ounts)
              {
            //         if (count.Value > max)
            //         {
            //           // Update the mode
            //           mode = count.Key;
            //           max = count.Value;
            //           // Print("count.Key1 : " + count.Key);
            //         }else
                    if (count.Value == max)
                    {
                      // Collect the doubles modes and the ints values
                      modes.Add(count.Key);
                      modesValues.Add(count.Value);
                      // Print("count.Key2 : " + count.Key);
                    }
                  }
                }
            
                Print("Modes.Count() : " + modes.Count() + " Time[0] : " + Time[0]);
            
                double var4_0 = modes[modes.Count()];
            //    double var4_1 = modes[1];
            //    double var4_2 = modes[2];
            //    double var4_3 = modes[3];
            
                double var4_01 = Instrument.MasterInstrument.RoundToTickSize(modes[0] / TickSize);
            //    double var4_02 = Instrument.MasterInstrument.RoundToTickSize(modes[1] / TickSize);
            //    double var4_03 = Instrument.MasterInstrument.RoundToTickSize(modes[2] / TickSize);
            //    double var4_04 = Instrument.MasterInstrument.RoundToTickSize(modes[3] / TickSize); 
            



            I'm trying to get the 4 most recent modes values only (not the oldest ones).


            Assuming the chronologically ordered from left to right sequence of values:
            21, 21, 21, 17, 17, 5, 5, 5, 5, 5, 5, 5, 0,1,1,1,2,2,3,4, 7, 7, 7, 7, 9, 9, 9, 9, 9
            with a BarsBack value of 20 (starting from the most recent mode value (the rightmost 9 value) going backward)

            I'd need the modes to be listed as
            9, 7, 1, 2 (discarding the 21 and 17 and 5 modes values because they are the oldest / outside of the BarsBack set)

            9 = 1st max (because count = 5)
            7 = 2nd max (because count = 4)
            1 = 3rd max (because count = 3)
            2 = 4th max (because count = 2)

            Would
            PHP Code:
            double var4_0 = modes[0];
            double var4_0 = modes[1];
            double var4_0 = modes[2];
            double var4_0 = modes[3]; 
            
            return that
            9 = 1st max (because count = 5)
            7 = 2nd max (because count = 4)
            1 = 3rd max (because count = 3)
            2 = 4th max (because count = 2)

            ?

            Or would (assuming the latest modes.Count = Modes.Count() : 7096 Time[0] : 21/03/2022 21:30:00)

            PHP Code:
            double var4_0 = modes[7096]; / double var4_0 = modes[Modes.Count()];
            double var4_0 = modes[7095]; / double var4_0 = modes[Modes.Count()-1];
            double var4_0 = modes[7094]; / double var4_0 = modes[Modes.Count()-2];
            double var4_0 = modes[7093]; / double var4_0 = modes[Modes.Count()-3]; 
            
            return that
            9 = 1st max (because count = 5)
            7 = 2nd max (because count = 4)
            1 = 3rd max (because count = 3)
            2 = 4th max (because count = 2)

            ?

            Or do you know of another correction? Thanks!
            Last edited by PaulMohn; 03-21-2022, 04:20 PM.

            Comment


              #81
              Hello PaulMohn,

              modes[modes.Count()]; would be an index that does not exist.

              Lets say that modes had 10 elements in it, 0 through 9. If you call modes.Count, this returns 10. But because the indexes start at 0, the highest index is 9. So calling for the 11th element with the index [10] causes an error with an invalid index.

              If you want the last element it would be .Count() - 1.
              Chelsea B.NinjaTrader Customer Service

              Comment


                #82
                Hey Chelsea, I found an 07 post that makes CurrentBar clearer

                https://ninjatrader.com/support/foru...chart#post1409

                It seems we can control how many bars back the script must go with the
                PHP Code:
                Bars.Count 
                

                Would for example Bars.Count - 7 guarantee that the script would only go back up to 7 bars from the currently processing bar on the chart? Thanks!

                If that's the case, why not always be that specific instead of the usual if (CurrentBar < n) return; ?

                And even further why not use Bars.Count and remove altogether CurrentBar as for example

                if (Bars.Count < n ) return; (instead of (CurrentBar < n) return; ) ?

                Is there any difference between
                PHP Code:
                if (Bars.Count  < n ) return; 
                
                and
                PHP Code:
                if (CurrentBar < n) return; 
                
                ?



                Determining "Last Bar On Chart"

                01-16-2007, 06:14 AM
                If you want to incorporate some logic to have your indicator or strategy only run on real-time data, then you should incorporate the following.

                Checks if bar data is historical or real-time. Ifhistorical, return out of the method.

                protected override void OnBarUpdate()
                {
                if (Historical)
                return;
                }
                If you want to know if the bar being processed is the last bar on the chart.

                When CalculateOnBarClose == false, then OnBarUpdate() is being called for the last bar on the chart:

                protected override void OnBarUpdate()
                {
                if (CurrentBar == Bars.Count - 1)
                // Is last bar on chart
                }
                When CalculateOnBarClose == true, then OnBarUpdate() is being called for the last closed bar on the chart, not thein processbar:

                protected override void OnBarUpdate()
                {
                if (CurrentBar== Bars.Count -2)
                // Is last bar on chart
                }
                Ray

                Why not explicitly add the Bars.Count "method" and distinguish it to the CurrentBar and Currentbars Ninjatrader 8 documentation pages?

                https://ninjatrader.com/support/help...currentbar.htm

                https://ninjatrader.com/support/help...urrentbars.htm

                That should/might solve 90%+ of the Indexing error

                Instead of a Feature request, would you please add a Documentation update request (to explicitly add the Bars.Count "method" and distinguish it to the CurrentBar and Currentbars Ninjatrader 8 documentation pages) ?

                https://ninjatrader.com/support/foru...698#post806698

                Thanks!
                Last edited by PaulMohn; 03-29-2022, 09:19 AM.

                Comment


                  #83
                  Hello PaulMohn,

                  Bars.Count is the total of bars which increases as new bars form in realtime.

                  CurrentBar is the currently processing bar number.

                  Any barsAgo index must be less than CurrentBar, the currently processing bar number.

                  See this post on indexing errors.
                  Hello, I want to create an indicator that show data in a chart but calculate in other charttime different to the time of the chart where is showed. For example:


                  I did not see that you were requesting how to find the last historical bar in your previous posts. However, see this post on finding the last historical bar. (at the bottom)
                  Hello All! I'm working on strategy with the next logic: According the defined conditions I submit EnterLongLimit with defined price. On every new bar close I check the change of desired EnterLongLimit price and if it is different from previously submitted price - I change EnterLongLimit order price by submitting new order
                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #84
                    Ah ok, the count can be used with CurrentBar too as I see from the post you shared.


                    PHP Code:
                    protected override void OnBarUpdate()
                    {
                       if(CurrentBar < Count-2 ) return;
                    ....
                    } 
                    

                    PHP Code:
                    if (State == State.Historical && CurrentBar == Count - 2) 
                    

                    That's good to know.

                    It seems that way with the Count we can "start" the script similar to the BarsAgo way backward and specify the exact number of bars in the bars Check the script is allowed to calculate from. That makes it easier (more visually checkable) than conceptually going forward from whatever the initial leftmost bar may be to calculate from.


                    Please can you add a request to update the CurrentBar and Currentbars Ninjatrader 8 documentation pages to mention the Count use and provide the distinction? Thanks!
                    Last edited by PaulMohn; 03-29-2022, 09:37 AM.

                    Comment


                      #85
                      Hello,

                      CurrentBar should be used for preventing any index errors.

                      Bars.Count should only be used when trying to find the last bar and no where else.

                      Bars.Count is not documented, as the use of this is generally discouraged.
                      Chelsea B.NinjaTrader Customer Service

                      Comment


                        #86
                        Why would it be discouraged?

                        Please can you answer my previous question

                        Is there any difference between

                        PHP Code:
                        if (Bars.Count  < n ) return; 
                        
                        and

                        PHP Code:
                        if (CurrentBar < n) return; 
                        

                        Don't both checks provide the same stating bar for the script to begin (Bars.Count being more specific)?

                        Thanks!

                        Comment


                          #87
                          Hello PaulMohn,

                          Because CurrentBar should be used to prevent index errors.

                          Bars.Count will not consistent as this changes from historical to real-time.
                          Chelsea B.NinjaTrader Customer Service

                          Comment


                            #88
                            Ok. Do you have a simple example / doc to illustrate the from historical to real-time change issue with Bars.Count? And any fix to permanently prevent that issue?
                            I'd like to know more about the Bars.Count as I'm considering using it instead of CurrentBar always going forward, especially to prevent indexing errors. Thanks!

                            Comment


                              #89
                              Hello PaulMohn,

                              I recommend you use the documented CurrentBar unless you are specifically trying to find the last historical bar.

                              Count is documented. But CurrentBar should be used to prevent index errors.


                              To illustrate print Bars.Count and State at the top of OnBarUpdate outside of any conditions.

                              Print(string.Format("{0} | State: {1}, Bars.Count: {2}", Time[0], State, Bars.Count));
                              Chelsea B.NinjaTrader Customer Service

                              Comment


                                #90
                                Ok Thanks Chelsea. I'll test the prints next. But I'll try to use both going forward and check if I get no/less index errors. If I do I'll use both as shown in the 2007 post

                                PHP Code:
                                if (CurrentBar < Bars.Count - 7) 
                                

                                going forwards.

                                That way I could benefit from both with the added more specific advantage of the Bars.Count rather than any index or any variation of Check of CurrentBar +/- n.

                                The CurrentBar Documentation still would benefit from an update, as almost every day indexing errors are experienced by users. It would likewise reduce the need for support in this regard.

                                Thanks!
                                Last edited by PaulMohn; 03-29-2022, 12:15 PM.

                                Comment

                                Latest Posts

                                Collapse

                                Topics Statistics Last Post
                                Started by molecool, Today, 01:48 PM
                                1 response
                                4 views
                                0 likes
                                Last Post NinjaTrader_Jesse  
                                Started by ETFVoyageur, Today, 12:26 PM
                                3 responses
                                11 views
                                0 likes
                                Last Post NinjaTrader_ChelseaB  
                                Started by ETFVoyageur, Today, 10:34 AM
                                9 responses
                                21 views
                                0 likes
                                Last Post NinjaTrader_ChelseaB  
                                Started by HiddenPhilosopher, 05-22-2020, 01:09 AM
                                28 responses
                                2,722 views
                                0 likes
                                Last Post NinjaTrader_ChelseaB  
                                Started by warpinator, 05-16-2024, 10:44 AM
                                11 responses
                                60 views
                                0 likes
                                Last Post ETFVoyageur  
                                Working...
                                X