Backtesting 101: Why are my trades delayed?

Since starting this blog, I have posted quite a few articles specifically aimed at helping beginners get started. Said articles have always focused on “how to” do something on either Backtrader or Tradingview. However, tinkering around in a specific language or framework is just one part of the equation. There are also backtesting ideas, concepts, fundamentals and best practices that are equally important for the beginner to understand and apply to any language or framework. One item, in particular, has come up a few times with clients who are interested in outsourcing their development work. As such, I think the topic is a good place to start in what will hopefully be a series of posts covering backtesting topics in general.

Why are my trades delayed?

Can you help me tweak my strategy to enter trades earlier? These are two questions that could be asked for a variety of reasons but I have found that there is a common misunderstanding of how a strategy is tested. This can then lead new users to believe that there is a problem with their code. This is often not the case.

If you are reading this and had a similar question, let me start by saying there is absolutely nothing wrong with asking it. In fact, it is always good to be sceptical of the results presented to you. When you look at the charts, it is easy to understand why beginners could believe that their backtest is not running in an optimal fashion. It also touches on why indicators can often look so good “on paper” but when it comes to real-world performance we find them lacking. Let’s take a look at some simple examples that demonstrate why people might ask themselves “why are my trades delayed?”.

Example 1

The following screenshots are taken from a simple moving average crossover strategy.

Only entering on the bar after a signal

In the first screenshot, we can see that the moving averages crossover before the strategy makes a long entry. The strategy does not enter until the opening of candle following the crossover. Some people may be trying to enter the moment the crossover happens and they see this as late. However, this is to be expected for a couple of reasons.

  • The signal is not confirmed until the candle is closed. Therefore, in the real world, the absolute soonest you would be able to enter would be the opening of the following bar.
  • When backtesting on a single time-frame, we do not have the data of how price moved between the open and close of the bar. Did it hit the highs first or lows first? Did it bounce between the two multiple times? Unless we are working on multiple time-frames or replaying data for the whole day we do not have this information. Therefore, it is impossible to know exactly when a trade would be opened between the bars and a such, what price you could have entered at.

Example 2

In the second screenshot below, the moving averages crossover between the bars.

Again this is expected. The lines of the moving average are drawn from point to point. Depending on the angle of the lines, they can easily cross between the bars rather than right on them. As such, the crossover you see is not related to time. For example, if a crossover happens halfway between daily bars, it does not mean the MA’s crossed over after exactly 12 hours.

Example 3: A 2 bar delay – What is going on?

In the third screenshot, the problem appears to get worse! We are now delayed by 2 candles! This one also caused me to start debugging the first time I saw it. There must be something wrong with the script right?

trade delayed?

However, if you take a closer look, you will see that although it appears that the lines crossed over 2 bars before the entry, the indicator values show that they actually did not cross over until the following bar.

Hopefully, that will save your scalp from a bit of head scratching.

Is it possible to enter earlier?

Yes, you can set “Recalculate On Every Tick” in the properties tab of the strategy. This allows you to enter as soon as a condition is met on the tick! Note: That this only affects real-time data. I.e. Forward tests, where data is delivered tick by tick. By comparison, historical data is delivered bar by bar. In other words, one bar equals one tick for historical data. Having said all that, you should carefully consider if you want to enter on the tick in real-time. If you enter and exit trades before a candle has closed, the signal you think you are entering on has not been confirmed yet. Price could easily turn around and invalidate the signal. In addition, you are no longer trading on the same time frame. You are actually trading the price action on a lower time frame. If you want to get into trades earlier it is better to trade on a lower time frame. You can still do this while referencing values on the higher time frame for confirmation.

Recalculate on every tick
Recalculate on every tick

Conclusion

I used the word “delayed” a lot in this article and perhaps for no good reason in the end but I think it touches on the first thing that comes to mind when you see the differences in the entries on the chart. We can see that in the end, there are no delays, but rather a logical explanation to each case. Hopefully, this article can save you some debugging time and pain. If you are seeing something similar, all is good!