Backtrader简单均线交易策略“金叉和死叉”
1、使用5日均线和10日均线
MA5和MA10的交叉点作为买入和卖出信号
交易策略是量化交易的核心,MA均线策略也称为SMA均线策略,是量化交易的最简单的量化交易策略之一,当5日均线向上穿过10日均线的时候,我们称为金叉,当5日均线向上穿过10日均线的时候,我们成为死叉。本使用的是极宽量化交易的包。
2、导入包
import sys;
sys.path.append("topqt/")#
import matplotlib as mpl
import matplotlib.pyplot as plt#
import os,time,arrow,math,random,pytz
import datetime as dt
#
import backtrader as bt
import topquant2019 as tq
3、设置交易策略
Backtrader的策略函数源自Strategy类函数,一个完整的策略函数至少要包括以下两个策略函数。
(1)init:策略初始化函数
(2)next:策略执行函数
(3)notify_order:订单信息管理函数
(4)notify_trade:交易信息管理函数
(5)stop:策略回测结束函数
(6)log:自定义输出函数
本案例中时间周期为5天和10天,在init初始化函数的重点是增加了一组MA均线指标。
程序调用的是Backtrader内部指标模块indicators,周期参数变量是均线函数内部的变量名称period,不同指标参数变量名称是不同的。周期参数数值。使用的是策略定义的周期变量,数值为5天和10天。
#----------------------# # 创建一个自定义策略类class
# class TQSta001(bt.Strategy):class TQSta001(bt.Strategy):"""继承并构建自己的bt策略"""# 定义MA均线策略周期参数变量def log(self, txt, dt=None, doprint=True):''' 日志函数,用于统一输出日志格式 '''if doprint:dt = dt or self.datas[0].datetime.date(0)print('%s, %s' % (dt.isoformat(), txt))def __init__(self):# 初始化相关数据self.dataclose = self.datas[0].closeself.order = Noneself.buyprice = Noneself.buycomm = None# 五日移动平均线self.sma5 = bt.indicators.SimpleMovingAverage(self.datas[0], period=5)# 十日移动平均线self.sma10 = bt.indicators.SimpleMovingAverage(self.datas[0], period=10)def notify_order(self, order):"""订单状态处理Arguments:order {object} -- 订单状态"""if order.status in [order.Submitted, order.Accepted]:# 如订单已被处理,则不用做任何事情return# 检查订单是否完成if order.status in [order.Completed]:if order.isbuy():self.log('买单执行BUY EXECUTED,成交价: %.2f,小计 Cost: %.2f,佣金 Comm %.2f' % (order.executed.price,order.executed.value,order.executed.comm))self.buyprice = order.executed.priceself.buycomm = order.executed.commelif order.issell():self.log('卖单执行SELL EXECUTED,成交价: %.2f,小计 Cost: %.2f,佣金 Comm %.2f' % (order.executed.price,order.executed.value,order.executed.comm))self.bar_executed = len(self)# 订单因为缺少资金之类的原因被拒绝执行elif order.status in [order.Canceled, order.Margin, order.Rejected]:self.log('Order Canceled/Margin/Rejected')# 订单状态处理完成,设为空self.order = Nonedef notify_trade(self, trade):"""交易成果Arguments:trade {object} -- 交易状态"""if not trade.isclosed:return# 显示交易的毛利率和净利润self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %(trade.pnl, trade.pnlcomm), doprint=True)def next(self):''' 下一次执行 '''# 记录收盘价self.log('Close, %.2f' % self.dataclose[0])# 是否正在下单,如果是的话不能提交第二次订单if self.order:return# 是否已经买入if not self.position:# 还没买,如果 MA5 > MA10 说明涨势,买入if self.sma5[0] > self.sma10[0]:self.order = self.buy()else:# 已经买了,如果 MA5 < MA10 ,说明跌势,卖出if self.sma5[0] < self.sma10[0]:self.order = self.sell()def stop(self):self.log(u'(金叉死叉有用吗) Ending Value %.2f' %(self.broker.getvalue()), doprint=True)
4、设置交易策略
if __name__ == '__main__':cerebro = bt.Cerebro()dmoney = 100000.0cerebro.broker.setcash(dmoney)dcash0 = cerebro.broker.startingcashrs0 = 'data/stk/'xcod = '002046'fdat = rs0 + xcod + '.csv't0str,t9str='2018-01-01','2018-12-31'data=tq.pools_get4fn(fdat,t0str,t9str)cerebro.adddata(data)cerebro.addstrategy(TQSta001)# 设置佣金cerebro.broker.setcommission(commission=0.01)cerebro.addsizer(bt.sizers.FixedSize,stake=10)cerebro.run()dval9 = cerebro.broker.getvalue()kret = (dval9 - dcash0)/dcash0*100print('\t起始资金 Starting Portfolio Value: %.2f' % dcash0)print('\t资产总值 Final Portfolio Value: %.2f' % dval9)print('\tROI投资回报率 Return on investment: %.2f %%' % kret)cerebro.plot()
5、结果展示
参考链接:
https://zhuanlan.zhihu.com/p/133637955