August 16, 2026 · Backtesting

Why most backtests lie, and the four line items that fix them

Why most backtests lie, and the four line items that fix them

Open with the numbers, because they're the whole argument. A round-trip taker trade on a major perp venue costs about 0.10% of notional in commissions. Funding on a crowded long can run 10-30% annualized against you. A market order that's large relative to top-of-book depth pays square-root-law impact on top of the spread. And a backtest that reads today's revision of yesterday's data gets an edge worth several percent a year that never existed.

0.10%round-trip taker cost, per trade
0.15%min per-trade edge we require
4costs most backtests skip

The surprising number is the first one. Not because it's big — because of what it does to trade frequency. Everyone nods at "include fees" and then tests a strategy that trades forty times a day. At 0.10% a round trip, forty trades is 4% of notional per day in costs. There is no signal on a mid-cap perp that clears that bar. The strategy wasn't close to viable, and the fee-free backtest said it was brilliant.

Fees are a filter, not a haircut

The mental model most people carry is that fees shave the curve: same shape, slightly lower. That's wrong. Fees are a frequency filter. They erase high-frequency variants of an edge entirely and leave slow variants nearly untouched. When our pipeline started enforcing real maker/taker schedules per venue, the strategies that died weren't the bad ideas — they were good ideas trading too often. The fix was usually a longer timeframe, not a better signal. We now abandon anything whose average trade return is under 0.15% of notional, because after two-way costs there's nothing left to compound.

Funding is a position tax with a memory

Perpetual futures pay funding every hour or eight hours, and it isn't noise: it's structurally correlated with exactly the trades momentum systems want. When everyone's long, funding is positive, and your long momentum position pays it. A backtest without funding accrual systematically flatters trend-following on perps. We learned this the embarrassing way — an entire family of funding-carry strategies got auto-abandoned because the engine wasn't crediting the funding they were designed to harvest. The signal was fine. The accounting was missing.

Impact scales with the square root of your size

The polite fiction of bar-based backtesting is that you fill at the close. For small orders that's roughly true. For anything meaningful, the accepted model is that impact grows with the square root of order size relative to volume, and it never comes back. We fold a sqrt-law impact estimate into every fill and into the equity curve itself. It matters most exactly where it's least convenient: capacity. A strategy can be genuinely profitable at $50k and structurally unprofitable at $5M, and only an impact-aware curve shows the boundary.

Look-ahead hides in the data, not the code

Nobody writes if tomorrow_close > today_close: buy(). Look-ahead sneaks in through data plumbing: news sentiment stamped by publication time instead of ingestion time, funding rates joined on the period they cover rather than when they were known, "current" symbol universes applied to history (survivorship), revised economic prints replacing the number that actually hit the tape. Our rule is point-in-time everywhere: every supplementary series is timestamped by when we could have known it, and a backtest can only read what existed at that nanosecond.

The test of a backtest isn't whether the curve goes up. It's whether the same code, fed the same signals live, produces the same trades — and you only find out by checking, daily, forever.

That last sentence is a real process, not a slogan. Every day we replay each paper-traded strategy's window through the backtest engine and diff the trades one by one. When paper and replay disagree, one of them is lying, and it's usually a cost or a timestamp. The four line items above are just the ones that lied to us first.

backtestingfeesfundingmarket impacthonesty
← All posts