Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Using BarsArray to get data from a difference data series.

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

    #16
    Originally posted by NinjaTrader_ChelseaB View Post
    Hello ChrisR,

    Print out the elements in the list. Is this what you expect?

    I think you should be clearing the list before you loop again and add all new elements.

    However, the way you design your custom logic is up to you.
    Consider the following code.
    Code:
    protected override void OnBarUpdate()
    {
       if (Time[0].Hour == 15)
       {
          MyList.Add(High[0]);
          if (MyList.Count > 0) Print(MyList.Average());
       }
    }
    ^^On NQ, on a 60min chart with 90 days loaded, the above prints 21683.07.

    My goal is to replicate this value, which is mathematically accurate at the base calculation of average high.

    The previous mentioned code is not allowing me to match this value, and I am unsure as to why. It returns 21261.75 when ran on the same days loaded with a 1min interval chart. I have racked my brain around this and can not figure out why it is not matching the normal 60 minute chart. Is there some kind of data nuance I need to be familiar with when using lists or loops?

    Comment


      #17
      Hello ChrisR,

      This code does not check for BarsInProgress. This would be adding the highs of the 1 minute bars (BarsArray[0]) and the 60 minute bars (BarsArray[1]) together.

      Further, this is not being compared to any other bar. You are only checking that the hour is 15.

      This not a loop..

      You are wanting to compare the current bar hour to previous bars hours correct? You would have to wait until the current bar, then loop through the previous bars to do that comparison.
      Chelsea B.NinjaTrader Customer Service

      Comment


        #18
        Originally posted by NinjaTrader_ChelseaB View Post
        Hello ChrisR,

        This code does not check for BarsInProgress. This would be adding the highs of the 1 minute bars (BarsArray[0]) and the 60 minute bars (BarsArray[1]) together.

        Further, this is not being compared to any other bar. You are only checking that the hour is 15.

        This not a loop..

        You are wanting to compare the current bar hour to previous bars hours correct? You would have to wait until the current bar, then loop through the previous bars to do that comparison.

        The code in post #16 as stated in the post, is simply showing a basic list logic which is applied to the 60min chart to get the high averages of the current hour candles, which at that time was 3pm hour. This was to give me a base value to attempt to match with the code in question. Post #16 is not the code in question, as stated. The code in question, derived from the feedback I received from you, is as follows from post #12. Can you provide specific recommendations on the code below to get it to perform the desired outcome? The desired outcome is to give me the average hourly high derived from only the hours that match the current hour, relative to the data loaded on the chart. I'm not sure if I am just not explaining this properly, if there is a communication breakdown somewhere, or if there is some other problem. I do not know how to ask this any differently than I already have.....

        My Question:
        If I am on a 1 minute chart, and lets just say its the 1pm hour (any time between 1:01 and 2:00). How do I collect a list of all the historical 1pm hour candles (which would have a 60min bar time of 2pm) and get the average high? I am attempting to do this via the code below, which is returning the wrong value. I know it is the wrong value because I am comparing it against the printed value derived from the code in post #16 which is applied to a 60min chart. Do you have recommendations on the code below?

        Code:
        if (CurrentBars[0] > 0 && CurrentBars[1] > 0)
        {
           if (Times[0][0].Minute == 00) HiValue.Clear(); //Resets list at new hour
        
           int lookBackPeriod = 5000;
        
           for (int index = 1; index < Math.Min(lookBackPeriod, CurrentBars[1]); index++)
           {
              if (Times[1][index].Hour == Times[0][0].Hour)
              {
                 HiValue.Add(Highs[1][0]);
        
                 if (HiValue.Count > 0) Print(Math.Abs(HiValue.Average()));
              }
           }
        }
        Last edited by ChrisR; 02-26-2025, 02:36 PM.

        Comment


          #19
          For efficiency, you need to reimagine this, so that instead of indexing back you simply keep track of it as you go. It sounds like you're trying to make an average volume for each hour of the day, which is a type of common technical analysis idea (see for instance https://traderfeed.blogspot.com/2009...olatility.html).

          There are two ways to do this - you can use the primary data series, and make sure it's at least granular enough to do what you're trying to measure - for instance, if you're averaging every 30 minute period's volume over the past 10 trading days, you can use 30 minute bars or any factor of 30 such as 1 minute bars, 2 minute bars, 3 minute bars, 5 minute bars, 10 minute bars, or 15 minute bars. The important thing is that some combination of the bars make 30 minutes without splitting across a 30-minute period. Then, either you'll run it as Calculate.OnBarClose or if you're running intrabar calculations, you'll have to assess if you have a newly completed bar and look back 1 to get the completed bar (in realtime, at least). You'll then figure out which bar of the day it is - a common way to do that is to determine how many minutes you are past the session start and divide by 30 (or whatever size buckets you are aggregating). Assign the volume for the bar to the right bucket for the day. When the session changes, push the day's buckets into a list or collection or ring buffer of the past 10 sessions, such that if we're on the 3rd 30-minute period of the day, you can simply look in the collection to get the 3rd bucket of each of the past 10 days and average those 10 numbers.

          The other way to do this would be to ignore the chart series and add what you need e.g. a 30-minute bar, or a 1-minute bar as a second data series. Then, do the same thing as above, but only do your calculations if BarsInProgress == 1.

          That's a quick overview of how the calculation is done. I wouldn't go indexing back 5000 bars or that sort of thing trying to calculate it all in hindsight. First, you'll probably make some logic mistakes trying to do that perfectly, but perhaps more importantly, that will be super slow compared to doing it as you go. So, re-think this as an "as you go" calculation, and you'll be well on your way.
          Bruce DeVault
          QuantKey Trading Vendor Services
          NinjaTrader Ecosystem Vendor - QuantKey

          Comment


            #20
            Originally posted by QuantKey_Bruce View Post
            For efficiency, you need to reimagine this, so that instead of indexing back you simply keep track of it as you go. It sounds like you're trying to make an average volume for each hour of the day, which is a type of common technical analysis idea (see for instance https://traderfeed.blogspot.com/2009...olatility.html).

            There are two ways to do this - you can use the primary data series, and make sure it's at least granular enough to do what you're trying to measure - for instance, if you're averaging every 30 minute period's volume over the past 10 trading days, you can use 30 minute bars or any factor of 30 such as 1 minute bars, 2 minute bars, 3 minute bars, 5 minute bars, 10 minute bars, or 15 minute bars. The important thing is that some combination of the bars make 30 minutes without splitting across a 30-minute period. Then, either you'll run it as Calculate.OnBarClose or if you're running intrabar calculations, you'll have to assess if you have a newly completed bar and look back 1 to get the completed bar (in realtime, at least). You'll then figure out which bar of the day it is - a common way to do that is to determine how many minutes you are past the session start and divide by 30 (or whatever size buckets you are aggregating). Assign the volume for the bar to the right bucket for the day. When the session changes, push the day's buckets into a list or collection or ring buffer of the past 10 sessions, such that if we're on the 3rd 30-minute period of the day, you can simply look in the collection to get the 3rd bucket of each of the past 10 days and average those 10 numbers.

            The other way to do this would be to ignore the chart series and add what you need e.g. a 30-minute bar, or a 1-minute bar as a second data series. Then, do the same thing as above, but only do your calculations if BarsInProgress == 1.

            That's a quick overview of how the calculation is done. I wouldn't go indexing back 5000 bars or that sort of thing trying to calculate it all in hindsight. First, you'll probably make some logic mistakes trying to do that perfectly, but perhaps more importantly, that will be super slow compared to doing it as you go. So, re-think this as an "as you go" calculation, and you'll be well on your way.
            Thanks that makes sense. I will look to rebuild this later tonight from a back to front flow. I am already indexing back with daily and weekly added data series, but those are more simplistic as they do not require looping through a specific time occurrence.

            Comment


              #21

              Hello ChrisR,

              I think the loop would work. You would need to reset the list before running the loop.

              Attached is a test script with the code you suggested modified and the output saved to a text file.
              ChrisRPreviousHourTest_NT8.zip
              NinjaScript Output 2_27_2025 6_52 AM.txt

              Notice how I am using prints to verify the behavior.


              It may be more efficient to use a while loop that subtracts 1 day and checks if the hour is the same as the last updated bar.

              Or you could make a list for every hour of the day, and when a bar updates add the corresponding list.
              Attached Files
              Chelsea B.NinjaTrader Customer Service

              Comment


                #22
                Originally posted by NinjaTrader_ChelseaB View Post
                Hello ChrisR,

                I think the loop would work. You would need to reset the list before running the loop.

                Attached is a test script with the code you suggested modified and the output saved to a text file.
                ChrisRPreviousHourTest_NT8.zip
                NinjaScript Output 2_27_2025 6_52 AM.txt

                Notice how I am using prints to verify the behavior.


                It may be more efficient to use a while loop that subtracts 1 day and checks if the hour is the same as the last updated bar.

                Or you could make a list for every hour of the day, and when a bar updates add the corresponding list.
                After digging into this more and debugging some stuff I was able to get it working 100% late last night. I verified it is returning the correct value by going to a 60 minute chart and grabbing the highs for that specific hour, than calculating the average. That value matches via the below code every time the hour changes. Here is the code for anyone else trying to do something similar. This will collect within the HiAvg variable, the average high hourly high for the current hour, across the data loaded on the chart for every hour that matches the current hour.

                Code:
                private double HiAvg;
                private int latestHour, currentHour = -1;​
                private List<double> HiValue = new List<double>();
                Code:
                if (BarsInProgress == 1)
                {
                   if (CurrentBars[1] < 1)
                   return;
                
                   int latestHour = Times[1][0].Hour;
                
                   if (latestHour != currentHour)
                   {
                      currentHour = latestHour;
                      HiValue.Clear();
                   }
                
                   for (int barsAgo = 0; barsAgo < CurrentBars[1]; barsAgo++)
                   {
                      if (barsAgo >= Times[1].Count || barsAgo >= Opens[1].Count || barsAgo >= Highs[1].Count || barsAgo >= Closes[1].Count)
                      break;
                
                      if (Times[1][barsAgo].Hour == currentHour+1)
                      {
                         HiValue.Add((Highs[1][barsAgo]);
                         HiAvg = UpHiValue.Average();
                      }
                   }
                }
                Last edited by ChrisR; 02-27-2025, 10:44 AM.

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                0 responses
                558 views
                0 likes
                Last Post Geovanny Suaza  
                Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                0 responses
                324 views
                1 like
                Last Post Geovanny Suaza  
                Started by Mindset, 02-09-2026, 11:44 AM
                0 responses
                101 views
                0 likes
                Last Post Mindset
                by Mindset
                 
                Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                0 responses
                545 views
                1 like
                Last Post Geovanny Suaza  
                Started by RFrosty, 01-28-2026, 06:49 PM
                0 responses
                547 views
                1 like
                Last Post RFrosty
                by RFrosty
                 
                Working...
                X