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

Using MAX() for backtesting isn't returning what I expect.

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

    Using MAX() for backtesting isn't returning what I expect.

    Hello,

    I'm having an issue with MAX().

    What I'm trying to do is get the MAX high price over the last 30 days in a back testing scenario.

    I want to see if the price during any given point in a backtesting strategy is less than 10% of the prior 30 days high to determine good entry points to go Long. (Not looking for Month bars... I want the literal last 30 Days high, so it's always a running 30 day High)

    Code:
    protected override void OnBarUpdate()       
    {                                                   
        highPeriod = MAX(30)[0];         
        Print(Instrument.FullName + ": " + "HighPeriod Var is: $" + highPeriod);
    }
    I would assume this should grab the last 30 days of data and return the high price over that period, but when I run it... it only uses the dates I've selected to return a value. It doesn't look back past the start date of the strategy, which seems wrong to me.

    If I backtest it on one day's data, I get nothing. If I backtest on 2 day's data, I get the high from the first day.

    I trying to start a strategy on any day I choose, assuming it can look back at data 30 days prior.

    Any ideas how to make this happen?

    Do I have to start the backtest 30 days prior and then ignore the values for 30 days in order to start my strategy? If that's the case, I don't know how to make that work in a real-time scenario.

    Thank you,
    Jeff

    #2
    Hello Jeff, thanks for your post.

    When you call MAX(Period), and the indicator has not processed "Period" bars yet, the CurrentBar will be used. So when CurrentBar = 1, it will calculate MAX(1)[0]. To ensure you are getting the 30 day maximum, add a Period check at the top of OnBarUpdate:

    if(CurrentBar < 30) return;

    Print("30 Day Max " + MAX(30)[0]);

    Make sure you load an extra 30 days prior to the date you want the strategy to start trading.

    Please let me know if I can assist any furher.
    Chris L.NinjaTrader Customer Service

    Comment


      #3
      Awesome Chris, this is the part I was missing! That points me in the right direction for sure.

      Thank you!

      --

      As a follwoup question, how can I take it a little further...

      What I'm ultimately trying to do is use 1 Day bars to get the 30 days of history to get the Max High. This could be my seconary Data Series.

      My primary Data Series would be on a 5 minute bar.

      So, how would I go about doing the following:
      • check for the high of the past 30 days (this would be done by loading the extra 30 days historically to calculate the initial value)
      • hold off backtesting until the initial 30 days have been processed.

      Thanks again
      -Jeff

      Comment


        #4
        I think I figured it out... here's what I have so far:

        Code:
        if (BarsInProgress == 1) {                    
          // get the initial 30 days historical
        
          // Disregard processing until we can look back 30 days                    
          if (CurrentBars[1] < 30)                        
            return;                                          
        
          highPeriod = MAX(Highs[1], 30)[0];                    
          Print(Instrument.FullName + ": " + "HighPeriod Var is: $" + highPeriod);                                          
        
          dataIsLoaded = true;                
        }                                                  
        
        if (dataIsLoaded && BarsInProgress == 0){
          // The rest of the code for the 5 min bars

        Comment


          #5
          Hello Jeff, thanks for the follow up.

          The code you posted looks like it will work. Please test in the strategy analyzer to confirm.

          Best regards.

          Chris L.NinjaTrader Customer Service

          Comment


            #6
            Another question for you Chris regarding the historical data.

            When I make a strategy active... how do I figure for 30 days of data everytime... I'm struggling with tihs because I use Interactive Brokers and I constantly have to re-enable my strategies everyday because they force a connection reset which disconnects all my strategies (I usually have 5-15 active on average), so I have to manually figure out how many days to load so they are in sync again.

            So, everytime I renable them I'm guessing I'll have to manually add in the 30 previous trading days so it ends prior to the start of the current trading day.

            Is there no way to add the 30 days of historical data via program without having to load it in the "Days to Load" section?

            I just think of what I would do in Python, I would look up the 30 Day High price (from anywhere like Yahoo... super easy) and I could start the strategy because that's the 1 price I need.

            This hasn't gotten so complex, is there any easier way to do get the 1 price I need (the 30 Day High) than all of the above?

            I know I'm rambling... any input is appreciated.

            Thanks again,
            Jeff

            Comment


              #7
              Hello Jeff, thanks for your reply.

              For the Interactive Brokers disconnect, there are settings under Tools>Options>Strategies>On Connection Loss where you can set a time window for NinjaTrader to wait to keep running strategies when a disconnect happens. This can be set to wait a long enough time for the reconnection then keep the strategy running as if it never disconnected:

              https://ninjatrader.com/support/help...riptProperties

              You can set a default template for the data series menu in the bottom left. Name the template "Default" so that it loads for every new chart created. If the daily chart loads up 365 days of data (e.g. from 22 Feb 2020 till today) then accessing MAX(30) on today's bar will consistently give the highest price 30 days prior to today, so I'm not sure if I see where the issue is coming from. The only way I see this being an issue is if the very first position taken by the strategy in the historical data has something to do with the next trade the strategy is going to take in real time data.

              If you do need to programmatically control the number of bars/days loaded, you may add a 1 day series to the script using this special overload and use this series to calculate MAX:
              Code:
              AddDataSeries(string instrumentName, BarsPeriod barsPeriod, int barsToLoad, string tradingHoursName, bool? isResetOnNewTradingDay)
              Please let me know if I can assist any further.
              Chris L.NinjaTrader Customer Service

              Comment


                #8
                Hi Chris,

                Just as a side note, I was able to get the last "AddDataSeries" working, but the MAX still doesn't do what I would expect. I still have to manually force it to process the 30 days of historical data.

                Again, what I'm trying to do, is as soon as I make this strategy active. I want it to look through the last 30 daily highs to see what the highest high was. Then use that to determine entry points. Here's what I used to make that work

                In State == State.Configure, I am loading 30 days of 1 Day Bars as a separate series:

                Code:
                AddDataSeries(Instrument.FullName, new BarsPeriod{BarsPeriodType = BarsPeriodType.Day, Value = 1}, 30, "US Equities RTH", true);

                Then in OnBarUpdate, I use a loop to get it to process the 30 days of 1 Day bars...
                Code:
                if (Bars.IsFirstBarOfSession && IsFirstTickOfBar)                 
                {                     
                 // Look through the last 30 Day Bar Highs
                 for (int i=0; i<=30; i++)                     
                 {                         
                  highPeriod = MAX(Highs[1], 30)[0];                     
                 }                                          
                 // Print 30 Day Max                                          
                 Print(Instrument.FullName + ": " + "HighPeriod Var is: $" + highPeriod);                     
                
                }
                If I don't do this, it takes the first 30 5 minute bars (on my primary instrument) to actually get the accurate MAX calc. Again, it's not how I would expect it to operate from any of the guides out there, but I finally was able to get it working for my needs and wanted to get it posted here for anyone else.

                -Jeff

                Comment

                Latest Posts

                Collapse

                Topics Statistics Last Post
                Started by trilliantrader, 04-18-2024, 08:16 AM
                4 responses
                18 views
                0 likes
                Last Post trilliantrader  
                Started by mgco4you, Today, 09:46 PM
                1 response
                7 views
                0 likes
                Last Post NinjaTrader_Manfred  
                Started by wzgy0920, Today, 09:53 PM
                0 responses
                9 views
                0 likes
                Last Post wzgy0920  
                Started by Rapine Heihei, Today, 08:19 PM
                1 response
                10 views
                0 likes
                Last Post NinjaTrader_Manfred  
                Started by Rapine Heihei, Today, 08:25 PM
                0 responses
                10 views
                0 likes
                Last Post Rapine Heihei  
                Working...
                X