How results are calculated

Every backtest lies a little. Ours tells you how much.

A backtest is a simulation, and every simulation makes assumptions. Most tools make the assumptions that produce the prettiest chart. Here is exactly what this one assumes, and why each choice is the less flattering one.

Three places backtests quietly cheat

Filling at the signal price

If your rule says “buy when RSI drops below 30”, that signal only exists once the bar has closed. Filling at that same closing price means buying at the exact price you needed in order to make the decision — which nobody could ever have done.

We fill at the next bar’s open, which is the first price you could actually have traded.

Resolving ambiguous bars kindly

When a single bar’s range covers both your stop loss and your take profit, the data cannot say which one happened first. Assume the profit and a losing strategy backtests as a winner.

We take the stop. Pessimistic, and stated rather than hidden.

Forgetting what trading costs

Fees, slippage and — on perpetual futures — a funding payment every eight hours. Small individually, decisive across hundreds of trades.

All charged, with liquidation checked against the mark price rather than the last trade.

Impossible rules are rejected before they run

A strategy here is structured data rather than code, so we know the range every indicator can produce. RSI never exceeds 100 — so a rule waiting for it to cross 119 can never fire. The position would open once and never close, and the result would look like a spectacular winner while really being buy-and-hold.

check_strategy
rule:    crossunder(rsi, 119)
verdict: never_true
reason:  rsi ranges over [0, 100] and is
         always at or below 119

→ rejected before any data was loaded
   cost: nothing

This is not hypothetical. A competing service returns exactly this configuration as a winning optimisation result, and offers to apply it in one click.

The optimizer will tell you its winner is worthless

Search hard enough over historical data and a good-looking result always turns up, whether or not any edge exists. The arithmetic is worse than most people expect: the reliability of an annualised Sharpe ratio depends on the span of the test rather than the number of bars in it, so one year of data gives roughly ±1.0 either way. The best of a thousand combinations therefore sits about three standard errors up — meaning a thousand-combination sweep over one year is expected to produce a best-of Sharpe above 3 from pure luck.

Best of 144 combinations scored Sharpe 0.96, but the best of 144 worthless strategies would be expected to score 3.05 by luck alone. This result is indistinguishable from noise — do not trade it.

Every sweep also withholds a third of the window from the search and re-runs the winner on it. A strategy that looks good in-sample and collapses out-of-sample was fitted to the past, and no amount of in-sample performance can reveal that.

Where the data comes from

Binance’s public archive: real minute-to-daily candles, real funding rates, and real mark prices, across 1,000+ perpetual markets. Nothing is synthetic and nothing is sampled.

Two numbers, because they answer different questions. Around 570 of those markets are trading today, which is what you can forward test. The rest have been delisted, and their history is still perfectly good to backtest against — leaving it out would quietly bias every result towards coins that happened to survive.

It begins in January 2020. Binance listed its first perpetual in September 2019, but never published the months before 2020 to the archive, so those weeks do not exist here and a backtest cannot pretend otherwise. Ask for a window that starts earlier and you get the bars that exist, with a note saying so — not a quietly shortened test reported as the one you asked for.

Test an idea and see for yourself.

Start free

Backtests simulate the past. They are not predictions and not financial advice.