失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 基于backtrader的唐奇安通道策略实现

基于backtrader的唐奇安通道策略实现

时间:2023-07-23 00:14:37

相关推荐

基于backtrader的唐奇安通道策略实现

基于backtrader的唐奇安通道策略实现

代码实现

##导入相关包 优化jupyter画图设置from datetime import datetime,timedeltaimport backtrader as btimport tushare as tsimport pandas as pdimport talib as taimport numpy as npimport matplotlib.pyplot as pltimport mplfinance as mpfplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falseplt.rcParams['figure.figsize']=[6, 3]plt.rcParams['figure.dpi']=200plt.rcParams['figure.facecolor']='w'plt.rcParams['figure.edgecolor']='k'

# ts获取数据测试ts.get_k_data('601398',autype='qfq',start='-01-01',end='-05-25')

578 rows × 7 columns

# 获取数据函数编写def get_data(code,start_date,end_date,period):df=ts.get_k_data(code,autype='qfq',start=start_date,end=end_date)df['ret']=df.close.pct_change()close=df.closehigh=df.highlow=df.lowup=pd.Series(0.0,index=close.index)down=pd.Series(0.0,index=close.index)middle=pd.Series(0.0,index=close.index)for i in range(period,len(close)):up[i]=max(high[(i-period):i])down[i]=min(low[(i-period):i])middle[i]=(up[i]+down[i])/2df['up']=updf['down']=downdf['middle']=middledf=df[20:]df['atr']= ta.ATR(high, low, close, timeperiod=14)df=df[20:]df['openinterest']=0df.index=pd.to_datetime(df.date)df=df[['open','high','low','close','volume','openinterest','ret','up','down','middle','atr']] return df

# 获取数据函数测试stock_df=get_data('601398','-01-01','-05-25',20)stock_df.head()

# 唐奇安通道画图style = mpf.make_mpf_style(base_mpl_style="ggplot")add_plot=[mpf.make_addplot(stock_df.up),mpf.make_addplot(stock_df.middle),mpf.make_addplot(stock_df.down)]mpf.plot(data=stock_df,type="candle",title="Candlestick for fhgx",addplot=add_plot,ylabel="price",style=style,volume=True,figratio=(100,50))

# 编写唐奇安通道策略def strategy(data,start,end):df=datax1=data.close>data.upx2=data.close.shift(1)<data.up.shift(1)x=x1&x2y1=data.close<data.downy2=data.close.shift(1)>data.down.shift(1)y=y1&y2data.loc[x,'收盘信号']=1data.loc[y,'收盘信号']=0data=data.fillna(0)df['当天仓位']=df['收盘信号'].shift(1)df['当天仓位'].fillna(method='ffill',inplace=True)d=df[df['当天仓位']==1].index[0]-timedelta(days=1)df1=df.loc[d:].copy()df1['ret'][0]=0df1['当天仓位'][0]=0#当仓位为1时,买入持仓,当仓位为-1时,空仓,计算资金净值df1['策略净值']=(df1.ret.values*df1['当天仓位'].values+1.0).cumprod()df1['指数净值']=(df1.ret.values+1.0).cumprod()df1['策略收益率']=df1['策略净值']/df1['策略净值'].shift(1)-1df1['指数收益率']=df1.rettotal_ret=df1[['策略净值','指数净值']].iloc[-1]-1annual_ret=pow(1+total_ret,250/len(df1))-1dd=(df1[['策略净值','指数净值']].cummax()-df1[['策略净值','指数净值']])/df1[['策略净值','指数净值']].cummax()d=dd.max()beta=df1[['策略收益率','指数收益率']].cov().iat[0,1]/df1['指数收益率'].var()alpha=(annual_ret['策略净值']-annual_ret['指数净值']*beta)exReturn=df1['策略收益率']-0.03/250sharper_atio=np.sqrt(len(exReturn))*exReturn.mean()/exReturn.std()TA1=round(total_ret['策略净值']*100,2)TA2=round(total_ret['指数净值']*100,2)AR1=round(annual_ret['策略净值']*100,2)AR2=round(annual_ret['指数净值']*100,2)MD1=round(d['策略净值']*100,2)MD2=round(d['指数净值']*100,2)S=round(sharper_atio,2)df1[['策略净值','指数净值']].plot(figsize=(15,7))plt.title('海龟交易策略简单回测',size=15)bbox = dict(boxstyle="round", fc="w", ec="0.5", alpha=0.9)plt.text(df1.index[int(len(df1)/5)], df1['指数净值'].max()/1.5, f'累计收益率:\策略{TA1}%,指数{TA2}%;\n年化收益率:策略{AR1}%,指数{AR2}%;\n最大回撤: 策略{MD1}%,指数{MD2}%;\n\策略alpha: {round(alpha,2)},策略beta:{round(beta,2)}; \n夏普比率: {S}',size=13,bbox=bbox) plt.xlabel('')ax=plt.gca()ax.spines['right'].set_color('none')ax.spines['top'].set_color('none')plt.show()

strategy(data=stock_df,start='-01-01',end='-05-25')

## 编写bt回测策略import backtrader.analyzers as btanalyzersimport backtrader.feeds as btfeedsimport backtrader.strategies as btstratsfrom backtrader.feeds import PandasDataclass PandasData(PandasData):# 新增两条数据线lines = ('up', 'down',) # 新增数据在dataframe中的位置params = (('up',8), ('down',9), )class TestStrategy(bt.Strategy):def log(self,txt,dt=None):dt=dt or self.datas[0].datetime.date(0)print('%s,%s'%(dt.isoformat(),txt))def __init__(self):self.dataclose = self.datas[0].closeself.dataup = self.datas[0].upself.datadown = self.datas[0].downself.datatime=self.datas[0].datetime.date(0)self.order=None #跟踪挂单self.buyprice = Noneself.buycomm = None #加入手续费def notify_order(self,order):if order.status in [order.Submitted,order.Accepted]: #经纪商提交/接受/接受的买入/卖出订单 returnif order.status in [pleted]: ## 检查订单是否完成# 注意:如果没有足够的现金,经纪人可能会拒绝订单if order.isbuy():self.log('BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %(order.executed.price,order.executed.value,m))self.buyprice = order.executed.priceself.buycomm = melse:self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %(order.executed.price,order.executed.value,m))self.bar_executed=len(self)elif order.status in [order.Canceled,order.Margin,order.Rejected]:self.log('Order Canceled/Margin/Rejected')self.order=None #写下:无挂单def next(self):# self.log('Close,%.2f'%self.dataclose[0])if self.order: ## 检查订单是否处于待处理状态...如果是,我们不能发送第二个returnif not self.position: #检查我们是否在市场上if self.dataclose[0]>self.dataup[0]:if self.dataclose[-1]<self.dataup[-1]:self.log('BUY CREATE,%.2f'%self.dataclose[0])self.log('BUY CREATE,%.2f'%self.dataup[0])self.order=self.buy() #跟踪创建的订单以避免第二个订单else:if self.dataclose[0]<self.datadown[0]:if self.dataclose[-1]>self.datadown[-1]:self.log('SELL CREATE,%.2f'%self.dataclose[0])self.log('SELL CREATE,%.2f'%self.datadown[0])self.order=self.sell()

#回测data = PandasData(dataname=stock_df)cerebro=bt.Cerebro()cerebro.addstrategy(TestStrategy)cerebro.adddata(data)cerebro.addanalyzer(btanalyzers.SharpeRatio, _name='mysharpe')cerebro.broker.setcash(50000.0)cerebro.addsizer(bt.sizers.FixedSize, stake=5000) cerebro.broker.setcommission(commission=0.002) print(f'组合初始价值:%.2f'%cerebro.broker.getvalue())# 运行brokerthestrats = cerebro.run()print(f'组合期末价值:%.2f'%cerebro.broker.getvalue())cerebro.plot(iplot=False)thestrat = thestrats[0]print('Sharpe Ratio:', thestrat.analyzers.mysharpe.get_analysis())

组合初始价值:50000.00-03-16,BUY CREATE,4.64-03-16,BUY CREATE,4.60-03-17,BUY EXECUTED, Price: 4.63, Cost: 23155.00, Comm 46.31-03-31,SELL CREATE,4.62-03-31,SELL CREATE,4.67-04-01,SELL EXECUTED, Price: 4.62, Cost: 23155.00, Comm 46.21-09-04,BUY CREATE,4.63-09-04,BUY CREATE,4.62-09-07,BUY EXECUTED, Price: 4.62, Cost: 23120.00, Comm 46.24-09-22,SELL CREATE,4.66-09-22,SELL CREATE,4.68-09-23,SELL EXECUTED, Price: 4.66, Cost: 23120.00, Comm 46.64-12-23,BUY CREATE,4.69-12-23,BUY CREATE,4.65-12-24,BUY EXECUTED, Price: 4.69, Cost: 23470.00, Comm 46.94-01-22,SELL CREATE,4.77-01-22,SELL CREATE,4.83-01-25,SELL EXECUTED, Price: 4.76, Cost: 23470.00, Comm 47.64-04-29,BUY CREATE,4.95-04-29,BUY CREATE,4.91-04-30,BUY EXECUTED, Price: 4.94, Cost: 24720.00, Comm 49.44-06-01,SELL CREATE,4.91-06-01,SELL CREATE,4.92-06-02,SELL EXECUTED, Price: 4.91, Cost: 24720.00, Comm 49.14-07-15,BUY CREATE,4.75-07-15,BUY CREATE,4.68-07-16,BUY EXECUTED, Price: 4.75, Cost: 23750.00, Comm 47.50-08-12,SELL CREATE,4.63-08-12,SELL CREATE,4.64-08-13,SELL EXECUTED, Price: 4.63, Cost: 23750.00, Comm 46.30-11-11,BUY CREATE,4.66-11-11,BUY CREATE,4.61-11-12,BUY EXECUTED, Price: 4.66, Cost: 23300.00, Comm 46.60-12-15,SELL CREATE,4.61-12-15,SELL CREATE,4.62-12-16,SELL EXECUTED, Price: 4.61, Cost: 23300.00, Comm 46.10-03-10,BUY CREATE,4.56-03-10,BUY CREATE,4.50-03-11,BUY EXECUTED, Price: 4.55, Cost: 22750.00, Comm 45.50-04-27,SELL CREATE,4.71-04-27,SELL CREATE,4.73-04-28,SELL EXECUTED, Price: 4.71, Cost: 22750.00, Comm 47.10-05-13,BUY CREATE,4.70-05-13,BUY CREATE,4.64-05-16,BUY EXECUTED, Price: 4.70, Cost: 23500.00, Comm 47.00组合期末价值:49395.34

Sharpe Ratio: OrderedDict([('sharperatio', -1.0256629031574036)])

如果觉得《基于backtrader的唐奇安通道策略实现》对你有帮助,请点赞、收藏,并留下你的观点哦!

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