Backtesting replays a strategy over historical candles and shows what it would have done. It is the cheapest way to reject a bad strategy, and it is also easy to fool yourself with. This guide covers the commands, how to read the report, and the checks we use for every strategy on this site.
Step 1: Download historical data
Freqtrade needs candle data stored locally before it can backtest:
freqtrade download-data --exchange binance \
--pairs BTC/USDT ETH/USDT SOL/USDT \
--timeframes 5m 1h \
--timerange 20240101-
With Docker, prefix commands with docker compose run --rm, for example docker compose run --rm freqtrade download-data ....
Download a little more history than you plan to test. Many indicators need warm-up candles (the strategy's startup_candle_count), and download-data does not add them for you.
Step 2: Run a backtest
freqtrade backtesting --config user_data/config.json \
--strategy BbandRsi --timeframe 1h \
--timerange 20240101-20250101
Useful options:
| Option | What it does |
|---|---|
--timerange 20240101-20250101 |
Limits the test to a date range |
--dry-run-wallet 1000 |
Sets the starting balance |
--stake-amount 200 |
Fixed amount per trade |
--max-open-trades 5 |
How many trades can be open at once |
--fee 0.001 |
Fee per side (0.1%); applied on entry and exit |
--strategy-list A B C |
Tests several strategies on the same data |
--timeframe-detail 5m |
Uses smaller candles to simulate fills inside each candle more accurately |
--breakdown month |
Adds a per-month results table |
--export trades |
Saves every trade for later analysis |
Step 3: Read the report
Freqtrade prints several tables. These are the numbers that matter most.
Total profit %. Return on the starting balance. Always compare it with simply holding the coins over the same period. Freqtrade's report includes a Market change line for exactly this reason.
Max drawdown. The largest fall from a peak to a low in your account. A 50% drawdown needs a 100% gain to recover. We consider this at least as important as total profit.
Win rate. The share of trades closed in profit. On its own it is misleading: a strategy that takes 1% profits with a 10% stoploss can win 85% of the time and still lose money.
Profit factor. Gross profit divided by gross loss. Below 1.0 means the strategy loses money; 1.2–1.5 is a modest edge; much higher on few trades often means luck or over-fitting.
Expectancy. The average result per trade in your stake currency. It should be clearly positive after fees.
Exit reason table. Shows whether trades closed by take-profit (roi), exit_signal, stop_loss or trailing_stop_loss. If almost everything exits via ROI, the strategy's exit logic is barely doing anything.
Trades and pairs. A result from 30 trades is far less reliable than one from 1,000. A result driven by one pair is fragile.
How freqtrade simulates trades
The official docs list the assumptions backtesting makes. The most important:
- Entries happen at the open of the next candle after a signal.
- Orders fill at the requested price with no slippage, as long as the price is inside the candle's range.
- If a candle's range touches both the stoploss and the take-profit, freqtrade assumes the low came first and the stoploss wins.
- Stoploss exits happen exactly at the stop price, which can be optimistic in fast markets.
Backtests on short timeframes (1m and 5m) and with tight targets are hurt most by these simplifications. Expect live results on scalping strategies to be worse than the backtest.
Common backtesting mistakes
Look-ahead bias. Using information from the future, for example shift(-1) or indicators computed over the whole dataset. Freqtrade has a command that checks for this:
freqtrade lookahead-analysis --config user_data/config.json --strategy MyStrategy
Recursive indicator issues. Some indicators give different values depending on how much history they start with. Check with freqtrade recursive-analysis.
Testing only a bull market. A strategy tested only during a rally may simply be long crypto. Test across rising, falling and sideways periods.
Ignoring fees. Always include realistic fees with --fee, or let freqtrade use the exchange's fee. High-frequency strategies live or die by them.
Over-fitting. Tuning parameters until the past looks perfect. See our hyperopt guide for how to test on data the optimiser has not seen.
How we backtest on this site
Every strategy in our leaderboard uses the same 10 coins, the same Binance data, the same $1,000 wallet, $200 stakes, five open trades and a 0.1% fee. The full settings are on our methodology page. Each strategy page includes the exact command to reproduce the result.
After backtesting
A good backtest is a reason to keep testing, not a reason to go live. The next step is dry-run: set "dry_run": true and let the bot trade live prices with a simulated wallet for several weeks. If dry-run results are close to the backtest, you have a much better idea of what to expect.
Ready to connect an exchange?
Freqtrade needs an exchange account with API access. Bybit supports both spot and futures in freqtrade and offers a demo mode for testing.
Affiliate link: we may earn a commission if you sign up, at no cost to you.
Related guides
- Freqtrade hyperopt guide: optimise a strategy without over-fitting itHow freqtrade hyperopt works, which spaces and loss functions to use, how to apply the results, and how to check that the optimised strategy still works on new data.3 min read
- How to control freqtrade from TelegramCreate a Telegram bot with BotFather, find your chat ID, add both to the freqtrade config and use the most useful commands to monitor and control your bot.2 min read
- Freqtrade vs 3Commas vs Pionex vs CryptohopperHow freqtrade compares with 3Commas, Pionex and Cryptohopper on cost, control, strategies, security and effort, and which type of trader each one suits.4 min read