Simulating Stops and Trailing Stops
A backtest that fills a stop at exactly the stop price is assuming the market never gaps. On the one day a year that it does, most of a strategy's tail risk is decided by that single, silently wrong assumption.
Prerequisites: Intrabar Path Ambiguity in OHLC Bars
A stop-loss order says "sell if the price reaches this level." A backtest usually implements that as "if the bar's low is at or below the stop, fill at the stop price" — which is exactly correct only when trading is continuous through that level. Real markets aren't continuous overnight, around earnings, or during a halt. When the next print after a stop level is already through it, the fill happens at whatever price the market reopens at, not at the level you set.
Worked example: the stop that fills fifteen points below where it was drawn
A stock is held with an 8% stop below the entry, standard practice for the strategy. The company reports earnings after the close and misses badly. The stock closes at $100 before the report and opens the next session at $85 — a 15% gap, with no trades printed anywhere between $100 and $85.
| Model | Assumed fill | Realized loss |
|---|---|---|
| Naive stop simulation | Exactly at the 8% stop, $92 | −8% |
| Realistic gap-aware simulation | At the next tradeable price after the gap, $85 | −15% |
The naive backtest simply cannot represent this trade correctly — there is no way to fill at $92 when the stock never traded there. Over many trades this doesn't show up as a small, evenly distributed error; it shows up as understated tail risk concentrated in the rare, large moves that a stop is specifically meant to protect against. A strategy's backtested max drawdown and its real max drawdown can diverge sharply on exactly the handful of gap events in the sample, precisely because those are the events the stop-fill assumption handles worst.
Simulate a stop as a trigger, not a guaranteed fill price: once the trigger level is breached, fill at the next actual tradeable price, which after a gap can be materially worse than the stop level itself.
Because gap risk is rare but large, a backtest built and tuned on a sample with few gap events can look nearly identical under naive and realistic stop-fill assumptions — right up until a new gap event arrives live and the strategy takes a loss several times larger than anything in the historical max drawdown.
Stress the stop-fill assumption specifically: pull out every historical instance where the prior close was already through the stop level, refill those trades at the actual open, and compare the resulting tail of the return distribution to the naive version — the two should look meaningfully different if stops are doing real work in the strategy.
Related concepts
Practice in interviews
Further reading
- Pardo, The Evaluation and Optimization of Trading Strategies (ch. 6)