本文主要记录保护点卖出策略,给买入的股票设立保护点,随着股票收盘价的提升,保护点不断提高,股价一旦跌破保护点,即卖出股票。

示例的买入条件为,5日线金叉60日线,且股价进行小幅回踩(较金叉日收盘价下跌1%)。卖出条件为,股价跌破保护点。保护点首先设置为买入当天收盘价减去一个资金回撤值(率),示例把回撤率设置为5%。后续如果股票的收盘价上升,则用新的收盘价更新保护点,如果股票的收盘价下跌,则保留原有保护点。回测初始资金100000元,单笔操作单位1000股,佣金千分之一,回测时间自2018年1月1日至2020年3月20日。

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

    def next(self):# 无场内资产if not self.position:# 未提交买单if None == self.order:# 金叉到达了买点if self.buy_con:# 计算订单有效期时间,如果超过有效期,股价仍未回踩,则放弃下买入订单valid = self.data.datetime.date(0)if self.p.buy_valid_date:valid = valid + datetime.timedelta(days=self.p.buy_valid_date)# 计算回踩后的买入价格price = self.datas[0].close[0] * (1.0 - self.p.buy_limit_percent)print('Buy order created: {}: close: {} / limit price: {} / valid: {}'.format(self.datetime.date(), self.datas[0].close[0], price, valid) )# 用有效时间及回踩买点提交买入订单self.order = self.buy(exectype = bt.Order.Limit, price = price, valid = valid)#o = self.buy()print('*' * 50)elif self.order is None:# 提交stoptrail订单self.order = self.sell(exectype=self.p.stoptype,trailamount=self.p.trailamount,trailpercent=self.p.trailpercent)

在买入时,程序中使用了backtrader的Limit类型订单,在Limit订单创建时,会设置一个price及有效日期valid,如果到达日期valid后,股价还没有匹配上price,订单就会被取消。匹配price包括两种情况:

  • 如果开盘价低于price,那么订单就会用开盘价被立即执行
  • 如果开盘价高于price,但是当日最低价低于price,那么订单将会以price的价格被执行
    从Limit订单的描述可以看出,正好符合我们所说的股价回踩买入规则。

在卖出时,程序使用了backtrader的StopTrail订单,回撤可以用回撤值(trailamount)或者回撤率(trailpercent)来表示,这里我们选择用5%的回撤率来做回测。StopTrail将按下面的逻辑进行工作:

  • 使用当日收盘价作为price值
  • price按照回撤率回撤计算后的价格,被作为触发价格(trigger price),即我们所说的保护点。比如price=100,trailpercent=5%,那么trigger price=100*(1-5%)=95
  • 代理在下一根K线迭代计算时,会计算是否达到trigger price
  • 如果达到trigger price,卖单将被执行
  • 如果没有达到trigger price,那么trigger price将用当前的收盘价按照之前选定的回撤率进行重新计算
  • 如果股价上涨,那么trigger price将会被更新为新的trigger price
  • 如果估计不变或者下跌,那么trigger price不更新

从StopTrail订单的描述可以看出,保护点会随着股价的上升不断更新,不断提高,一旦股价跌破保护点,就会进行卖出,这样可以有效的保护我们的利润。同时可以看到,即使股价一直下跌,StopTrail订单也可以有效止损。

回测000001后的最终资产为102017.97元。

回测000002后的最终资产为103236.59元。


回测603999后的最终资产为99510.06元。


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

保护点卖出策略代码:

# 创建策略
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(buy_limit_percent = 0.01,buy_valid_date = 5,stoptype=bt.Order.StopTrail,trailamount=0.0,trailpercent=0.05,p_high_period = 5,p_fast = 5,p_slow = 60,)def __init__(self):slowSMA = bt.ind.SMA(period = self.p.p_slow)self.buy_con = bt.And(bt.ind.CrossUp(bt.ind.SMA(period = self.p.p_fast), slowSMA),#slowSMA == bt.ind.Highest(slowSMA, period = self.p.p_high_period, plot = False))self.order = Nonedef notify_order(self, order):if order.status in [order.Completed]:print('Completed order: {}: Order ref: {} / Type {} / Status {} '.format(self.data.datetime.date(0),order.ref, 'Buy' * order.isbuy() or 'Sell',order.getstatusname()))self.order = Noneif order.status in [order.Expired]:self.order = Noneprint('{}: Order ref: {} / Type {} / Status {}'.format(self.data.datetime.date(0),order.ref, 'Buy' * order.isbuy() or 'Sell',order.getstatusname()))def next(self):# 无场内资产if not self.position:# 未提交买单if None == self.order:# 金叉到达了买点if self.buy_con:# 计算订单有效期时间,如果超过有效期,股价仍未回踩,则放弃下买入订单valid = self.data.datetime.date(0)if self.p.buy_valid_date:valid = valid + datetime.timedelta(days=self.p.buy_valid_date)# 计算回踩后的买入价格price = self.datas[0].close[0] * (1.0 - self.p.buy_limit_percent)print('Buy order created: {}: close: {} / limit price: {} / valid: {}'.format(self.datetime.date(), self.datas[0].close[0], price, valid) )# 用有效时间及回踩买点提交买入订单self.order = self.buy(exectype = bt.Order.Limit, price = price, valid = valid)#o = self.buy()print('*' * 50)elif self.order is None:# 提交stoptrail订单self.order = self.sell(exectype=self.p.stoptype,trailamount=self.p.trailamount,trailpercent=self.p.trailpercent)if self.p.trailamount:tcheck = self.data.close - self.p.trailamountelse:tcheck = self.data.close * (1.0 - self.p.trailpercent)print('Sell stoptrail order created: {}: \close: {} /  \Limit price: {} / check price {}'.format(self.datetime.date(), self.data.close[0],self.order.created.price, tcheck))print('-' * 10)else:if self.p.trailamount:tcheck = self.data.close - self.p.trailamountelse:tcheck = self.data.close * (1.0 - self.p.trailpercent)print('update limit price: {}: \close: {} /  \Limit price: {} / check price {}'.format(self.datetime.date(), self.data.close[0],self.order.created.price, tcheck))cerebro = bt.Cerebro()  # 创建cerebro
# 先找到脚本的位置,然后根据脚本与数据的相对路径关系找到数据位置
# 这样脚本从任意地方被调用,都可以正确地访问到数据
modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
datapath = os.path.join(modpath, '../TQDat/day/stk/603999.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(style = 'candlestick')  # 绘图

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

Python量化交易学习笔记(20)——保护点卖出策略相关推荐

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

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

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

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

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

    好友提出要验证连续下跌买入止盈止损卖出策略,本文对该策略回测和实现做分析记录. 买入条件中,连续下跌定义为收盘价连续4日低于前1日的收盘价.卖出条件中,止盈率设置为10%,止损率设置为5%.回测初始资 ...

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

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

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

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

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

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

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

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

  8. Python量化交易学习笔记(21)——A股股票列表更新

    在zwPython2020中,股票数据下载更新时,所读取的股票列表文件的目录位置为"zwPython\TQDat\TQDown2020v1\data\tq_wrk_code.csv" ...

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

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

最新文章

  1. 004_Vue按键修饰符
  2. Docker知识2:安装docker-desktop
  3. How to get information of all attachments belonging to a given appointment
  4. ospf协议_三级网络技术考前选择题3—OSPF协议
  5. html5标签详解,HTML5中figcaption标签用法详解
  6. Linux编程 3 (初识bash shell与man查看手册)
  7. 深度学习基础(二)激活函数
  8. 安卓开发入门到精通!免费Android高级工程师学习资源,系列篇
  9. linux tcb,在Linux中从潜藏密码迁移至tcb怎么做?
  10. 大厂产品经理是如何做好用数据驱动业务增长的?
  11. 【操作系统】SPOOLing技术(外部设备联机并行操作/假脱机技术)
  12. wenbao与cf整数直角三角形
  13. [操作系统]Nachos4.1安装教程(docker+linux)
  14. 【教程】美团联盟个人怎么注册推广做外卖cps红包
  15. 经济筑底要看房市“脸色”
  16. 【初级班】517编程普及组 第一课 循环经典问题
  17. Git如何生成SSH密钥
  18. ubuntu系统(二):ibus拼音将繁体中文改为简体中文
  19. 【 史上最全】测绘、遥感RS、地信GIS国家级比赛竞赛整理
  20. RIO10数据集下载链接提取

热门文章

  1. java中如何gzip_Java如何压缩Gzip格式的文件?
  2. B_随笔_关于网站记录(3)
  3. SAP EWM 与 WM 比较
  4. 国际博物馆日,百度超级链多款上新数字藏品
  5. assert函数--判断表达式是否正确
  6. Zabbix5.0版本 全网监控方案
  7. uniapp ios内购支付问题(返回订单信息失败)
  8. 文件/图片的上传 怎么做
  9. java查看gc日志_GC日志查看
  10. 国家反诈中心APP为什么这么火?这些超牛功能赶快下载使用