本文将继续对backtrader的order进行介绍,具体介绍Stop订单的使用。
选取平安银行(000001)2019年1月1日至2019年12月31日的日线数据进行回测。为了便于分析,回测过程中设置佣金为0,交易单位大小为100。
执行规则
在Stop订单创建时,会设置一个price和valid时间,如果超过valid时间订单仍未满足执行条件,订单就会过期被取消。在valid时间内,订单会按照下面描述的价格匹配规则判断订单是否会成交。
价格匹配
Stop订单使用K线4个价格点(Open/High/Low/Close)来判断是否有效突破设定的price值。
- 对于买单
- 如果某根K线的open高于设定的price,则立刻以open值成交。对于空头来说,若已持有做空的仓位,价格较设定的price持续走高,这时要及时平仓止损(stop a loss),因此这类订单成为Stop订单。
- 如果某根K线的open低于设定的price,但是high高于price,也就是price在这根K线的范围内,那么订单将以price值成交。
- 对于卖单
- 如果某根K线的open值低于设定的price,则以open值成交。
- 如果某根K线的open值高于设定的price,但是low低于price,也就是price在这根K线的范围内,那么订单将以price值成交。
示例
策略:
- 买入条件:收盘价高于15日均线,价格在4日内,较收盘价向上突破0.5%时买入
- 卖出条件:收盘价低于15日均线,价格在4日内,较收盘价向下跌破0.5%时卖出
# 检查是否持仓
if self.position:
# 检查是否达到卖出条件
if self.buysell < 0:
if self.p.valid:
valid = self.data.datetime.date(0) + \
datetime.timedelta(days=self.p.valid)
else:
valid = None
...
elif self.p.exectype == 'Stop':
price = self.data.close * (1.0 - self.p.perc1 / 100.0)
self.sell(exectype=bt.Order.Stop, price=price, valid=valid)
if self.p.valid:
txt = 'SELL CREATE, exectype Stop, close %.2f, price %.2f, valid: %s'
self.log(txt % (self.data.close[0], price, valid.strftime('%Y-%m-%d')))
else:
txt = 'SELL CREATE, exectype Stop, close %.2f, price %.2f'
self.log(txt % (self.data.close[0], price))
...
# 不在场内且出现买入信号
elif self.buysell > 0:
if self.p.valid:
valid = self.data.datetime.date(0) + \
datetime.timedelta(days=self.p.valid)
else:
valid = None
...
elif self.p.exectype == 'Stop':
price = self.data.close * (1.0 + self.p.perc1 / 100.0)
self.buy(exectype=bt.Order.Stop, price=price, valid=valid)
if self.p.valid:
txt = 'BUY CREATE, exectype Stop, close %.2f, price %.2f, valid: %s'
self.log(txt % (self.data.close[0], price, valid.strftime('%Y-%m-%d')))
else:
txt = 'BUY CREATE, exectype Stop, close %.2f, price %.2f'
self.log(txt % (self.data.close[0], price))
为了说明Stop订单可能出现的所有成交情况,在代码中使用p.perc1 = 0.5,来控制价格突破的比例,使用p.valid = 4,来控制订单的有效期。
先来分析买单的3种情况:
1. 过期取消
将图表显示时间范围调整为2019年3月,输出图形如下:
上图中,红色的曲线表示15日均线。
部分输出结果为:
2019-03-18, BUY CREATE, exectype Stop, close 12.91, price 12.97, valid: 2019-03-22
2019-03-19, ORDER SUBMITTED
2019-03-19, ORDER ACCEPTED
2019-03-19, Open: 12.92, High: 12.94, Low: 12.61, Close: 12.79
2019-03-20, Open: 12.68, High: 12.88, Low: 12.62, Close: 12.75
2019-03-21, Open: 12.77, High: 12.80, Low: 12.58, Close: 12.69
2019-03-22, Open: 12.69, High: 12.74, Low: 12.50, Close: 12.59
2019-03-22, BUY EXPIRED
下面结合输出打印结果及图形进行分析。
(1) 3月18日,收盘价高于15日均线,达到了买入条件,创建Stop买单,当日收盘价为12.91,设定上涨突破0.5%后的价位为12.97,p.valid = 4,有效期valid至3月22日。若在截止日期前价位能够达到price值12.97,订单就会成交,否则订单就会过期。
(2) 3月19日,收到买单提交通知。(18日创建的订单,在19日收到订单状态通知,是因为notify_order方法会在Strategy的next方法前被调用,即在18日的next方法中创建了买单,在19日的notify_order方法中通知订单被提交、接受。)
(3) 3月19日,收到买单接受通知。
(4) 3月19日,最低价12.61,最高价12.94,未达到设定price值12.97,因此订单未成交。
(5) 3月20日,最低价12.62,最高价12.88,未达到设定price值12.97,因此订单未成交。
(6) 3月21日,最低价12.58,最高价12.80,未达到设定price值12.97,因此订单未成交。
(7) 3月22日,最低价12.50,最高价12.74,未达到设定price值12.97,因此订单未成交。
(8) 3月22日,收到订单过期通知。3月22日为Stop订单设定的截止日期valid,订单未成交并过期。
2. 以开盘价成交
将图表显示时间范围调整为2019年9月,输出图形如下:
部分输出结果为:
2019-09-05, BUY CREATE, exectype Stop, close 14.58, price 14.65, valid: 2019-09-09
2019-09-06, ORDER SUBMITTED
2019-09-06, ORDER ACCEPTED
2019-09-06, Open: 14.71, High: 14.81, Low: 14.62, Close: 14.81
2019-09-06, BUY EXECUTED, Price: 14.71, Cost: 1471.00.
下面结合输出打印结果及图形进行分析。
(1) 9月5日,收盘价高于15日均线,达到了买入条件,创建Stop买单,当日收盘价为14.58,设定上涨突破0.5%后的价位为14.65,p.valid = 4,有效期valid至9月9日。若在截止日期前价位能够达到price值14.65,订单就会成交,否则订单就会过期。
(2) 9月6日,收到买单提交通知。
(3) 9月6日,收到买单接受通知。
(4) 9月6日,开盘价为14.71,高于了设定price值14.65,满足了买单价格匹配的规则1,将以开盘价成交。
(5) 9月6日,Stop买单以开盘价14.71成交。
3. 以设定的price成交
将图表显示时间范围调整为2019年6月,输出图形如下:
部分输出结果为:
2019-06-10, BUY CREATE, exectype Stop, close 12.34, price 12.40, valid: 2019-06-14
2019-06-11, ORDER SUBMITTED
2019-06-11, ORDER ACCEPTED
2019-06-11, Open: 12.34, High: 12.72, Low: 12.30, Close: 12.65
2019-06-11, BUY EXECUTED, Price: 12.40, Cost: 1240.17.
下面结合输出打印结果及图形进行分析。
(1) 6月10日,收盘价高于15日均线,达到了买入条件,创建Stop买单,当日收盘价为12.34,设定上涨突破0.5%后的价位为12.40,p.valid = 4,有效期valid至6月14日。若在截止日期前价位能够达到price值12.40,订单就会成交,否则订单就会过期。
(2) 6月11日,收到买单提交通知。
(3) 6月11日,收到买单接受通知。
(4) 6月11日,开盘价为12.34,低于设定的price值12.40,不满足买单价格匹配的规则1;但是最高价为12.72,高于设定的price值12.40,满足买单价格匹配的规则2,因此将以设定的price值成交。
(5) 6月11日,Stop买单以设定的price值12.40成交。
再来分析卖单的3种情况:
1. 过期取消
将图表显示时间范围调整为2019年9月,输出图形如下:
部分输出结果为:
2019-09-17, SELL CREATE, exectype Stop, close 14.24, price 14.17, valid: 2019-09-21
2019-09-18, ORDER SUBMITTED
2019-09-18, ORDER ACCEPTED
2019-09-18, Open: 14.24, High: 14.48, Low: 14.24, Close: 14.41
2019-09-19, Open: 14.48, High: 14.89, Low: 14.48, Close: 14.84
2019-09-20, Open: 14.95, High: 15.40, Low: 14.93, Close: 15.34
2019-09-23, Open: 15.34, High: 15.47, Low: 15.18, Close: 15.38
2019-09-23, SELL EXPIRED
下面结合输出打印结果及图形进行分析。
(1) 9月17日,收盘价低于15日均线,达到了卖出条件,创建Stop卖单,当日收盘价为14.24,设定向下跌破0.5%后的价位为14.17,p.valid = 4,有效期valid至9月21日。若在截止日期前价位能够达到price值14.17,订单就会成交,否则订单就会过期。
(2) 9月18日,收到卖单提交通知。
(3) 9月18日,收到卖单接受通知。
(4) 9月18日,最低价14.24,最高价14.48,未达到设定price值14.17,因此订单未成交。
(5) 9月19日,最低价14.48,最高价14.89,未达到设定price值14.17,因此订单未成交。
(6) 9月20日,最低价14.93,最高价15.40,未达到设定price值14.17,因此订单未成交。
(7) 9月23日(21日和22日为周末),最低价15.18,最高价15.47,未达到设定price值14.17。
(8) 9月23日,收到订单过期通知。9月21日为Stop订单设定的截止日期valid,订单未成交并过期。经测试,这里即使23日的价格范围达到的设定price值14.17,订单也会过期。即,若截止日期当日未开市,则在后续开市日期内,即使满足了价格匹配规则,订单也会过期失效。
2. 以开盘价成交
将图表显示时间范围调整为2019年8月,输出图形如下:
部分输出结果为:
2019-08-02, SELL CREATE, exectype Stop, close 13.74, price 13.67, valid: 2019-08-06
2019-08-05, ORDER SUBMITTED
2019-08-05, ORDER ACCEPTED
2019-08-05, Open: 13.60, High: 13.64, Low: 13.27, Close: 13.35
2019-08-05, SELL EXECUTED, Price: 13.60, Cost: 1394.94.
下面结合输出打印结果及图形进行分析。
(1) 8月2日,收盘价低于15日均线,达到了卖出条件,创建Stop卖单,当日收盘价为13.74,设定向下跌破0.5%后的价位为13.67,p.valid = 4,有效期valid至8月6日。若在截止日期前价位能够达到price值13.67,订单就会成交,否则订单就会过期。
(2) 8月5日(3日和4日为周末),收到卖单提交通知。
(3) 8月5日,收到卖单接受通知。
(4) 8月5日,开盘价为13.60,低于了设定price值13.67,满足了卖单价格匹配的规则1,将以开盘价成交。
(5) 8月5日,Stop卖单以开盘价13.60成交。
3. 以设定的price成交
将图表显示时间范围调整为2019年7月,输出图形如下:
部分输出结果为:
2019-07-08, SELL CREATE, exectype Stop, close 13.59, price 13.52, valid: 2019-07-12
2019-07-09, ORDER SUBMITTED
2019-07-09, ORDER ACCEPTED
2019-07-09, Open: 13.63, High: 13.71, Low: 13.44, Close: 13.59
2019-07-09, SELL EXECUTED, Price: 13.52, Cost: 1240.17.
下面结合输出打印结果及图形进行分析。
(1) 7月8日,收盘价低于15日均线,达到了卖出条件,创建Stop卖单,当日收盘价为13.59,设定向下跌破0.5%后的价位为13.52,p.valid = 4,有效期valid至7月12日。若在截止日期前价位能够达到price值13.52,订单就会成交,否则订单就会过期。
(2) 7月9日,收到卖单提交通知。
(3) 7月9日,收到卖单接受通知。
(4) 7月9日,开盘价为13.63,高于设定的price值13.52,不满足卖单价格匹配的规则1;但是最低价为13.44,低于设定的price值13.52,满足卖单价格匹配的规则2,因此将以设定的price值成交。
(5) 7月9日,Stop卖单以设定的price值13.52成交。
至此,通过示例展示了Stop订单所有可能出现的情况。
Stop订单的用法可以总结为:突破关键点开仓,跌破关键点平仓。
博客内容只用于交流学习,不构成投资建议,盈亏自负!
个人博客:http://coderx.com.cn/(优先更新)
项目最新代码:https://gitee.com/sl/quant_from_scratch
欢迎大家转发、留言。有微信群用于学习交流,感兴趣的读者请扫码加微信!
如果认为博客对您有帮助,可以扫码进行捐赠,感谢!
微信二维码 | 微信捐赠二维码 |
---|---|