Python量化交易学习笔记(26)——backtrader的order概述

在现实交易中,策略复杂多样。在backtrader中进行回测时,除了自定义Strategy子类以外,还可以通过各种order来辅助实现交易策略。

order在backtrader中的作用

在backtrader中,Cerebro是系统的控制核心,Strategy是用户的可操控点,还需要一个将Strategy与系统其它部分相连接的角色,有了这个角色就可以将用户自定义的Strategy的信息传递给系统的其它部分,让系统按用户的需要运转起来,这个角色的扮演者就是order

也就是说:order是连接用户自定义Strategy与backtrader系统其它部分的桥梁,让backtrader可以按照用户的想法运行(回测或者交易)。

这种桥梁作用是通过下面的方式来实现:

1. order将策略Strategy逻辑所做出的决定,翻译为代理Broker所能理解的信息,Broker最终来执行具体的交易操作。 具体的操作包括:

  • 订单创建
    通过调用Strategybuy()、sell()、close()方法来返回订单实例。

  • 订单取消
    通过调用Strategycancel(order)方法来取消订单。

2. order将Broker执行交易的信息反馈给用户。 具体方式为:

  • 订单通知
    通过调用Strategynotify_order(order)方法来通知order的状态。

订单创建

上面提到,可以通过buy()、sell()、close()方法来创建订单,这里介绍一下这些方法可能使用到的参数。参数的不同选择,会使订单的交易行为截然不同。因此为了全面了解order的作用,有必要过一遍这些参数:

  • data(默认值:None)
    order所要操作的数据。如果为None,则系统中的第一组数据(第一只股票/品种)将被使用,也就是self.datas[0]、self.data0、self.data,上面3种形式均可以表示系统中的第一组数据。

  • size(默认值:None)
    交易单位size是一个正数。对于买单,如果size=100,就是买100个单位数量的仓位;对于卖单,如果size=100,就是卖100个单位数量的仓位。
    如果size=None,sizer实例就会通过getsizer方法来获取size的值。也就是说,除了使用buysell方法来设置单个订单的交易单位大小,还有方法设置全局交易单位的大小(通过Cerebro.addsizer方法来设置),这样就避免了每个order都要设置交易单位。

  • price(默认值:None)
    交易价格。
    默认值None适用于Market、Close订单(后面的exectype参数会介绍各类型订单的意义),由市场决定具体的交易价格。
    对于Limit、Stop、StopLimit订单,必须显式给price赋值,price值决定了交易的触发点(trigger point)。
    对于StopTrail、StopTrailLimit订单,是否显示设置price,将决定不同的交易触发点。(后续文章将详细介绍)

  • plimit(默认值:None)
    只适用于StopLimit订单。在StopLimit订单中,plimit值被设置为隐含的Limit订单price值,而price值被用于触发当前StopLimit订单的Stop条件。(后续文章将详细介绍)

  • exectype(默认值:None)
    可能的取值:

    • Order.Market或者None:Market订单将以下一个可行的价格进行交易,在回测中,就将以下一根K线的开盘价进行交易。
    • Order.Limit:在给定的价位price或者更好的价位执行的订单。
    • Order.Stop:当价格突破price时,触发订单成交。
    • Order.StopLimit:当价格突破price时触发订单(类似于Order.Stop订单),之后以给定的价位plimit或者更好的价位执行订单(相当于以参数plimitpriceOrder.Limit订单)。
    • Order.StopTrail:根据收盘价的变化,动态调整订单的交易价格,以实现利润的保护。
    • Order.StopTrailLimitOrder.StopTrailOrder.Limit的组合,按照Order.StopTrail条件触发,按照Order.Limit条件成交。
    • Order.Historical:尚未发现相关说明及应用。
  • valid(默认值:None)
    可能的取值:

    • None。生成的订单将不会过期,将一直在市场中等待满足条件后执行或者等待被手动取消。
    • datetime.datetime或者datetime.date的实例。这个日期将被用来创建这样一个订单,如果截止到该给定的日期,该订单仍未满足执行条件,那么这个订单就会过期而取消。
    • Order.DAY或者timedelta()。生成一个单日订单,有效期为1天,单日未满足执行条件,订单就会过期取消。
    • numeric value。对应于matplotlib中的日期格式,将被用来创建订单,订单有效期截止日为该日期。
  • tradeid(默认值:0)
    这是backtrader应用的一个内部值,用于跟踪相同资产上的重叠交易。当通知订单状态的变化时,此tradeid被发送回策略。

  • ∗ ∗ ** kwargs
    其他代理的实现可能支持额外的参数。backtrader将kwarg向下传递到创建的order对象。

close方法将首先检查当前的持仓情况,然后根据持仓情况对应地使用buy或者sell方法来清空仓位。如果用户不指定具体的size值,size会被自动计算。如果指定了size值,那么将实现部分close或者reversal订单。

订单通知

为了收到订单通知,需要在用户自定义的Strategy子类中,重写notify_order方法,该方法默认为空。notify_order方法将会被以如下方式使用:

  • notify_order方法会在Strategy的next方法前被调用
  • 在同一个next周期内,同一个order的通知,可以以相同或者不同的状态在notify_order方法中出现多次。
    例如:一个订单先被提交给代理,然后立即被代理接受,且已经满足了执行的条件,它的执行就会在下一个next方法被调用前就已经完成。在这个例子中,至少有以下3个状态通知产生:
    • Order.Submitted:产生于订单提交给代理
    • Order.Accepted:产生于代理接受订单,等待被执行
    • Order.Completed:产生于订单满足了执行条件,被立即执行完成

在实盘交易中,对于订单状态同为Order.Partial的通知可能会出现多次,因为实盘中订单可能会被拆分为多笔交易被执行完成。而在回测中,由于不考虑成交量的匹配,所以不会出现这种情况。

被执行的订单数据被记录在属性order.executed中,它是一个类型为OrderData的实例,包含sizeprice字段。

订单创建时的数据被记录在order.created中,这些数据在order的整个生命周期中保持不变。

订单状态值

  • Order.Createdorder实例被创建后的状态。当使用buysellclose创建订单时,该状态对用户不可见,需要手动创建order的实例,才能获取到该状态。
  • Order.Submitted:当order实例被发送给broker后的状态。在回测模式下,订单发送是一个即时动作,不需要花费时间。而在实盘中,订单发送将要实际花费时间,代理收到订单后,将订单转发给交易所,随即通知订单已提交。
  • Order.Accepted:当order处于该状态时,该order已经在系统或者交易所中等待被执行,会根据设置的exectypesizepricevalid等参数确定何时被执行。
  • Order.Partialorder部分成交时的状态。order.executed属性里记录了已经成交的size及平均价格。order.executed.exbits里包含了分批成交的详细情况完整列表。
  • Order.Completeorder全部成交的状态(平均成交价格被计算并记录下来)。
  • Order.Rejectedorderbroker拒绝的状态。如果某个参数不被broker所接受,那么order也将不被broker接受。订单被拒的原因将通过Strategynotify_store方法通知用户。该状态对于回测代理不可见。
  • Order.Margin:资金不足,订单无法成交,之前接受的订单会被从系统中删除。
  • Order.Cancelled(或者Order.Canceled): 对用户订单取消要求的确认。用户通过Strategycancel方法提交取消订单申请,可能无法成功地取消订单。订单可能已经成交,但是代理尚未反馈成交结果,或者成交通知还没有发送到Strategy。因此需要Order.Canncelled对是否成功取消订单进行确认。
  • Order.Expired:在该状态下,之前被提交的包含有效时间的订单已经过期,订单被从系统中删除。

order类型

翻看backtrader源代码,在order.py中可以看到ExecTypes列表共有8种不同类型的订单,即按照执行类型,可以分为以下8种:

    ExecTypes = ['Market', 'Close', 'Limit', 'Stop', 'StopLimit', 'StopTrail',
                 'StopTrailLimit', 'Historical']

各种执行类型的简单说明可以参见上文中exectype参数描述部分,后续文章将进行详细描述。

order成交原则

在backtrader中,代理(broker)使用以下2个原则来进行订单交易:

1. 当前数据已经产生,不能被用于执行交易。

例如,Strategy的逻辑如下:

 if self.data.close > self.sma:  # sma表示简单移动平均线
     self.buy()

在这个逻辑中,将收盘价close与移动平均线做比较,如果满足条件,就下买单。但是买单是无法用close进行交易的,因为close是已经产生的数据。只能用下一根K线的某个价位成交,成交价格取决于order类型。

订单的首个可交易的时间在下一根K线上。

2. 成交量在交易中不发挥作用

在实际交易中,成交量是会影响交易的。如果交易员是在进行非流动资产的买卖,或者是在K线的极端点(最高点或者最低点)进行的交易,成交量将影响实盘交易。

但是触及最高点/最低点是很少发生的(A股例外,有涨跌停。。。),所选资产将有足够的流动性来吸收任何常规交易的指令。因此backtrader假设成交量在交易中不发挥作用。

PS:原计划用1篇文章记录backtrader的order,写着写着发现需要5篇左右文章才能进行完整的描述。只有慢慢来了,力争把所有的知识点掰开了、揉碎了再呈现出来:)

为了便于相互交流学习,新建了微信群,感兴趣的读者请加微信。
在这里插入图片描述

Guess you like

Origin blog.csdn.net/m0_46603114/article/details/106031259