从本文开始,将结合实例陆续对backtrader的各个类型的订单进行介绍,本文将首先介绍Market和Close订单。 选取平安银行(000001)2019年1月1日至2019年12月31日的日线数据进行回测。为了便于分析,回测过程中设置佣金为0,交易单位大小为100。
Market- 执行规则:以下一根K线的开盘价执行订单。
- 原理:假设在某一时刻满足了交易的条件,这时生成一个Market订单,如果想成交这一订单,就需要下一个将要出现价格点位,这个点位就是下一根K线的开盘价(open)。
对于Market订单,参数price和valid将被忽略。 - 买入条件:收盘价高于15日均线
- 卖出条件:收盘价低于15日均线
# 检查是否持仓 if self. position: # 检查是否达到卖出条件 if self. buysell < 0: ... if self. p. exectype == 'Market': self. sell( exectype = bt. Order. Market) self. log( 'SELL CREATE, exectype Market, close %.2f' % self. data. close[ 0]) ... # 不在场内且出现买入信号 elif self. buysell > 0: ... if self. p. exectype == 'Market': self. buy( exectype=bt. Order. Market) # Market是默认的订单类型 self. log( 'BUY CREATE, exectype Market, close %.2f' % self. data. close[ 0]) - 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
将图表显示时间范围调整为2019年3月,输出图形如下: 
上图中,红色的曲线表示15日均线,绿色的三角形表示买入,红色的三角形表示卖出。 部分输出结果为: 2019-03-18, BUY CREATE, exectype Market, close 12.91 2019-03-19, ORDER SUBMITTED 2019-03-19, ORDER ACCEPTED 2019-03-19, BUY EXECUTED, Price: 12.92, Cost: 1292.00. 2019-03-19, Open: 12.92, High: 12.94, Low: 12.61, Close: 12.79 2019-03-22, SELL CREATE, exectype Market, close 12.59 2019-03-25, ORDER SUBMITTED 2019-03-25, ORDER ACCEPTED 2019-03-25, SELL EXECUTED, Price: 12.40, Cost: 1292.00. 2019-03-25, Open: 12.40, High: 12.40, Low: 12.10, Close: 12.11 下面结合输出打印结果及图形,对Market订单进行分析。 - 3月18日,收盘价高于15日均线,达到了买入条件,创建买单。
- 3月19日,收到买单提交通知。(18日创建的订单,在19日收到订单状态通知,也验证了上一篇文章中提到的:notify_order方法会在Strategy的next方法前被调用,即在18日的next方法中创建了买单,在19日的notify_order方法中通知订单被提交、接受、执行。)
- 3月19日,收到买单接受通知。
- 3月19日,买单被执行,执行价格为12.92,与3月19日的开盘价相同。(Market订单以一根K线的开盘价成交,即18日达到买入条件创建了订单,会以19日的开盘价成交。)
- 3月22日,收盘价跌破15日均线,达到了卖出条件,创建卖单。
- 3月25日(23日及24日为周末),收到卖单提交通知。(notify_order方法会在Strategy的next方法前被调用。)
- 3月25日,收到卖单提交通知。
- 3月25日,卖单被执行,执行价格为12.40,与3月25日开盘价相同。(Market订单以一根K线的开盘价成交。)
小结:Market订单以下一根K线的开盘价成交。
Close
执行规则:当下一根K线结束时,以下一根K线的收盘价执行订单。
原理:以日线回测为例,它包含了已经结束的日K数据,在满足交易条件后,订单将以下一根K线的收盘价(close)立即成交。大多数回测数据属于这种情况,但是也有例外的情况,比如分时数据。在下一个分时K线产生之前,当前的分时K线由于分时时段未结束,数据会保持不断的更新。在这种情况下,只有当前分时时段结束,该分时K线不再变化,才会以收盘价进行交易。
示例: 策略:(与上面Market订单相同) - 买入条件:收盘价高于15日均线
- 卖出条件:收盘价低于15日均线
# 检查是否持仓 if self. position: # 检查是否达到卖出条件 if self. buysell < 0: ... elif self. p. exectype == 'Close': self. sell( exectype = bt. Order. Close) self. log( 'SELL CREATE, exectype Close, close %.2f' % self. data. close[ 0]) ... # 不在场内且出现买入信号 elif self. buysell > 0: ... elif self. p. exectype == 'Close': self. buy( exectype=bt. Order. Close) self. log( 'BUY CREATE, exectype Close, close %.2f' % self. data. close[ 0]) - 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
输出图形与Market订单相同: 
部分输出结果为: 2019-03-18, BUY CREATE, exectype Close, close 12.91 2019-03-19, ORDER SUBMITTED 2019-03-19, ORDER ACCEPTED 2019-03-19, BUY EXECUTED, Price: 12.79, Cost: 1279.00. 2019-03-19, Open: 12.92, High: 12.94, Low: 12.61, Close: 12.79 2019-03-22, SELL CREATE, exectype Close, close 12.59 2019-03-25, ORDER SUBMITTED 2019-03-25, ORDER ACCEPTED 2019-03-25, SELL EXECUTED, Price: 12.11, Cost: 1279.00. 2019-03-25, Open: 12.40, High: 12.40, Low: 12.10, Close: 12.11 下面结合输出打印结果及图形,对Close订单进行分析。 - 3月18日,收盘价高于15日均线,达到了买入条件,创建买单。
- 3月19日,收到买单提交通知。(18日创建的订单,在19日收到订单状态通知,也验证了上一篇文章中提到的:notify_order方法会在Strategy的next方法前被调用,即在18日的next方法中创建了买单,在19日的notify_order方法中通知订单被提交、接受、执行。)
- 3月19日,收到买单接受通知。
- 3月19日,买单被执行,执行价格为12.79,与3月19日的收盘价相同。(Close订单以一根K线的收盘价成交,即18日达到买入条件创建了订单,会以19日的收盘价成交。)
- 3月22日,收盘价跌破15日均线,达到了卖出条件,创建卖单。
- 3月25日(23日及24日为周末),收到卖单提交通知。(notify_order方法会在Strategy的next方法前被调用。)
- 3月25日,收到卖单提交通知。
- 3月25日,卖单被执行,执行价格为12.11,与3月25日收盘价相同。(Close订单以一根K线的收盘价成交。)
小结:Close订单与Market订单逻辑基本相同,不同之处为,Close订单以下一根K线的收盘价成交,而Market订单以下一根K线的开盘价成交。
|