A cost model is not a detail. It can be larger than the effect you are trying to measure.
I ran a 1-minute futures strategy and it lost 94% of its capital. That looked like a decisive answer: the strategy does not work.
It was not decisive. Half of that loss was invented by my cost model.
What I assumed
I used 5 basis points per side, which is 10 bp round trip. That number came from crypto, where I had been working. It felt conservative: surely paying more cost than reality is the safe direction.
That intuition is wrong, and not mildly wrong.
What it actually costs
| Instrument | measured round trip | assumption was |
|---|---|---|
| NQ (Nasdaq futures) | 0.30 bp | 33× too high |
| MGC (micro gold) | 0.55 bp | 18× too high |
| BTC perpetual | 10.2 bp | about right |
Note the last row. The number I used was correct — for the asset class I took it from. That is the trap: a cost assumption is a fact about a specific market, and it does not travel.
Futures on a liquid index are extraordinarily cheap to trade. Crypto perpetuals are not. They differ by more than an order of magnitude, and I applied the expensive one to the cheap market.
Why it mattered more than usual
Here is the part that makes this a systemic problem rather than a slip.
With 1-minute entries, the per-trade risk on this strategy was only about 6.2 bp. So the cost-to-risk ratio was:
10 bp cost ÷ 6.2 bp risk ≈ 162%
I was charging more than one and a half times the risk of the trade as friction. The result was that every trade lost 3.16R on average, of which 2.16R was invented fees and only 1.0R was the strategy.
That is not a strategy being measured. That is a cost model being measured.
Correcting the number to 0.30 bp moved the same run from −94.0% to −45.5%.
The rule of thumb
Before rejecting a strategy on cost grounds, compute one ratio:
round-trip cost ÷ per-trade risk
If it exceeds about 5%, stop. Do not conclude the strategy is bad — conclude that you do not know your costs, and go measure them. A ratio above 100% (as mine was) means the cost term dominates the result entirely and the backtest is telling you about your assumptions, not about the market.
The corollary is just as important: a strategy whose edge is small relative to friction is not necessarily broken. It may be correctly measured and simply too small — which is a different conclusion with a different next step (find cheaper execution, trade less often, or move to a higher timeframe) and not "throw it away".
How to measure instead of guess
I did not have a perfect cost model afterwards either. What I had was something better than a guess:
- Use the exchange's own fee schedule, not a number from another asset class.
- Add the spread separately. It is usually larger than commission on liquid futures and it varies by time of day. Sample it, don't assume it.
- Sanity-check against a fill-quality sample. Take 50 real fills, compare your simulated price to the actual one. The gap is your slippage estimate.
- State the number and its source in the results. "Costs: 0.30 bp round trip, measured from NQ fill samples over the sample period" is a claim someone can audit. "5 bp" is a habit.
The uncomfortable asymmetry
An optimistic cost assumption makes a bad strategy look good — and you will find out in production, expensively.
A pessimistic cost assumption makes a good strategy look bad — and you will never find out, because you will have moved on. That failure is silent. It cost me a line of research, and I only noticed because a 94% loss looked too clean to be real.
So the discipline is symmetric: do not treat high costs as the safe direction. Both directions are errors, and the pessimistic one is the one nobody catches for you.
The cost-per-risk check is one of the static checks in a small open-source linter (GitHub, MIT, no dependencies). It flags a fee column that is missing or zero, and reports cost against per-trade risk so the ratio is visible before you draw conclusions.
If you would rather have this as a download than a repo: the same tool, plus the
demo trade logs (one with five bugs planted, one clean), is *$0** on Gumroad —
pay what you want, and $0 is a valid answer: https://weiwave23.gumroad.com/l/backtest-lie-detector*

Top comments (0)