Market structure · JUL 18, 2026 · 4 MIN READ
Slippage: the tax nobody models
Spreads, market impact, and fill fantasies: how trading costs quietly eat simulated edges, and why so many paper strategies die on contact with a real order book.
Every strategy exists twice. There’s the version in the backtest, which trades against a file of historical prices that never argues back. And there’s the version at the broker, which trades against people and machines who have money at stake and no obligation to hand you the price on your screen. The difference between the two shows up in a lot of costumes, but the family name is usually slippage: the accumulated cost of spreads, market impact, and optimistic fill assumptions.
It behaves like a tax. You can’t opt out of it. You can only model it honestly or get surprised by it.
The spread: a toll booth on every trade
A real market quotes two prices at once. Say a market is quoted 100.00 bid, 100.05 offered. Those are made-up numbers, purely for illustration. If you want to buy right now, you pay 100.05. If you want to sell right now, you receive 100.00. Buy and then sell without the market moving at all, and you’re down the spread. Nothing happened, and it still cost you.
Backtests routinely trade at the last price or the midpoint, which assumes you cross that toll booth for free. Per trade, the toll looks tiny. But it’s charged per trade, so the meter runs with your trade count. A strategy that trades constantly pays the toll constantly, and simulations that skip it are quietly pocketing money no real account would ever see.
Market impact: you are also the news
The prices in your data file are records of trades that happened without you. Add your order to that market and you change it. A small order in a liquid market slips in unnoticed. A larger one eats through the best price, then the next-best, and finishes at a worse average than the screen promised. And your buying is itself information: other participants see demand and adjust.
The uncomfortable rule is that impact grows with your size relative to the market’s liquidity. A backtest can’t feel this, because historical prices don’t move when a simulation trades into them. That assumption is roughly true for small orders in deep markets and gets more fictional as size grows, which is one reason results that hold at small scale can degrade as an account does the thing everyone wants accounts to do.
Fill fantasies: the polite lies about limit orders
Cost modeling gets subtlest around fills. A common backtest assumption: if the market touched your limit price, you were filled. In reality there was a queue at that price, and you were at the back of it. Touched does not mean filled.
Worse, the fills you do get are biased against you. When price barely kisses your limit and bounces, you often miss the fill and miss the profit. When price slices straight through your level, you’re filled every time, and disproportionately in exactly the trades where the market kept going against you. Execution researchers call it adverse selection. A backtest that awards a fill on every touch collects the good fills it wouldn’t have gotten and none of the pain.
Stops have a mirror-image fantasy: the simulation exits at the stop price, while real markets gap and fast markets fill worse than the level you asked for.
Why fast strategies suffer most
Here’s the arithmetic that kills paper edges, with invented numbers, as a pure illustration: imagine a system whose simulated gain averages one tick per trade, in a market where crossing the spread costs one tick. With free trading assumed, it looks like a machine. Charge the toll, and the machine’s entire output was the toll. Before commissions.
That’s the general rule. The thinner the edge per trade and the higher the trade count, the larger the share of simulated profit that is really an unpaid tax bill. High-frequency ideas don’t get killed by being wrong about markets. They get killed by being right about markets and wrong about costs.
What honest cost modeling looks like
- Charge the full toll. Simulated trades cross the spread unless there’s a specific, defensible reason to assume better.
- Penalize size. Fills degrade as order size grows relative to liquidity, and the model should say how.
- Be a pessimist about fills. Limits fill when price trades through, not when it touches. Stops fill worse than the stop.
- Stress it. Re-run the test at double and triple the assumed costs. An idea that dies at double costs was never robust, just an arithmetic coincidence.
- Reconcile against reality. Real fills, from real trading, get compared with what the model assumed, and the differences feed back into the model.
That last step is where we have skin in the game: we trade our own capital, so our fills grade our own assumptions. When we publish a backtest, the cost assumptions ship with it, alongside the required hypothetical-performance disclaimer, because a simulation is only as honest as its least honest assumption. The tax nobody models is the one we’d rather model in public.