参数优化¶
参数优化帮助找到最佳策略参数。需要在高普适性和高效率之间权衡。
警告
作者建议使用自定义多进程进行优化,而不是 cerebro.optstrategy(),
因为偶尔会出现优化结果与单次运行结果不一致的bug。
内置优化¶
使用 optstrategy 的基本用法:
cerebro = bt.Cerebro()
# 添加带参数范围的策略
cerebro.optstrategy(
MyStrategy,
period=range(10, 31, 5), # 10, 15, 20, 25, 30
stake=[10, 20, 50]
)
# 运行优化
results = cerebro.run()
# 处理结果
for run in results:
for strat in run:
print(f'周期: {strat.params.period}, 仓位: {strat.params.stake}')
print(f'最终资金: {strat.broker.getvalue()}')
多核优化¶
cerebro = bt.Cerebro(maxcpus=4) # 使用4核
# 或者
cerebro = bt.Cerebro(maxcpus=None) # 使用所有可用核心
获取最优参数¶
def run_optimization():
cerebro = bt.Cerebro()
cerebro.adddata(data)
cerebro.optstrategy(
MyStrategy,
fast=range(5, 15),
slow=range(20, 40, 5)
)
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
results = cerebro.run()
# 找到最佳结果
best = None
best_sharpe = float('-inf')
for run in results:
for strat in run:
sharpe = strat.analyzers.sharpe.get_analysis()
ratio = sharpe.get('sharperatio', 0) or 0
if ratio > best_sharpe:
best_sharpe = ratio
best = strat
if best:
print(f'最优参数: fast={best.params.fast}, slow={best.params.slow}')
print(f'夏普比率: {best_sharpe:.4f}')
return best
内存优化¶
对于大规模优化:
cerebro = bt.Cerebro(
optreturn=False, # 不返回完整的策略对象
maxcpus=4
)
推荐:多进程优化¶
为了更可靠和灵活的优化,使用 Python 的 multiprocessing:
from multiprocessing import Pool
from itertools import product
import pandas as pd
def run_strategy(params):
'''使用给定参数运行单次回测'''
period, stake = params
cerebro = bt.Cerebro()
cerebro.adddata(data) # 你的数据
cerebro.addstrategy(MyStrategy, period=period, stake=stake)
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe')
cerebro.addanalyzer(bt.analyzers.DrawDown, _name='dd')
cerebro.broker.setcash(100000)
results = cerebro.run()
strat = results[0]
sharpe = strat.analyzers.sharpe.get_analysis().get('sharperatio', 0) or 0
max_dd = strat.analyzers.dd.get_analysis()['max']['drawdown']
final_value = cerebro.broker.getvalue()
return {
'period': period,
'stake': stake,
'sharpe': sharpe,
'max_dd': max_dd,
'final_value': final_value
}
if __name__ == '__main__':
# 定义参数网格
periods = range(10, 31, 5)
stakes = [10, 20, 50]
param_grid = list(product(periods, stakes))
# 并行运行
with Pool(processes=4) as pool:
results = pool.map(run_strategy, param_grid)
# 转换为 DataFrame 进行分析
df = pd.DataFrame(results)
print(df.sort_values('sharpe', ascending=False).head(10))
# 获取最优参数
best = df.loc[df['sharpe'].idxmax()]
print(f"最优: period={best['period']}, stake={best['stake']}")
print(f"夏普比率: {best['sharpe']:.4f}")
滚动优化(Walk-Forward)¶
def walk_forward(data, strategy_cls, param_ranges,
train_period=252, test_period=63):
results = []
for start in range(0, len(data) - train_period - test_period, test_period):
# 训练期
train_start = start
train_end = start + train_period
# 测试期
test_start = train_end
test_end = test_start + test_period
# 在训练数据上优化
cerebro = bt.Cerebro()
train_data = data[train_start:train_end]
cerebro.adddata(train_data)
cerebro.optstrategy(strategy_cls, **param_ranges)
opt_results = cerebro.run()
# 找到最优参数
best_params = find_best_params(opt_results)
# 在样本外数据上测试
cerebro = bt.Cerebro()
test_data = data[test_start:test_end]
cerebro.adddata(test_data)
cerebro.addstrategy(strategy_cls, **best_params)
test_results = cerebro.run()
results.append({
'train_period': (train_start, train_end),
'test_period': (test_start, test_end),
'best_params': best_params,
'test_results': test_results
})
return results
最佳实践¶
使用多进程: 比内置的
optstrategy更可靠谨慎设置 maxcpus: 使用
maxcpus = cpu_count - 1避免系统卡死使用 optreturn=False: 对于大规模优化,减少内存使用
验证结果: 始终用单次运行验证优化结果
避免过拟合: 使用滚动优化或交叉验证
保存结果: 将优化结果输出到 CSV 以便后续分析