Slippage and Transaction Costs: The Silent Killer of Backtests
A strategy that's profitable on paper often dies the moment you add realistic trading costs. Here's what slippage, spread, and fees actually do to returns, and how to model them honestly.
Here’s a pattern that has humbled every developer who builds a trading strategy: the backtest shows a smooth, rising equity curve, you deploy it, and the live results are mediocre or negative. The strategy didn’t break — your backtest was lying, because it assumed you could trade at the price on the screen, instantly, for free. None of those things are true, and the gap between them and reality is where backtested edges go to die. None of this is investment advice.
The three costs your backtest probably ignores
Real trading has three frictions that a naive backtest leaves out, and they compound.
The spread. Every tradable asset has a bid and an ask, and you buy at the higher ask and sell at the lower bid. The difference is a cost you pay on every round trip, before the price moves at all. On liquid large-cap stocks it’s tiny; on small-caps, options, or thin crypto pairs it can be substantial.
Slippage. Your order isn’t free to the market — placing it moves the price against you, especially if your size is large relative to available liquidity. You also rarely fill at the exact moment your signal fired; by the time your order reaches the exchange, the price has drifted. Backtests that fill at the closing price of the signal bar are quietly assuming away this entire problem.
Commissions and fees. Even “commission-free” brokers have costs baked in elsewhere, and many assets carry explicit fees. These are the easiest to model and the smallest of the three for most strategies — but they still add up with frequency.
Why turnover is the multiplier that matters
Transaction costs aren’t a fixed tax — they scale with how often you trade. A strategy that rebalances once a month pays these costs twelve times a year; one that trades several times a day pays them hundreds or thousands of times. So the same per-trade cost that’s negligible for a low-turnover strategy is fatal for a high-frequency one.
This is why so many high-turnover strategies look brilliant gross and lose money net. Their edge per trade is real but tiny, and costs eat all of it. Before you get excited about a strategy with a high trade count, ask: what’s the average profit per trade, and is it comfortably larger than the round-trip cost? If a strategy makes 0.1% per trade but costs 0.15% to execute, no amount of win-rate saves it.
Modeling costs honestly
You don’t need a perfect market simulator; you need to stop assuming costs are zero. A reasonable approach for retail backtesting:
Fill at the next bar’s open rather than the signal bar’s close, so you’re not trading on information you couldn’t have acted on. Subtract a per-trade cost that combines an estimate of the spread plus slippage for your asset and typical order size — be pessimistic, because optimism here is expensive. Add explicit commissions where they apply. Then re-run, and judge the strategy on the net curve, never the gross one.
The goal isn’t precision; it’s to stop fooling yourself. A strategy that survives conservative cost assumptions might be real. A strategy that only works at zero cost was never a strategy — it was a measurement of the market’s frictions, mistaken for an edge.
FAQ
How much should I assume for slippage?+
Do commission-free brokers eliminate transaction costs?+
Why does filling at the next open matter so much?+
Slippage and transaction costs are unglamorous, which is exactly why they’re so often ignored — and why ignoring them ruins so many strategies. Model them conservatively from the start, and you’ll waste far less time chasing edges that only ever existed in a frictionless simulation.
Related reading
2026-06-10
Building a Market-Data Pipeline: Caching, Rate Limits, and Gaps
Reliable backtests need reliable data, and pulling it live from an API on every run is slow, fragile, and costly. Here's how to build a local market-data pipeline that caches, respects rate limits, and handles gaps.
2026-06-10
Order Types Explained for Retail Algorithmic Traders
Market, limit, stop, and the time-in-force flags behind them decide whether your strategy fills where you expect. Here's what each order type actually does, and when the wrong one quietly costs you money.
2026-06-10
Pairs Trading and Cointegration: A Developer's Introduction
Pairs trading bets that two related securities will revert to their usual relationship. Here's what cointegration actually means, why it's not the same as correlation, and how to think about building a pairs strategy.
2026-06-10
Portfolio Optimization with PyPortfolioOpt: Mean-Variance in Practice
PyPortfolioOpt makes Markowitz mean-variance optimization a few lines of Python. Here's what it does, why naive optimization produces fragile portfolios, and the techniques that make the output usable.
2026-06-10
Time-Series Cross-Validation: Why Standard K-Fold Ruins Trading Models
Standard k-fold cross-validation shuffles data and leaks the future into the past — fatal for trading models. Here's why time order matters, and how walk-forward and purged validation fix it.
Get the best tools, weekly
One email every Friday. No spam, unsubscribe anytime.