失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Python量化交易学习笔记(19)——连续下跌买入止盈止损卖出策略

Python量化交易学习笔记(19)——连续下跌买入止盈止损卖出策略

时间:2024-07-29 16:13:14

相关推荐

Python量化交易学习笔记(19)——连续下跌买入止盈止损卖出策略

好友提出要验证连续下跌买入止盈止损卖出策略,本文对该策略回测和实现做分析记录。

买入条件中,连续下跌定义为收盘价连续4日低于前1日的收盘价。卖出条件中,止盈率设置为10%,止损率设置为5%。回测初始资金100000元,单笔操作单位1000股,佣金千分之一,回测时间自1月1日至3月20日。

策略核心代码位于策略类的next方法中:

def next(self):if self.orefs: # order列表,用于存储尚未执行完成的订单return# 有尚未执行的订单# 尚未进场if not self.position:# 获取近几日收盘价用于判断是否连续下跌lastcloses = list()for i in range(self.p.p_downdays + 1):lastcloses.append(self.dataclose[-i])# 连续N日下跌if lastcloses == sorted(lastcloses):# 计算买入报价跑p1,止损价p2,止盈价p3close = self.dataclose[0]p1 = close * (1.0 - self.p.limit)p2 = p1 - self.p.p_stoploss * closep3 = p1 + self.p.p_takeprofit * close# 计算订单有效期valid1 = datetime.timedelta(self.p.limdays)valid2 = valid3 = datetime.timedelta(self.p.limdays2)# 使用bracket orders设置买入卖出os = self.buy_bracket(price=p1, valid=valid1,stopprice=p2, stopargs=dict(valid=valid2),limitprice=p3, limitargs=dict(valid=valid3),)# 保存激活的的订单self.orefs = [o.ref for o in os]

这里主要应用了backtrader的bracket order,它其实并不是1个订单,而是有3个订单构成:1个买单,1个止损卖单,1个止盈卖单。2个卖单就像是把买单用括号括起来一样,因此合称为bracket order(括号订单)。我们所使用的buy_bracket方法遵循以下规则:

为了避免被分开执行,3个订单要被一起提交2个卖单要作为买单的子订单在买单执行前,2个卖单处于非激活状态买单如果被取消,2个卖单也会随之被取消买单被执行后,2个卖单均被激活一旦两个卖单被激活,其中一个被执行或者被取消,另一个都将被自动取消。

buy_bracket方法中除了设置买入价、止损价、止盈价外,还设置了订单有效时间,如果订单在有效时间内未执行,则会过期失效。一般我们将买入有效期设置为3天以内,卖出有效期设置为较长时间,以保证股票可以卖出。

回测000001后的最终资产为102781.90元,这里交易大小仅为1000股,所用资金仅为不到20000元,提高交易量,收益还是相当可观。

回测000002后的最终资产为96476.14元,亏损。

回测601318后的最终资产为75044.50元,亏得一塌糊涂。

观察几张图标可以发现,我们经常可以找到很好的买点,但是会出现本来盈利的订单,最后变成亏损的情况。在挖backtrader文档的时候,发现了一个比较好的利润保护方法,将在下一篇文章中进行实现及分析,敬请期待。

友情提示:本系列学习笔记只做数据分析,记录个人学习过程,不作为交易依据,盈亏自负。

连续下跌买入止盈止损卖出策略代码:

from __future__ import (absolute_import, division, print_function, unicode_literals)import datetime # 用于datetime对象操作import os.path # 用于管理路径import sys # 用于在argvTo[0]中找到脚本名称import backtrader as bt # 引入backtrader框架# 创建策略class St(bt.Strategy):params = dict(p_downdays = 4,# 连续下跌天数p_stoploss = 0.05, # 止损比例p_takeprofit = 0.1, # 止盈比例limit=0.005,limdays=3,limdays2=1000,hold=10,usebracket=False, # use order_target_sizeswitchp1p2=False, # switch prices of order1 and order2)def notify_order(self, order):print('{}: Order ref: {} / Type {} / Status {}'.format(self.data.datetime.date(0),order.ref, 'Buy' * order.isbuy() or 'Sell',order.getstatusname()))if order.status == pleted:self.holdstart = len(self)if not order.alive() and order.ref in self.orefs:self.orefs.remove(order.ref)def __init__(self):# 引用data[0]数据的收盘价数据self.dataclose = self.datas[0].closesma = bt.ind.SMA(period = self.p.p_downdays + 1, plot = False)self.orefs = list()def next(self):if self.orefs: # order列表,用于存储尚未执行完成的订单return# 有尚未执行的订单# 尚未进场if not self.position:# 获取近几日收盘价用于判断是否连续下跌lastcloses = list()for i in range(self.p.p_downdays + 1):lastcloses.append(self.dataclose[-i])# 连续N日下跌if lastcloses == sorted(lastcloses):# 计算买入报价跑p1,止损价p2,止盈价p3close = self.dataclose[0]p1 = close * (1.0 - self.p.limit)p2 = p1 - self.p.p_stoploss * closep3 = p1 + self.p.p_takeprofit * close# 计算订单有效期valid1 = datetime.timedelta(self.p.limdays)valid2 = valid3 = datetime.timedelta(self.p.limdays2)# 使用bracket orders设置买入卖出os = self.buy_bracket(price=p1, valid=valid1,stopprice=p2, stopargs=dict(valid=valid2),limitprice=p3, limitargs=dict(valid=valid3),)# 保存激活的的订单self.orefs = [o.ref for o in os]cerebro = bt.Cerebro() # 创建cerebro# 先找到脚本的位置,然后根据脚本与数据的相对路径关系找到数据位置# 这样脚本从任意地方被调用,都可以正确地访问到数据modpath = os.path.dirname(os.path.abspath(sys.argv[0]))datapath = os.path.join(modpath, '../TQDat/day/stk/000001.csv')# 创建价格数据data = bt.feeds.GenericCSVData(dataname = datapath,fromdate = datetime.datetime(, 1, 1),todate = datetime.datetime(, 3, 31),nullvalue = 0.0,dtformat = ('%Y-%m-%d'),datetime = 0,open = 1,high = 2,low = 3,close = 4,volume = 5,openinterest = -1)# 在Cerebro中添加价格数据cerebro.adddata(data)# 设置启动资金cerebro.broker.setcash(100000.0)# 设置交易单位大小cerebro.addsizer(bt.sizers.FixedSize, stake = 1000)# 设置佣金为千分之一cerebro.broker.setcommission(commission=0.001)cerebro.addstrategy(St) # 添加策略cerebro.run() # 遍历所有数据# 打印最后结果print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())cerebro.plot() # 绘图

为了便于相互交流学习,新建了微信群,感兴趣的读者请加微信。

如果觉得《Python量化交易学习笔记(19)——连续下跌买入止盈止损卖出策略》对你有帮助,请点赞、收藏,并留下你的观点哦!

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