backtrader内置的策略参数优化方法是权利搜索方法,也就是遍历每个参数组合值。在参数很多,每个参数取值变化范围大的情况下,优化效率是很低的。
可以采用智能优化算法,比如粒子群优化等进行大规模参数优化。下面,我们用python开源算法库optunity来对backtrader策略参数进行优化。
我们的示例策略是一个简单的双均线策略,要优化两个参数,及两个均线移动窗口,目标是使得账户市值最大化。采用optunity中的粒子群算法来优化,代码如下:
# example of optimizing SMA crossover strategy parameters using
# Particle Swarm Optimization in the opptunity python library
# https://github.com/claesenm/optunity
from datetime import datetime
import backtrader as bt
import optunity
import optunity.metrics
class SmaCross(bt.SignalStrategy):
params = (
('sma1', 10), # 需要优化的参数1,短期均线窗口
('sma2', 30), # 需要优化的参数2,长期均线窗口
)
def __init__(self):
SMA1 = bt.ind.SMA(period=int(self.params.sma1)) # 用int取整
SMA2 = bt.ind.SMA(period=int(self.params.sma2)) # 用int取整
crossover = bt.ind.CrossOver(SMA1, SMA2)
self.signal_add(bt.SIGNAL_LONG, crossover)
data0 = bt.feeds.YahooFinanceData(dataname='YHOO',
fromdate=datetime(2011, 1, 1),
todate=datetime(2012, 12, 31))
def runstrat(sma1,sma2):
cerebro = bt.Cerebro()
cerebro.addstrategy(SmaCross, sma1=sma1, sma2=sma2)
cerebro.adddata(data0)
cerebro.run()
return cerebro.broker.getvalue()
# 执行优化,执行100次回测(num_evals),设置两个参数的取值范围
opt = optunity.maximize(runstrat, num_evals=100,solver_name='particle swarm', sma1=[2, 55], sma2=[2, 55])
optimal_pars, details, _ = opt
print('Optimal Parameters:')
print('sma1 = %.2f' % optimal_pars['sma1'])
print('sma2 = %.2f' % optimal_pars['sma2'])
cerebro = bt.Cerebro()
cerebro.addstrategy(SmaCross, sma1=optimal_pars['sma1'], sma2=optimal_pars['sma2'])
cerebro.adddata(data0)
cerebro.run()
cerebro.plot()
optunity支持如下几种算法(solver),读者可以分别测试它们。
particle swarm,sobol,random search,cma-es,grid search
更多内容请参考我们编写的backtrader教程
或视频教程