Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Backtest a strategy that buys either on open or close

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

    Backtest a strategy that buys either on open or close

    Hello,

    This question has been asked a long time ago but because NinjaTrader has come a long way I wanted to bring it up again to see if it is possible to do this now. I'm trying to backtest a system that does the following:
    • Using Daily price series as primary series
    • If SMA has been rising for the last 3 bars
    • AND if the Close price has been falling for the last 3 bars
    • AND If the Open of the next bar is lower, buy at that price. Otherwise, if the open is higher, wait to buy the lower Close. If neither is lower, don't buy at all.
    The conditions are easy to check for, but the difficult part seems to be the whole issue with The bar has already been calculated using historical data, so you can't take action on the open or close of the current bar since the bar is already finished. However, there are many situation in which a strategy calls for this, and I've seen some suggestions just not to backtest it and just forward test, but that's definitely not a good idea for many reasons.

    I had one idea that I tested but am not having luck with it. My idea was based on the SampleIntraBarBacktest.cs found in the NinjatTrader 8 Guide. It states in the comments in the code:

    Code:
    When working with multiple bar series objects it is important to understand the sequential order in which the OnBarUpdate() method is triggered.
    The bars will always run with the primary first followed by the secondary and so on.
    
    Important: Primary bars will always execute before the secondary bar series.
    If a bar is timestamped as 12:00PM on the 5min bar series, the call order between the equally timestamped 12:00PM bar on the 1min bar series is like this:
    12:00PM 5min
    12:00PM 1min
    12:01PM 1min
    12:02PM 1min
    12:03PM 1min
    12:04PM 1min
    12:05PM 5min
    12:05PM 1min
    My idea was that if OnBarUpdate is called on the secondary data series after the primary series, then why couldn't I take my Daily price data and call
    Code:
    AddDataSeries(Data.BarsPeriodType.Day, 1);
    to simply add a duplicate secondary data series and just call EnterLongLimit at the Open of the primary series before the secondary series is calculated and pass the barsInProgress as 1 to the EnterLongLimit call. I thought that would then execute on the secondary series since it was called after the primary series, but it doesn't seem to be working.

    I'd hate to have to resort to writing the buy/sell values to a csv and import into Excel just to get accurate backtesting data for this type of system.

    Thank you!
    Paul

    #2
    Hello pdennis,

    The intrabar sample would be the closest to simulating that in a backtest, that would let you use a more granular series to place entries during a larger bar like a daily series however that is not really the same as what you are asking to do. For what you are asking or to take action on the open of a bar you would need to use the playback connection or a realtime mode. You can find the open price of the bar and place an order at that time but you would need to use IsFirstTickOfBar to know that it is the beginning of the bar. You can otherwise use OnBarClose processing in historical data to submit orders based on the close of bars.

    Comment


      #3
      I was worried you would say that I understand those things already but ultimately they are trying to work around the solution rather than solve it in my opinion. You can easily use Calculate.OnEachTick and check the time of day and enter a position near the close, or check if it is the first tick of the bar as you mentioned and enter a position on the open etc, but the real topic at hand here is not real time, it is backtesting these types of systems to understand the profile of the system before trading in real time. This is such a vital step that I feel strongly that it deserves its own behavior in the code.

      What I mean is that because of the fact we can code a real time strategy to do pretty much anything intrabar that we want, we should be able to do things in backtesting that wouldn't apply in real time in order to simulate the real time behavior. An example is that if I'm backtesting, I should be able to do these things:
      Code:
      if (Open[0] > Close[1]) EnterLongThisBarOnOpen();
      else if (Close[0] > Close[1]) EnterLongThisBarOnClose();
      These two methods are obviously made up, but the names explain what I mean, where it would allow you to use historical data but enter positions based on the Open or Close of the bar that was just calculated during the backtest. These two methods make no sense when trading a system in real time, but they make perfect sense when related to a backtest, since you could easily take those actions in realtime and therefore it is a realistic backtest.

      The main problem with using intrabar granularity is the access to enough data. Generally there is Daily data going back 15 years or so, but if you start using Hourly data for intrabar granularity you have to severely limit that time period to something like 2 years I think? Plus, even if I use Hourly or even Minute data as a secondary series to a Daily bar series, I still couldn't use it to buy on the current bar's open or close since the primary series is calculated first, therefore the Minute data that comes next in OnBarUpdate will be too late to actually execute on that session.

      I really hope the NinjaTrader developers seriously consider adding this. I feel like any serious system developer would agree being able to accurately backtest a system is crucial. I'm not sure if it would lead to anything, but please let me know if you can add a feature request for this or if there's a way to vote on an existing one.

      Thanks!
      Paul

      Comment


        #4
        Hello pdennis,

        Testing in historical and testing in realtime are not the same in that regard, there is no ability to use intrabar granularity for historical fills because the platform does not process historical data in that way. When using historical data you only have 1 data point which is the OHLCV of that bar, nothing more can be done intrabar as the data does not exist in that scenario.

        The fill resolution setting of the backtest adds a secondary series for more granular fills, the same way that the sample strategy shows for adding secondary fill granularity. That would be the extent that a historical backtest can accomplish for intrabar granularity, other properties like IsFirstTickOfBar can't work because there is only 1 datapoint per bar which means it will always be true.

        OnEachTick logic is not intended to work historically at all, NinjaTrader has implemented ways to historically test using intrabar granularity which is the playback connection, that allows the script to work as it would in realtime over past days. You will also run into this problem with more complex bars types like renko which require realtime data to work correctly, the backtest has limitations based on using historical data so some items will inherently not work 1:1 in that scenario.


        Comment

        Latest Posts

        Collapse

        Topics Statistics Last Post
        Started by NullPointStrategies, Yesterday, 05:17 AM
        0 responses
        62 views
        0 likes
        Last Post NullPointStrategies  
        Started by argusthome, 03-08-2026, 10:06 AM
        0 responses
        134 views
        0 likes
        Last Post argusthome  
        Started by NabilKhattabi, 03-06-2026, 11:18 AM
        0 responses
        75 views
        0 likes
        Last Post NabilKhattabi  
        Started by Deep42, 03-06-2026, 12:28 AM
        0 responses
        45 views
        0 likes
        Last Post Deep42
        by Deep42
         
        Started by TheRealMorford, 03-05-2026, 06:15 PM
        0 responses
        50 views
        0 likes
        Last Post TheRealMorford  
        Working...
        X