Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

How to get the bar index of list's items?

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

    How to get the bar index of list's items?

    I got this error:
    Error on calling 'OnBarUpdate' method on bar 20: 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.
    From this code:

    Code:
    for(int i= MyList.Count - 5 ;i<MyList.Count;i++)
    {
    Print(" " + MyList[i]);
    }​​

    Commented out I get these prints:
    Code:
    //for(int i= MyList.Count - 5 ;i<MyList.Count;i++)
    //{
    //Print(" " + MyList[i]);
    //}​​​
    CurrentBar 25240
    MyList.Count 25222
    CurrentBar 25241
    MyList.Count 25223
    CurrentBar 25242
    MyList.Count 25224
    CurrentBar 25243​
    Is there some way to get the MyList items bar indices?

    Something like:

    Print("MyList Items Bars index " + Bars.GetBarIndex(MyList.Count - 5) );

    CurrentBar 25240
    MyList.Count 25222
    MyList Items Bars index ??
    CurrentBar 25241​


    In order to perform this kind of bars check:
    Code:
    if (CurrentBar < Bars.GetBarIndex(MyList.Count - 5))
    return;​

    #2
    Hello PaulMohn,

    The terminology is confusing here.

    Is MyList a List<T> or a Series<double> object type?

    Where is the declared in the code?

    CurrentBar is the number of primary bars that processed in OnBarUpdate().
    MyList may not be series object and not associated with the number of bars..

    Looping over a collection like a List, the <List>.Count() will be the number of elements. The indexes, however, start with 0, so will always have a value 1 less than the total count.

    For instance if there 10 elements, the indexes would be 0 through 9.

    Meaning subtract 1 from the count for any loop and start the loop at 0.

    for (int index = 0; index < MyList.Count() - 1; index++)
    {
    Print(string.Format("index: {0}, MyList[{0}]: {1}", index, MyList[index]));
    }

    CurrentBar starts with bar 0 and is not the total Count, but the index of the bar being processed in OnBarUpdate().

    for (int index = CurrentBar; index > 0; index--)
    {
    Print(string.Format("{0} | index: {1}, Close[{0}]: {2}", Time[index], index, Close[index]));
    }




    Where you have:
    if (CurrentBar < Bars.GetBarIndex(MyList.Count - 5))
    return;​​

    I'm not quite sure what this is meant to be doing.

    You should ensure that any barsAgo index for a Series<double> is less than CurrentBar.

    if (CurrentBar < 5)
    return;

    Print(Close[5]); // any index greater than 5 would cause an error

    For an unrelated List<T>, you want to ensure any indexes used on that list are less than the <List>.Count().

    if (MyList.Count() < 5)
    return;

    Print(MyList[5]); // any index greater than 5 would cause an error
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      NinjaTrader_ChelseaB Hello and thanks,

      I Have something like this:

      // Class Variable
      private List<int> MyList;

      protected override void OnBarUpdate()
      {


      ...

      DailyTrades = SystemPerformance.AllTrades.TradesCount - SessionStartTradeCount;
      lossesCount = SystemPerformance.AllTrades.LosingTrades.Count - SessionStartLosingTradesCount;
      winsCount = SystemPerformance.AllTrades.WinningTrades.Count - SessionStartWinningTradesCount;
      tradesProfits = SystemPerformance.AllTrades.TradesPerformance.NetP rofit - SessionStartNetProfitTrades;
      bottomLineTrades = (-1 * lossesCount) + winsCount;

      MyList.Add(bottomLineTrades);​

      if (CurrentBar < BarsRequiredToTrade)
      return;​

      bool x3 = CurrentBars[0] < ( (CurrentBars[0] + 20 ) - MyList.Count ) ;

      if (x3)
      return;

      for(int i= MyList.Count - 4 ;i<MyList.Count;i++)
      {
      Print(" ");
      Print(Times[0][0] + " MyList Items: " + MyList);
      }​
      ...
      }


      Instead of x3 bool, how can we use the Bar Index of MyList.Count - 5 ?

      Like this:
      if (CurrentBar < Bars.GetMyBarIndex(MyList.Count - 5))
      return;​​

      Is there a Ninjascript specific method to get this MyBarIndex?
      Something like the reverse of GetValueAt()?



      Or something like GetSlotIndexByX()​

      Comment


        #4
        Hello PaulMohn,

        A List<int> isn't related to a Series<double>.

        A List would have as many elements in it as you have added to it.

        A Series has a slot for each bar on the chart.

        The count of a list isn't relatable to the number of bars on a chart..

        I think you want to be using a Series<int> object type instead of a list..



        That said, I'm not clear on how you want to identify a bar to retrieve it's index.

        You can get a bar by it's time with Bars.GetBar().


        You can get a bar by it having the highest or lowest value.




        If you already have a bar index, then you can get values by that bar index.


        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          NinjaTrader_ChelseaB Hello,

          In a new script I have this error:

          Time Category Message
          18/09/2024 07:39:56 Default Indicator 'myScript': Error on calling 'OnBarUpdate' method on bar 51: 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.
          This bars check solves the error:

          Code:
          if (CurrentBars[0] > 200 )
          {​
          // double item1 = myList[myList.Count -1];
          // double item2 = myList[myList.Count -2];​
          }

          What way do you suggest of getting a non hardcoded CurrentBars[0] Check?

          I mean > 200 suggests the chart needs 200 bars before it can start calculating the values of
          double item1 = myList[myList.Count -1];
          double item2 = myList[myList.Count -2];​​


          But what is the way to get the required number of bars for the check without trying harcoded values?

          Also, for now the > 200​ value works, but with different bars timeframe it might not
          (for example when changing from a 5min timeframe Bars to a 10 seconds charts).

          What is the way you know of getting the right number of bars for the Bars check on any timeframe/chart bars type?

          Comment


            #6
            Hello PaulMohn,

            I would ensure the count of the collection is checked to ensure any index .

            private List<int> myList;

            if (myList == null)
            myList = new List<int>();
            myList.Add(1);

            double item1;

            if (myList.Count() > 200)
            {
            item1 = myList[myList.Count-1];
            }


            If you mean to be saving values for each bar, use a Series<T>.

            private Series<int> mySeries;

            if (mySeries == null)
            mySeries = new Series<int>(this);
            mySeries[0] = 1;

            double item1;

            if (CurrentBar > 200)
            {
            item1 = mySeries[0];
            }
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              That's not the answer to the latest questions:
              What way do you suggest of getting a non hardcoded CurrentBars[0] Check?​
              But what is the way to get the required number of bars for the check without trying harcoded values?
              What is the way you know of getting the right number of bars for the Bars check on any timeframe/chart bars type?
              Do reread the post

              I'm inquiering about how to get the "?" part non-hardocded:

              if(CurrentBars[0] > ?)

              In order to prevent any Indexng error.

              For any bar timeframe / Bar type.

              "?" should be the list item's bar number that comprises enough CurrentBars[0] bars
              to start calculating the values of
              double item1 = myList[myList.Count -1];
              double item2 = myList[myList.Count -2];​​

              Comment


                #8
                Hello PaulMohn,

                The ? should be replaced with the highest index you are using.

                If the highest index you are using in the code is 5, then the ? should be 5. If the highest index you are using is 600 then the ? should be 600.

                To prevent any indexing error, ensure the index you are using is less than the size of the collection the index is being used on and equal to or greater than 0.

                CurrentBar is the index of the currently processing bar of a Series<T> (not a List<T>).


                With the suggested code:
                double item1 = myList[myList.Count -1];
                double item2 = myList[myList.Count -2];​​​

                The greatest index here is myList.Count -1.
                This will always be less than the size of the collection. Because it's the size of the collection minus 1.

                But if myList.Count is 0, then this would produce a negative 1 and negative 2 which would cause an error.
                This means to call these lines of code, myList.Count() must be greater than 1.

                double item1;
                double item2;

                if (myList.Count() > 1)
                {
                item1 = myList[myList.Count() -1];
                item2 = myList[myList.Count() -2];​​​​
                }

                CurrentBar would not be involved here in anyway as there is no Series<T> being accessed.
                Chelsea B.NinjaTrader Customer Service

                Comment


                  #9
                  NinjaTrader_ChelseaB thanks,

                  How to do it without harcoding a value? What is the way to do it using the 1st compatible list item?

                  For example, with indicators requiering delays like the Swing indicator.
                  How would you get the 1st compatible Swing value bar index without harcoding it?

                  Something like:
                  if ( CurrentBars[0] > MySwing's1stValuematchingenoughbarsforCurrentbarch eckminimalbarsrequierement)
                  insead of the harcoded index:
                  if ( CurrentBars[0] > 200)

                  So that there's never any possible indexing error when changing bars resolution.
                  for example:
                  if (CurrentBars[0] > 200) // no index error for a 5min bars timeframe resolution
                  but
                  if (CurrentBars[0] > 200) // does return index error for a 10secs bars timeframe resolution
                  Which
                  if (CurrentBars[0] > 2500) // no index error for a 10secs bars timeframe resolution

                  What way to get tailored value for any bars resoution/bar type?
                  if (CurrentBars[0] > (? == tailoredValue))

                  Comment


                    #10
                    Hello PaulMohn,

                    How are you choosing the index?

                    Use that same value for the collection size check.
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      I had to test hardcoded values until I found 200 fixed the indexing error.

                      My question is again how to do it without testing harcoded values.

                      What is the way to do it without having to test for every timeframe/bar resolution/bar type until finding the fixing harcoded value?
                      Last edited by PaulMohn; 09-19-2024, 06:35 AM.

                      Comment


                        #12
                        Hello PaulMohn,

                        Save the index to a variable.

                        Ensure the variable is less than the size of the collection.

                        Use the variable for the index.
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Yes, that is the 2nd/last step to the solution to this problem.

                          But how to solve the 1st step to the problem?
                          How to get the index?
                          For for every timeframe/bar resolution/bar type?
                          Without manually probing for the right minimal index / harcoded value?
                          Last edited by PaulMohn; 09-19-2024, 07:10 AM.

                          Comment


                            #14
                            Hello PaulMohn,

                            "How to get the index?"

                            This is up to you. Why are you using an index with a List object?

                            This is your logic. There must be a reason you want an index in the first place. There must be a value you have added to the List you want some information from.

                            But I would not be able to tell you why you are wanting information saved in this list.

                            What information is being saved in the list?

                            What specific element in the list are you looking for and what index is it saved at?

                            If you are trying to loop over the collection, the for loop parameters would be from 0 to 1 less than the size of the collection.

                            "For for every timeframe/bar resolution/bar type?"

                            I don't understand why you mentioning timeframe and bars. This is a List object and not related to bars or series data.
                            Checking the index is less than the size of the List will prevent an invalid index no matter what bar type is it is not related to bar type at all.
                            This is a List<t> not a Series<T>.
                            Chelsea B.NinjaTrader Customer Service

                            Comment


                              #15
                              Code:
                              if (CrossAbove(Close[1], EMA(5)[1], 1) == true){myList.Add(CurrentBar[1]); };
                              // if like me you do not like to have too unnecessarily huge lists :
                              if (myList.Count > someIntValue) { myList.Remove(myList.First()); };​

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by MiCe1999, Today, 06:49 AM
                              0 responses
                              7 views
                              0 likes
                              Last Post MiCe1999  
                              Started by gaz0001, 12-12-2023, 09:36 AM
                              13 responses
                              282 views
                              0 likes
                              Last Post kevinenergy  
                              Started by timwey, Today, 06:01 AM
                              0 responses
                              6 views
                              0 likes
                              Last Post timwey
                              by timwey
                               
                              Started by patrickgeys7, Today, 06:01 AM
                              0 responses
                              2 views
                              0 likes
                              Last Post patrickgeys7  
                              Started by ayham12, Today, 05:42 AM
                              0 responses
                              11 views
                              0 likes
                              Last Post ayham12
                              by ayham12
                               
                              Working...
                              X