A newer, extended version of this post can be found on my new blog.
For back-testing, the typical approach is to use daily closing prices both for the signal and for the entry point. Implementing such a system in practice however is not straightforward. The most obvious problem is that the close remains unknown until the end of the day, thus, we don’t know what our action needs to be before the very end of the trading day.
The way I approach this problem usually is by computing the actions for all possible scenarios. Sometimes that’s easy. For example in this earlier article I have shown how to pre-compute the EMA which would trigger a change in the position. Although it looks great in theory there are two problems with this approach:
It works mostly for simple models (consider reversing the stochastic indicator)
The implementation would require different code (from what we have already written for the back testing), so bugs are likely
Even if the second bullet doesn’t apply to you (I keep hearing there are some bright individuals who write error free code), one still has to deal with the first, so bear with me. We need an alternative.
The simplest solution is to use brute force. It all depends on the strategy, but in general the idea is to first generate the set of possible outcomes (for example all possible closing prices for the next day), then to attach each possible outcome to the end of the series, then run the engine generating the signals (from the back testing code base) on each of these possible series and keep the results.
Let’s consider for example contrarian trading of SPY (S&P 500) using RSI(2). It is unlikely that the SPY will move more than 5% either way on any single day. Thus, using the last day close we can generate all closing prices (rounding to a penny) for the next day within 5% of the today’s price. For each of these prices we compute RSI(2) and the corresponding position.
Finally we need to execute the indicated trade. Either use a broker who allows limit order at the close, like Interactive Brokers. Or, pick a random time between 3:30 and 4:00 on the next day, connect at that time, look at the price and manually execute the pre-determined action for this price.
The added benefit of this approach is that it does not require much new code – the new code is to generate the list of possible outcomes, for the rest we execute the same code we used in the back testing.
How realistic is this in real life? Works quite well IMO. For instruments which are traded very actively, it should be random whether a few points are made or lost compared to the back tested on-close trading. For instruments that are not traded too actively, putting a limit order a penny above the “last price” typically does not result in a slippage of more than 2 pennies, which can easily be factored into the model. Of course, it misses some trades (think wide spreads). In all these discussions, I am mostly concerned of highly liquid ETFs – certainly one cannot use this strategy for penny stocks. If intra-day data is available, the slippage can even be modeled nicely using historic intra-day data.