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

买入条件中,连续下跌定义为收盘价连续4日低于前1日的收盘价。卖出条件中,止盈率设置为10%,止损率设置为5%。回测初始资金100000元,单笔操作单位1000股,佣金千分之一,回测时间自2018年1月1日至2020年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 == order.Completed: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(2018, 1, 1),todate = datetime.datetime(2020, 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)——连续下跌买入止盈止损卖出策略相关推荐

  1. Python量化交易学习笔记(1)

    Python量化交易学习笔记(1) http://zwpython.com/ http://www.topquant.vip/?p=2275 [更多参见] <zwPython,目前最好的py开发 ...

  2. Python量化交易学习笔记(20)——保护点卖出策略

    本文主要记录保护点卖出策略,给买入的股票设立保护点,随着股票收盘价的提升,保护点不断提高,股价一旦跌破保护点,即卖出股票. 示例的买入条件为,5日线金叉60日线,且股价进行小幅回踩(较金叉日收盘价下跌 ...

  3. Python量化交易学习笔记(18)——放量突破布林线中轨买入策略

    本文将探索新的策略回测程序,主要是为了尝试不同的技术指标在backtrader平台上的应用,为后续复杂策略的实现做准备. 本文将实现的策略是,当股票放量突破布林线中轨时进行买入,当股票收盘价低于短期均 ...

  4. Python量化交易学习笔记(33)——backtrader仓位管理

    本文将对backtrader的仓位管理进行介绍,具体以同时回测交易3只股票为例,查看每日仓位情况. 策略 买入条件:5日线金叉60日线 卖出条件:5日线死叉60日线 示例 仓位信息输出的核心代码位于策 ...

  5. Python量化交易学习笔记(36)——backtrader多股回测避坑3

    本文继续记录多股回测时可能遇到的异常情况. 坑描述 多股回测时,当日期达到所有股票的技术指标都能够计算出有效值后,backtrader才开始进行回测.由于这种逻辑的存在,如果某些股票在回测周期的最后几 ...

  6. Python量化交易学习笔记(25)——Data Feeds扩展

    背景:需要扩展data feeds的场景 在backtrader中,data feeds中包含了被普遍认为是业界标准的几个字段: datetime open high low close volume ...

  7. Python量化交易学习笔记(14)——均线交叉策略

    本文使用均线交叉策略,对平安银行自2018年1月1日至2020年2月28日的日线数据进行回测分析. 策略会用到短期移动均线及长期移动均线两个技术指标,在backtrader自定义策略init方法中,添 ...

  8. Python量化交易学习笔记(46)——通达信日线数据获取

    序 从2020年初开始接触量化,马上就要满一年了.在这一年里,想过去做量化,想过去做机器学习,想过去做少儿编程教育.就这样大概折腾了小半年时间,最后在CSDN上看到这样一句话:"你把时间投在 ...

  9. Python量化交易学习笔记(2)——A股数据下载

    由于笔者只接触过A股交易,因此本系列笔记仅针对A股交易展开.笔者的计算机为Windows 10 64位操作系统. TOP极宽量化总群(124134140)群文件中提供了大量的学习资料,一眼看去有点懵圈 ...

最新文章

  1. 告诫那些有创业梦的大学生,切记千万不要盲目创业!
  2. 如何使ResNet优于EfficientNet?
  3. 赠 看穿一切的var_dump
  4. 全新开源,《Pytorch常用函数函数手册》开放下载!内含200余个函数!
  5. ADF声明性组件示例
  6. 酒店wifi代理服务器没有响应,wn10连接酒店wifi的登录界面无法弹出如何处理
  7. 产品设计:APP个人信息保护指引
  8. ACM-ICPC 2018徐州网络赛-H题 Ryuji doesn't want to study
  9. leetcode力扣17.电话号码的字母组合
  10. ORB-SLAM2双目开源框架 (1)
  11. 阿里巴巴创新中心联手上海市经信委在沪搞大事情了!
  12. python实现自动化打印
  13. 单点登录(java)
  14. 统计学---方差分析
  15. 文件上传5-uploads靶场
  16. interactive governor study for android
  17. Excel数据分析入门-数据透视表
  18. windows10下使用DNW下载
  19. 动态规划之01背包问题讲解
  20. python爬虫20 | 小帅b教你如何使用python识别图片验证码

热门文章

  1. 二维数组中查找指定数据
  2. 旅游行业网站怎么搭建?
  3. 批量下载Google字体示例(实)
  4. 前端学习笔记——JavaScript进阶
  5. 微星主板cpu故障灯一直亮红灯解决办法
  6. 程序员要保持学习,持续学习
  7. 腾讯通(RTX) 自动关闭 及解决方案
  8. 如何运行一个BSV创世全节点
  9. 中国科学院计算机网络中心刘倩,中国科学院大学研究生导师教师师资介绍简介-刘倩...
  10. [明日方舟抽卡数据库]开发日志(二)