# How to backtest a trading strategy without fooling yourself

> How to backtest a trading strategy with unseen data, realistic crypto fees and funding, and checks for overfitting before you risk money.

**Short answer:** To backtest a trading strategy without fooling yourself, write the rules before looking at results, test them on later data you did not use to develop them, and include realistic trading costs. Then check whether the result survives repeated time splits and paper trading. A profitable historical curve is evidence to investigate, not a promise about future trades.

## How to backtest a trading strategy in practice

Start by writing a version of the rules that another person could follow without making judgment calls. State the market and symbol, timeframe, entry trigger, order type, position size, stop and exit, and what happens if a signal arrives while a position is open. Define when the signal becomes knowable. For example, if a rule uses a candle’s closing price, it can’t enter at that same close unless your assumed execution could actually happen then.

Keep this rule sheet unchanged during the first test. Save the date, data source, code or spreadsheet version, and each parameter you chose. This makes it harder to quietly change a rule after seeing a losing trade.

Next, select data that matches the instrument you plan to trade. Spot prices and perpetual futures prices aren’t interchangeable. Check timestamps, missing candles, symbol changes and whether the test can see only information that existed at that time. A signal calculated using a candle’s final high, for example, must not act before that candle has finished.

Use the same starting balance, position-sizing rule and execution assumptions throughout. Record every trade, including losses and trades with no fill. Don’t skip a valid signal because the next candle looks unfavorable on a chart.

## How should you split the data for walk forward analysis?

Keep development data separate from data used to judge the final rule. **In-sample** data is the earlier history you use to define or tune a strategy. **Out-of-sample** data is later history kept aside to evaluate the frozen version. If you inspect the test results and change the strategy, that period has become part of development; it’s no longer a clean out-of-sample test. Researchers describe this problem with repeated out-of-sample retesting ([Harvey & Liu, 2015](https://people.duke.edu/~charvey/Research/Published_Papers/P120_Backtesting.PDF)).

For walk-forward optimization, fit or choose settings using a past window, then apply them unchanged to the next window. Move forward and repeat. The table is an illustrative schedule, not a recommended universal window size:

| Round | Data used to choose settings | Frozen test window |
| ----- | ---------------------------- | ------------------ |
| 1     | January–June                 | July–August        |
| 2     | March–August                 | September–October  |
| 3     | May–October                  | November–December  |

Join only the results from the test windows to see how the process would have behaved as time moved forward. Keep one later period untouched until the rules and schedule are fixed, if enough data is available. Don’t choose window lengths because they make the results look best. A short test window can contain too few trades; a long one can mix market conditions that no longer match the strategy.

There’s no split that removes uncertainty. Even a held-out result can be due to chance, and revising a strategy after seeing the test weakens the test ([Harvey & Liu, 2015](https://people.duke.edu/~charvey/Research/Published_Papers/P120_Backtesting.PDF)). Report each window’s result and trade count, not just the combined curve. A large gap between development and test results is a reason to question the rule.

## Which costs belong in crypto backtesting?

Subtract costs for every execution: exchange fees, slippage and, for perpetual futures, funding payments. **Slippage** is the difference between the price assumed by your test and the price an order could actually receive. A limit order may not fill just because the market touched its price.

For a simple round trip, estimate trading fees as:

`entry notional × entry fee rate + exit notional × exit fee rate`

For example, assume an illustrative $1,000 position is opened and closed at $1,000 notional each time, with a 0.05% taker rate on both executions. The entry fee is $0.50 and the exit fee is $0.50, or $1.00 total. If the gross gain was $8, that leaves $7 before slippage or funding. These are assumed numbers, not a quoted Binance rate. Binance fees depend on the instrument, maker/taker execution and account tier; check the current fee page for the account you will use ([Binance, 2026](https://www.binance.com/en/support/faq/detail/360033544231)).

For a perpetual contract, include each funding settlement that occurs while the position is open. Funding is a payment between long and short positions. Its direction and size depend on the rate and position, and the interval can be adjusted by the exchange. Use the historical funding rate for each settlement in your test, rather than applying today’s rate to old trades. Binance gives the funding amount as nominal position value multiplied by the funding rate ([Binance, 2026](https://www.binance.com/en/support/faq/detail/360033525031)).

If you don’t have order-book data to estimate slippage, write down a conservative assumption and rerun the test at higher costs. Treat that as a sensitivity check, not a forecast. A strategy that only works with perfect fills or zero funding isn’t ready for a live test. For the fee distinction, see our guide to [maker and taker fees](/blog/maker-vs-taker-fees).

## What can make backtesting a trading strategy misleading?

Use this checklist before trusting a result.

| Mistake                                                    | How it can show up in results                                                              | Fix                                                                                                                                                                                                                                                                                                                                                                                                      |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Changing rules after each run                              | The best-looking version is reported, but the number of attempts is hidden.                | Keep a dated log of every rule and parameter tried. Recheck the chosen version on untouched data.                                                                                                                                                                                                                                                                                                        |
| Reusing the holdout                                        | “Out-of-sample” performance improves after repeated edits.                                 | Once you inspect that period and revise the strategy, move it into development. Reserve later data for a new final check.                                                                                                                                                                                                                                                                                |
| Looking ahead inside a candle                              | Entries happen at a high, low or close that was not yet known when the signal appeared.    | Make signals available only after their inputs are complete; use an execution price and time that could follow.                                                                                                                                                                                                                                                                                          |
| Ignoring delisted coins                                    | The test includes today’s survivors but misses assets that were later delisted or removed. | Rebuild the tradable universe as it existed at each date, including delisted assets when data is available. A 2022 working paper using 3,904 cryptocurrencies from 2014–2021 reports survivorship effects in portfolio returns; its sample is evidence of the issue, not a forecast for your strategy ([Ammann et al., 2022](https://www.sebastianstoeckl.com/publications/wp2022_liebi_survivorship/)). |
| Leaving out costs or assuming every limit order fills      | Gross returns look strong while net returns shrink or disappear.                           | Apply the actual fee tier and order type, model slippage, and include historical funding for perpetuals.                                                                                                                                                                                                                                                                                                 |
| Choosing a result from many variants without counting them | One lucky parameter set looks like a repeatable edge.                                      | Report the number of trials. More tests create more chances to fit noise; research on backtest overfitting describes settings that capture past noise rather than future signal ([Bailey et al., 2014](https://carmamaths.org/resources/jon/backtest2.pdf)).                                                                                                                                             |

Keep ordinary performance measures in context. Win rate alone ignores the size of wins and losses. Net return alone hides the path and the largest fall from a previous peak. Check drawdown by period ([what drawdown means in trading](/blog/drawdown-in-trading)), compare gains with losses ([risk-reward ratio](/blog/risk-reward-ratio)), and read Sharpe as one risk-adjusted summary rather than a complete test ([what makes a good Sharpe ratio](/blog/good-sharpe-ratio)).

## What should you do after a backtest passes?

Freeze the rules and paper trade them forward, without changing settings mid-test. Paper trading checks whether signals arrive as expected and whether the orders appear fillable; it still may not reproduce the fills, fees or market impact of real orders. If you later try live trading, use an amount small enough that a loss wouldn’t harm your finances, and compare actual fills and costs with the assumptions in your log before deciding whether to continue.

Use a simple decision rule: reject or revise the strategy if its net test results depend on one favorable window or disappear when you add realistic costs. If results are reasonably consistent across the test windows, paper trade the frozen rules and record where live prices and fills differ from the simulation. A small live run is a later check, not a conclusion that the strategy will keep working.

We started with our own money in July 2025 and removed rules that worked on historical data but failed in real trading. We run Cointrapper, a private trading pool on Binance. That experience is one reason we treat a backtest as a filter, not proof that a strategy will work. You can run these checks yourself with historical data and a spreadsheet or backtesting program.

Crypto trading is high risk: you can lose your entire investment. Past performance does not guarantee future results, and this article is not individual investment advice.
