回测
本页解释如何验证您的策略性能通过使用历史数据进行回测。
回测需要可用的历史数据。要了解如何获取您感兴趣的交易对和交易所的数据,请参阅文档中的数据下载部分。
回测命令参考
usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH]
[--recursive-strategy-search]
[--freqaimodel NAME] [--freqaimodel-path PATH]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,feather,parquet}]
[--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[-p PAIRS [PAIRS ...]] [--eps]
[--enable-protections]
[--dry-run-wallet DRY_RUN_WALLET]
[--timeframe-detail TIMEFRAME_DETAIL]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
[--export {none,trades,signals}]
[--export-filename PATH]
[--breakdown {day,week,month,year} [{day,week,month,year} ...]]
[--cache {none,day,week,month}]
[--freqai-backtest-live-models]
主要参数
-i TIMEFRAME, --timeframe TIMEFRAME- 指定时间框架(1m,5m,30m,1h,1d)--timerange TIMERANGE- 指定要使用的数据时间范围--data-format-ohlcv- 下载的蜡烛(OHLCV)数据的存储格式(默认:feather)--max-open-trades INT- 覆盖max_open_trades配置设置的值--stake-amount STAKE_AMOUNT- 覆盖stake_amount配置设置的值--fee FLOAT- 指定费用比例。将应用两次(在交易进入和退出时)-p PAIRS [PAIRS ...], --pairs PAIRS [PAIRS ...]- 限制命令仅适用于这些交易对。交易对以空格分隔--eps, --enable-position-stacking- 允许多次购买相同的交易对(位置叠加)--enable-protections, --enableprotections- 为回测启用保护。这将显著减慢回测速度,但会包括配置的保护措施--dry-run-wallet DRY_RUN_WALLET, --starting-balance DRY_RUN_WALLET- 起始余额,用于回测/超参数优化和干跑--timeframe-detail TIMEFRAME_DETAIL- 指定回测的详细时间框架(1m,5m,30m,1h,1d)--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]- 指定要回测的策略列表--export {none,trades,signals}- 导出回测结果(none, trades, signals)--export-filename PATH- 指定导出文件的路径--breakdown {day,week,month,year}- 显示按天、周、月、年分解的回测结果--cache {none,day,week,month}- 加载不超过指定年龄的缓存回测结果(默认:day)--freqai-backtest-live-models- 使用现有模型运行回测
基本回测示例
简单回测
# 基本回测
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20231231
指定时间框架
# 在 5 分钟时间框架上回测
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timeframe 5m \
--timerange 20230101-20231231
多交易对回测
# 回测特定交易对
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--pairs BTC/USDT ETH/USDT BNB/USDT \
--timerange 20230101-20231231
高级回测选项
详细时间框架
# 使用详细时间框架进行更精确的回测
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timeframe 5m \
--timeframe-detail 1m \
--timerange 20230101-20230201
详细时间框架
使用 --timeframe-detail 可以提高回测精度,但会显著增加计算时间和内存使用。
启用保护
# 启用保护机制的回测
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--enable-protections \
--timerange 20230101-20231231
性能影响
启用保护会显著减慢回测速度,但提供更真实的结果。
多策略回测
# 同时回测多个策略
freqtrade backtesting \
--config user_data/config.json \
--strategy-list Strategy1 Strategy2 Strategy3 \
--timerange 20230101-20231231
结果导出和分析
导出交易数据
# 导出交易详情
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20231231 \
--export trades \
--export-filename user_data/backtest_results/my_backtest.json
导出信号数据
# 导出入场和出场信号
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20231231 \
--export signals \
--export-filename user_data/backtest_results/signals.json
分解分析
# 按月分解结果
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20231231 \
--breakdown month
# 按周分解结果
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20231231 \
--breakdown week day
回测结果分析
查看回测结果
# 显示过去的回测结果
freqtrade backtesting-show
# 显示特定回测结果
freqtrade backtesting-show --backtest-filename user_data/backtest_results/backtest-result-2023-01-01_12-00-00.json
回测分析
# 分析回测结果
freqtrade backtesting-analysis \
--config user_data/config.json \
--analysis-groups 0 1 2 \
--enter-reason-list rsi_oversold bb_lower \
--exit-reason-list roi stop_loss
理解回测结果
主要指标
回测完成后,您将看到类似以下的结果:
============ BACKTESTING REPORT ============
| Metric | Value |
|-------------|----------------------|
| Backtesting from | 2023-01-01 00:00:00 |
| Backtesting to | 2023-12-31 23:59:00 |
| Max open trades | 3 |
| | |
| Total/Daily Avg Trades | 85 / 0.23 |
| Starting balance | 1000 USDT |
| Final balance | 1234.56 USDT |
| Absolute profit | 234.56 USDT |
| Total profit % | 23.46% |
| CAGR % | 25.12% |
| Profit factor | 1.34 |
| Trades per day | 0.23 |
| Avg. daily profit % | 0.064% |
| Avg. stake amount | 33.33 USDT |
| Total trade volume | 2833.05 USDT |
| | |
| Best Pair | ETH/USDT 45.67% |
| Worst Pair | ADA/USDT -12.34% |
| Best trade | 12.34% |
| Worst trade | -5.67% |
| Best day | 23.45% |
| Worst day | -8.91% |
| Days win/draw/lose | 123 / 45 / 67 |
| Avg. Duration Winners | 4:12:00 |
| Avg. Duration Loser | 2:34:00 |
| Rejected Entry signals | 12 |
| | |
| Min balance | 987.65 USDT |
| Max balance | 1345.67 USDT |
| Max % of account underwater | -1.23% |
| Absolute Drawdown (Account) | -12.35 USDT |
| Absolute Drawdown % | -1.23% |
| Max Drawdown (Account) | -23.45 USDT |
| Max Drawdown % | -2.34% |
| Max Drawdown Duration | 12:34:00 |
| Max Drawdown Duration (Account) | 23:45:00 |
| | |
| Sharpe Ratio | 1.23 |
| Sortino Ratio | 1.45 |
| Calmar Ratio | 1.12 |
关键指标解释
- Total profit % - 总利润百分比
- CAGR % - 复合年增长率
- Profit factor - 盈利交易总额 / 亏损交易总额
- Sharpe Ratio - 风险调整后收益
- Max Drawdown - 最大回撤
- Win Rate - 胜率
回测最佳实践
1. 使用足够的历史数据
# 至少使用 1 年的数据
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20220101-20231231
2. 测试不同市场条件
# 牛市期间
freqtrade backtesting --timerange 20210101-20211231
# 熊市期间
freqtrade backtesting --timerange 20220101-20221231
# 震荡市期间
freqtrade backtesting --timerange 20230101-20231231
3. 使用现实的费用
# 设置实际的交易费用
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--fee 0.001 # 0.1% 费用
4. 启用保护测试
# 测试保护机制
freqtrade backtesting \
--config user_data/config.json \
--strategy SampleStrategy \
--enable-protections \
--timerange 20230101-20231231
回测缓存
Freqtrade 会缓存回测结果以提高性能。
缓存设置
# 不使用缓存
freqtrade backtesting --cache none
# 使用日缓存(默认)
freqtrade backtesting --cache day
# 使用周缓存
freqtrade backtesting --cache week
# 使用月缓存
freqtrade backtesting --cache month
清除缓存
# 删除缓存文件
rm -rf user_data/backtest_results/.bt_data/
回测假设和限制
重要假设
回测假设
回测基于以下假设,这些可能与实际交易不同:
- 订单成交假设 - 假设所有限价单都会成交
- 滑点忽略 - 不考虑市场滑点
- 流动性假设 - 假设有足够的流动性
- 时间精度 - 基于蜡烛时间,不是实际成交时间
- 费用简化 - 使用固定费用率
与实盘的差异
-
订单成交
- 回测:假设所有订单都成交
- 实盘:订单可能部分成交或不成交
-
价格精度
- 回测:使用 OHLCV 数据
- 实盘:使用实时 tick 数据
-
网络延迟
- 回测:无延迟
- 实盘:存在网络和处理延迟
-
滑点
- 回测:不考虑滑点
- 实盘:存在价格滑点
回测策略优化
参数测试
# 测试不同的投注金额
freqtrade backtesting --stake-amount 10
freqtrade backtesting --stake-amount 50
freqtrade backtesting --stake-amount 100
# 测试不同的最大开仓数
freqtrade backtesting --max-open-trades 1
freqtrade backtesting --max-open-trades 3
freqtrade backtesting --max-open-trades 5
时间范围分析
# 分析不同时间段
freqtrade backtesting --timerange 20230101-20230331 # Q1
freqtrade backtesting --timerange 20230401-20230630 # Q2
freqtrade backtesting --timerange 20230701-20230930 # Q3
freqtrade backtesting --timerange 20231001-20231231 # Q4
回测结果可视化
生成图表
# 生成利润图表
freqtrade plot-profit \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20231231
# 生成数据框图表
freqtrade plot-dataframe \
--config user_data/config.json \
--strategy SampleStrategy \
--pairs BTC/USDT \
--timerange 20230101-20230201
Jupyter Notebook 分析
# 在 Jupyter Notebook 中分析结果
import pandas as pd
import json
# 加载回测结果
with open('user_data/backtest_results/backtest-result-2023-01-01_12-00-00.json') as f:
results = json.load(f)
# 转换为 DataFrame
trades_df = pd.DataFrame(results['strategy']['SampleStrategy']['trades'])
# 分析交易
print(f"总交易数: {len(trades_df)}")
print(f"胜率: {(trades_df['profit_ratio'] > 0).mean():.2%}")
print(f"平均利润: {trades_df['profit_ratio'].mean():.2%}")
print(f"最大单次利润: {trades_df['profit_ratio'].max():.2%}")
print(f"最大单次亏损: {trades_df['profit_ratio'].min():.2%}")
回测验证
前瞻偏差检查
# 检查前瞻偏差
freqtrade lookahead-analysis \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20230201
# 检查递归问题
freqtrade recursive-analysis \
--config user_data/config.json \
--strategy SampleStrategy \
--timerange 20230101-20230201
稳健性测试
# 不同起始日期测试
freqtrade backtesting --timerange 20230101-20231231
freqtrade backtesting --timerange 20230115-20240114
freqtrade backtesting --timerange 20230201-20240131
# 不同交易对组合测试
freqtrade backtesting --pairs BTC/USDT ETH/USDT
freqtrade backtesting --pairs BTC/USDT ETH/USDT BNB/USDT ADA/USDT
freqtrade backtesting --pairs BTC/USDT ETH/USDT BNB/USDT ADA/USDT DOT/USDT
常见回测错误
1. 过度拟合
# 错误:参数过度拟合特定时间段
minimal_roi = {
"0": 0.12345, # 过于精确的参数
"23": 0.06789,
"87": 0.01234
}
# 改进:使用合理的参数
minimal_roi = {
"0": 0.10,
"30": 0.05,
"60": 0.02,
"120": 0
}
2. 前瞻偏差
# 错误:使用未来数据
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['future_high'] = dataframe['high'].shift(-1) # 错误!
return dataframe
# 正确:只使用历史数据
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['prev_high'] = dataframe['high'].shift(1) # 正确
return dataframe
3. 数据不足
# 错误:数据太少
freqtrade backtesting --timerange 20231201-20231231 # 只有 1 个月
# 改进:使用足够的数据
freqtrade backtesting --timerange 20230101-20231231 # 1 年数据
4. 忽略费用
# 错误:不设置费用
freqtrade backtesting --config user_data/config.json
# 改进:设置现实的费用
freqtrade backtesting --config user_data/config.json --fee 0.001
回测性能优化
1. 使用缓存
# 利用缓存加速重复回测
freqtrade backtesting --cache day # 默认
2. 选择合适的数据格式
# 使用 feather 格式获得最佳性能
freqtrade backtesting --data-format-ohlcv feather
3. 限制数据量
# 使用较短的时间范围进行快速测试
freqtrade backtesting --timerange 20231101-20231130
# 使用较少的交易对
freqtrade backtesting --pairs BTC/USDT ETH/USDT
4. 并行处理
# 使用多个 CPU 核心(如果支持)
export NUMBA_NUM_THREADS=4
freqtrade backtesting --config user_data/config.json
回测后的步骤
1. 结果验证
- 检查胜率是否合理(通常 30-60%)
- 验证最大回撤是否可接受
- 确认 Sharpe 比率为正数
2. 干跑验证
# 在干跑模式下验证策略
freqtrade trade \
--config user_data/config.json \
--strategy SampleStrategy \
--dry-run
3. 参数优化
如果回测结果不理想,考虑使用超参数优化:
freqtrade hyperopt \
--config user_data/config.json \
--strategy SampleStrategy \
--hyperopt-loss SharpeHyperOptLoss \
--spaces roi stoploss trailing
下一步
完成回测后,您可能想要优化策略参数。您的下一步是阅读"超参数优化"文档。