Backtesting And Simulating Execution Algos
You cannot backtest an execution algorithm the way you backtest a signal — your own order changes the very book you're trading against. Simulating execution means modelling queue position, fill probability, and impact, not just replaying historical prices.
Prerequisites: TWAP, VWAP & POV, Queue Position and Priority
Backtest a signal and the exercise is honest: the market didn't know you existed, so replaying history and checking whether you'd have made money is a fair test. Backtest an execution algorithm the same way — replay history, pretend your order got filled whenever the historical price touched your limit — and the exercise lies to you. Your order would have changed the book. It would have consumed the very liquidity you're now claiming you traded through, and other participants would have reacted to it. Simulating execution properly means simulating the market's response to you, not just checking a price against a level.
The naive backtest and why it's optimistic
Say historical data shows the best bid touched 100.00 for 4,000 shares over one minute, and you had a resting buy order for 2,000 at 100.00. The naive check says: "price touched my level, size traded there, so I filled." But you were competing for a place in that queue with everyone else who was also at 100.00, and your own order — being one more resting bid — makes the queue longer, meaning more must trade through before you get hit. If you'd been at the back of a 10,000-share queue, only the first chunk of that 4,000 traded would have filled other people, not you.
What a real simulator tracks
- Queue position. On arrival, your order is placed behind whatever historical size was already resting at that price (see Queue Position and Priority). As historical trades print at your price, your position in the queue decrements; you only fill once your position reaches zero and volume remains.
- Your own footprint. Once you're resting, you have added size to a level that historical data didn't have that size at — later cancellations or trades by others may have played out differently in a market where you weren't there. Most simulators accept this as an approximation rather than trying to fully counterfactually rewrite the book.
- Impact of aggressive slices. When your algorithm crosses the spread, it should walk the historical book and pay a price consistent with sweeping that size, then optionally apply an impact model so subsequent historical prices are shifted to reflect that your trade happened, rather than reusing prices from a world where it didn't.
Worked example: simulating one clip
An algorithm slices a 5,000-share buy order into 500-share clips, posted passively at the bid. For one clip, the historical tape shows:
| Event | Bid queue ahead of you | Volume traded at bid |
|---|---|---|
| Arrival | 1,200 shares ahead | — |
| Minute 1 | — | 900 shares trade |
| Minute 2 | — | 600 shares trade |
After minute 1, the queue ahead of you shrinks from 1,200 to 300 (all 900 traded were ahead of you, none reached you yet). In minute 2, 600 shares trade: the first 300 clear the remaining queue ahead of you, and the next 300 fill you. Your simulated fill: 300 of your 500 shares filled at the bid by the two-minute mark, average price equal to the resting bid, and the remaining 200 shares are still working. A naive backtest that just checked "did 500+ shares trade at the bid over these two minutes" would have marked you fully filled a full clip early — a fill that never actually would have happened.
A price touching your limit is necessary but not sufficient for a fill. What matters is how much volume traded at or through your price after clearing everyone who was already ahead of you in the queue.
Even a careful queue simulator still can't see what other participants would have done differently had your order actually been in the market — cancellations that never happened, orders that would have been routed elsewhere, or a price path that would have been slightly different because your liquidity was or wasn't there. Treat simulated fills as an upper bound on realism, not ground truth, and validate against live paper-trading or small-size production fills whenever the strategy matters. See also Modelling Latency In Backtests for the timing side of the same problem.
In interviews
The standard question is "what's wrong with backtesting execution the way you'd backtest a signal?" The answer to give is queue position: a signal backtest assumes you don't affect the market, and for execution algorithms — which exist specifically because size affects the market — that assumption is exactly what breaks.
Related concepts
Practice in interviews
Further reading
- Bouchaud, Bonart, Donier & Gould, Trades, Quotes and Prices (ch. 15)
- Cartea, Jaimungal & Penalva, Algorithmic and High-Frequency Trading