📈Enhancing Backtesting Accuracy with Ticks Inside Minute Bars in NinjaTrader 8

Introduction:

In this tutorial, we’ll explore a technique for creating an autostrategy that fills ticks inside a minute bar to provide more precise insights during backtesting. This approach is particularly valuable when dealing with strategies that involve level crossings, as standard backtesting tools often display these crossings on the following bar, which may not accurately reflect real trading scenarios. To illustrate, we’ll use the example of a common strategy involving the crossover of fast and slow-moving averages. Please note that this tutorial is intended for advanced NinjaScript programmers.

Step 1: Understanding Order Fill Resolution

When configuring your autostrategy, you’ll encounter the “Order Fill Resolution” parameter, offering two options: “High” and “Standard.” This parameter governs the standard behavior of filling bar details. For our purpose, we’ll focus on using “Order Fill Resolution” with the “Standard” value.

The “Standard” setting creates virtual bars with the following logic:

When the Open price of the bar is closer to the High price than the Low price:

  1. Open price to the High price.
  2. High price to the Low price.
  3. Low price to the Close price.

When the Open price of the bar is closer to the Low price than the High price:

  1. Open price to the Low price.
  2. Low price to the High price.
  3. High price to the Close price.

In simple terms, to achieve a more accurate representation of intersections, we need to:

  1. Add a second series of data with a tick type.
  2. Define entry logic based on the first data series (e.g., one-minute chart).
  3. Execute entry orders on the second data series (e.g., tick data).

Let’s proceed with scripting using these rules.

Step 2: Adding a Secondary Tick Data Series

In the OnStateChange() method, when the object reaches the State.Configure state, we add a secondary tick data series using the AddDataSeries(Data.BarsPeriodType.Tick, 1) method. Ensure that the calculation mode is set to Calculate.OnEachTick to run the OnBarUpdate() method and associated logic with each new tick.

Important: Before implementing this method, ensure you have tick data available for the instrument you intend to test.

protected override void OnStateChange()
{
   if(State = State.SetDefaults)
    {
      Fast = 10;
      Slow = 25;
      Calculate = Calculate.OnEachTick;
      Name =  "Sample Intrabar Becktest";
    }
   else  if (State == State.Configure)
    {
        // Add a 1 tick Bars object: BarsInProgress index = 1
        AddDataSeries(BarsPeriodType.Tick, 1);
    }
}

Step 3: Defining Entry Logic and Order Execution

In the OnBarUpdate method, we define entry logic and execute orders. It’s crucial to understand the sequential order in which the OnBarUpdate() method is triggered—primary bars execute before secondary bars.

if (BarsInProgress == 0)
{
    // Entry logic on the primary bar series
}
else if (BarsInProgress == 1)
{
    // Order execution on the secondary bar series
    EnterLong(barsInProgressIndex: 1, quantity: yourQuantity, signalName: yourSignalName);
}

For instance, if a bar is timestamped as 12:00 PM on the 5-minute bar series, the call order between equally timestamped 12:00 PM bars on the 1-minute bar series proceeds as follows:

  1. 12:00 PM 5-minute
  2. 12:00 PM 1-minute
  3. 12:01 PM 1-minute
  4. 12:02 PM 1-minute
  5. 12:03 PM 1-minute
  6. 12:04 PM 1-minute
  7. 12:05 PM 5-minute
  8. 12:05 PM 1-minute

The entry condition is triggered on the primary bar series, but the order is sent and filled on the secondary bar series. To specify the bar series, we use the parameter barsInProgressIndex, where 0 represents primary bars and 1 represents secondary bars.

For example:

By using barsInProgressIndex set to 1, we send an order for the second data series, enabling us to achieve the desired backtesting results.

Important Note: Always ensure that you have historical tick data available for the instrument you intend to backtest.

Conclusion:

By following this tutorial, you can create an autostrategy that fills ticks inside minute bars, providing more accurate backtesting results, especially for strategies involving level crossings. This advanced technique empowers you to fine-tune your strategies and make informed trading decisions.

For further assistance or clarifications, feel free to reach out in the comments section. Happy programming and trading!