失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > backtrader期权回测框架

backtrader期权回测框架

时间:2019-01-27 23:37:54

相关推荐

backtrader期权回测框架

使用backtrader数据进行回测,数据源来自于交易所爬取。

效果还行,我相信各位通过这个的框架学习,会对backtrader的应用有更深的领悟。包括数据的连接,新指标的加入。

导入框架:

__future__ import (absolute_import, division, print_function, unicode_literals)import pymysqlfrom sqlalchemy import create_engineimport pandas as pdimport numpy as npimport pymssqlimport datetimeimport os.pathimport sysimport backtrader as btimport pandas as pdimport akshare as akimport matplotlibimport matplotlib.pyplot as pltfrom backtrader.feeds import PandasDataimport datetimefrom backtrader.feeds import PandasDatastarttime = datetime.datetime.now()print(starttime)

导入数据

df_read = pd.read_csv('option1.csv')#df_read = df_read[~df_read['ts_code'].isin([0])]date_value_list = []

创建策略

class BollStrategy(bt.Strategy):# 可配置策略参数params = dict(poneplot=False, # 是否打印到同一张图pstake=1,# 单笔交易股票数据)def __init__(self):self.order = None# for i, d in enumerate(self.datas):##跳过第一只股票data,第一只股票data作为主图数据#if i == 0:# if self.p.poneplot:# d.plotinfo.plotmaster = self.datas[0]def prenext(self):# for i,d in enumerate(self.datas):# print(d._name)self.next()# 策略核心,根据条件执行买卖交易指令(必选)def next(self):# 获取当天日期date = self.datas[0].datetime.date(0)# 获取当天valuevalue = self.broker.getvalue()# 存入列表date_value_list.append((date, value))for i,d in enumerate(self.datas):#self.log(f'收盘价,{self.datas[i].close[0]}')dt,dn = self.datetime.date(), d._name #获取时间和股票代码print(self.datas[i].rt[0])if self.order:returnpos = self.getposition(d).sizeif not pos:if self.datas[i].close[0] > 0:self.log(d._name, 'SELL Create, %2f' %self.datas[i].close[0])self.order = self.sell(d , size=self.p.pstake)elif self.datas[i].close[0] == 0 or self.datas[i].close[0] > pos.price * 2 or self.datas[i].rt[0] == 0 :self.log(d._name, 'CLOSE Create, %2f' % self.datas[i].close[0])self.order = self.close(d , size= self.p.pstake)#pass# print(self.datetime.date())# for i, d in enumerate(self.datas):#pos = self.getposition(d)#if not len(pos):# if d.close[0]>0:# self.sell(d,size= self.p.pstake)# elif d.close[0] ==0 or d.close[0] > pos.price * 2:# self.close(d,size= self.p.pstake)# for d in self.datas:#if len(d) == 0:# continue#else:# # 获取当天日期# date = self.datetime.date()# print(self.datas[0].datetime[0])# #print(date)# #查看持仓盈利情况# for i,d in enumerate(self.datas):# pos = self.getposition(d)# # if self.datas[i].close[0] < 0.05:# #self.close(d,size = self.params.pstake)# if len(pos):# # print('{}, 持仓:{}, 成本价:{}, 当前价:{}, 盈亏:{:.2f}'.format(# #d._name, pos.size, pos.price, pos.adjbase, pos.size * (pos.adjbase - pos.price)),# #file=self.log_file)# # print('{}, 持仓:{}, 成本价:{}, 当前价:{}, 盈亏:{:.2f}'.format(# #d._name, pos.size, pos.price, pos.adjbase, pos.size * (pos.adjbase - pos.price)),# #)# if self.datas[i].close[0] == 0:# self.close(d,size=self.params.pstake)# # 获取当天value# value = self.broker.getvalue()## # 存入列表# date_value_list.append((date, value))## for i,d in enumerate(self.datas):# #if self.datas[i].close[0] > 0.01:# try:# if self.datas[i].close[0] > 0:# #print('buy',d.close[0])# self.sell(data = d, size=self.params.pstake)# #print(d._name)# #order.addinfo(ticker=d._name)# #print(d._name)# # else:# ##print('sell',d.close[0])# #self.close(data = d, size=self.params.pstake)# ##order.addinfo(ticker=d._name)# ##print(d._name)# except:# pass#交易记录日志def log(self,txt,dt = None,doprint=False):dt = dt or self.datas[0].datetime.date(0)f = open("log.txt",'a')date = self.datas[0].datetime.date(0)f.write(f'{date},{txt}')f.write("\n")f.close()print(f'{txt}')# 记录交易收益情况(可省略,默认不输出结果)def notify_trade(self, trade):if not trade.isclosed:returnself.log(f'策略收益:\n毛收益 {trade.pnl:.2f}, 净收益 {trade.pnlcomm:.2f}')# 订单状态变化时引擎会调用notify_order# 记录交易执行情况(可省略,默认不输出结果)def notify_order(self, order):#print(order.getstatusname(order.status))if order.status in [order.Submitted, order.Accepted]:return# 如果交易已经完成,显示成交信息if order.status in [pleted]:if order.isbuy() or order.issell():self.log(f'买入:\n价格:{order.executed.price},\成本:{order.executed.value},\手续费:{m}')self.buyprice = order.executed.priceself.buycomm = melse:self.log(f'卖出:\n价格:{order.executed.price},\成本: {order.executed.value},\手续费{m}')self.bar_executed = len(self)elif order.status in [order.Canceled, order.Margin, order.Rejected]:self.log('交易失败')self.order = None#回测结束后输出结果(可省略,默认输出结果)# def stop(self):#self.log('(MA均线: %2d日) 期末总资金 %.2f' %# (self.params.maperiod, self.broker.getvalue()), doprint=True)def stop(self):self.log('期末总资金 %.2f' %(self.broker.getvalue()), doprint=True)

添加参数

#添加参数class ETFOptionPandasData(PandasData):# 新增两条数据线lines = ('rt',)# 新增数据在dataframe中的位置,分别是第6列和第7列params = (('rt', 6),)

调取数据,放入cerebro

cerebro = bt.Cerebro()# 建立期权池stk_pools = df_read['ts_code'].unique().tolist()# 获取期权数据for stk_code in stk_pools:df = df_read[df_read['ts_code'] == stk_code]df.index = pd.to_datetime(df['datetime'])#print(df.head())#data = ETFOptionPandasData(dataname=df)df = df[['ts_code', 'open', 'high', 'low', 'close', 'volume','rt']]#print(df.head())data = ETFOptionPandasData(dataname = df,datetime = -1)cerebro.adddata(data, name = str(stk_code))

运行策略,添加交易参数

cerebro.broker.setcash(10000000.0)cerebro.broker.setcommission(commission=1.62,margin = 2000,mult= 10000 )cerebro.addstrategy(BollStrategy)cerebro.broker.set_coc(True)#设置以当天收盘价成交cerebro.run() #减少内存。此设置会自动禁止数据预加载(preload)和指标预计算(runonce),也禁止绘图plot,因为内存中数据不足以绘图了。for d in cerebro.datas:d.plotinfo.plot =Falseprint('cash',cerebro.broker.getvalue())

如果觉得《backtrader期权回测框架》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。