简介Backtrader 是一个开源的 Python 量化交易回测框架,功能非常强大,主要由以下模块组成。
支持多种数据源(Yahoo、Pandas、CSV)
封装了功能强大的交易接口,个人只需要实现策略逻辑即可
提供了多种交易指标,并提供了Ta-lib的支持,个人可根据接口规范实现自定义的指标
提供了多种订单类型
提供了对实盘环境中会遇到的资金、税费、滑点、成交限制等问题的支持
提供了对仓位的管理功能
提供了对策略评估指标的支持
提供了对买卖点、净值曲线、盈亏曲线的支持
提供了对可视化的支持 可见,基本上 Backtrader 已经囊括了在量化交易中的方方面面,而且,它的文档非常详尽,按照官方文档即可很快上手。 官方文档: https://www./docu/ 实现三重滤网获取历史数据在之前的文章中已经给出了几种免费获取历史交易数据的方式,可自行查看。 梳理交易策略在之前的文章中已经给出了此策略的大体思路,以及使用程序实现时应该注意的问题。 实现技术指标在此策略中,强力指数是作者自定义的一个指标,因此需要自行实现。 # 自定义指标需继承自 bt.Indicator class ForceIndexLine(bt.Indicator): # 给指标起一个名字 lines = ('FI',) # 设置指标的时间周期 params = (('period', 2),)
def __init__(self): # 为计算指标所需的最小时间周期 self.addminperiod(self.p.period*2)
def next(self): last_c = self.data.close[-1] curt_c = self.data.close[0] curt_v = self.data.volume[0]
# 设置强力指数的计算逻辑 self.lines.FI[0] = curt_v * (curt_c - last_c) / 1000000 实现交易策略因为涉及到周、日、分钟三个时间周期,因此需要分别处理
然后需要注意的是: Backtrader自带的指标计算结果与国内各平台指标数值不一致! 因此,如果想要得到与国内平台一致的指标数值,需要自行实现按照国内指标计算规则的算法。好在已经有开源库(MyTT)实现了这些功能,安装此库后直接使用即可。 然后在 next 函数中添加每周、每天需要做的初始化操作。当然,这里也可以使用Timer来实现。 def next(self): # 为拉长指标的计算周期, 设置的回测开始时间较早, 因此这里需要做时间过滤 wait_flag = self.data_m.datetime.datetime(0) < datetime.datetime(2020, 1, 6) if wait_flag: return # 每天开盘后做初始化的操作 if self.data_m.datetime.time(0) == datetime.time(9, 35): self.idx_w = self.data_w.datetime.get_idx() self.idx_d = self.data_d.datetime.get_idx() calendar = self.data_m.datetime.datetime(0).isocalendar() # 每周的第一个交易日重置动力系统状态 if self.calendar is None or calendar[0] != self.calendar[0] or calendar[1] != self.calendar[1]: self.calendar = calendar self.stops_prefit = False self.impulse_status = 0 self.impulse_system() # 每天重新计算由平均下跌穿透得到的买入价 self.adp_f = False array = [self.ema_d_s[self.idx_d i] - self.data_d.close[i] for i in range(-2, 1)] self.adp_v = sum([item for item in array if item > 0]) / self.p.EMA_D_S pre_ema = 2 * self.ema_d_s[self.idx_d - 1] - self.ema_d_s[self.idx_d - 2] self.adp_p = pre_ema - self.adp_v 然后实现之前在聚宽平台上的处理,此外,这里添加了基于 ATR 的止损
测试交易策略cerebro = bt.Cerebro()
# 为尽量模拟全仓的效果, 这里设置最小单位为10 cerebro.addsizer(bt.sizers.FixedSize, stake=10)
# 加入三种时间周期的数据, 也可以使用 resampling 模式 m_data = get_data_feed(stock, '5M', '%Y-%m-%d %H:%M:%S') cerebro.adddata(m_data, name=f'{stock}-5M') d_data = get_data_feed(stock, 'D', '%Y-%m-%d') cerebro.adddata(d_data, name=f'{stock}-D')
w_data = get_data_feed(stock, 'W', '%Y-%m-%d') cerebro.adddata(w_data, name=f'{stock}-W') # 设置资金和税费 cerebro.broker.setcash(CASH) cerebro.broker.setcommission(COMMISSION)
# 添加策略后运行并绘制结果 cerebro.addstrategy(strategy) cerebro.run() cerebro.plot() 业绩评估指标接下来就要分析一下策略的业绩,通过 Backtrader 自带的分析器即可得到收益、回撤、指标等各项数据。 如果想要更详细的数据,也可以基于 quantstats 库做进一步的分析 当然,如果想要实现更复杂的显示效果,完全可以将收益序列导出后加载到 Highcharts-Stock 进行定制化开发。 参数优化在实现策略时涉及到了三个参数
显然,周线级别的参数决定了买入时参考的时间周期,日线级别的参数决定了卖出时参考的时间周期。13、3、20 只是一种想当然的经验值,是否还有其它更优的参数组合?如果是在量化平台网站进行测试,目前看来大多都只能手动调整。然而使用 Backtrader 的话,则只需要稍加修改,就可以支持对多个参数组合的回测。 # cerebro.addstrategy(strategy) # 将 addstrategy 修改为 optstrategy 即可,然后加入要测试的策略中的参数组合 cerebro.optstrategy(strategy, EMA_W_T=range(5, 25, 5), EMA_D_S=range(3, 15, 3), EMA_D_M=range(5, 30, 5)) # 这里需要设置最大内核数以避免目前其尚未修复的BUG results = cerebro.run(maxcpus=1) 得到完整的参数组合效果
从中可以看到,最优结果有聚集的现象,即当某个参数固定时,调整其它参数对整体结果影响不大。当然,最优参数有过拟合的可能,具体还要结合收益曲线做进一步的分析。 后期展望通过 Backtrader 可以本地运行回测后,没有了量化平台积分的限制,那么就可以借助它的强大功能开始做一些有意思的事情了。比如,分析某个指标在某些个股上的胜率,筛选对某些个股最有效的指标。以及,各种技术形态在某些个股上的胜率。 |
|