第十五章:委托单发单机制
委托单发达机制内容是最难的,也是最难测试的,主要牵扯到this bar与 next bar,market、limit单等、bar内交易与非bar内交易内容。
1. 委托单条件判断和委托单触发
这里首先我们需要理解两个概念,一个是“委托单条件判断”,另一个是“委托单触发”,这两个概念会贯穿这部分的内容,我们先来看一下代码例子,如下:
if condition1 then buy next bar at market;
条件condition1是next bar委托语句的判断条件,当条件condition1成立时,还需要等待下一笔tick的触发,才能将买入市价单发送出去;也就是说买入市价单是否能发送到交易所,涉及两个步骤,缺一不可:
那就是首先信号脚本执行计算必须进行“委托单条件判断”这个步骤,并且条件成立,然后需要“委托单触发”这个步骤,才可以将next bar的委托单发送到交易所;这里只是通过一个简单的例子来阐述这两个概念,那么对于“委托单条件判断”和“委托单触发”就光这两个步骤在非bar内模式、bar内模式、bar外模式、信号脚本不同的计算驱动因素会表现的不一样。
【备注】:“委托单条件判断”和“委托单触发”,就是在前面的“理想的limit限价单发单模式”中的“条件不变”,“条件不变” = “委托单条件判断”(不变) and “委托单触发”(不变)= “不会撤单,不会撤单再重新发单”
This bar和next bar主要有两点区别:
一个区别就是,this和next的区别,这正如它们的名称一样,next bar委托单需要经过两个步骤才能发送到交易所,也就是上面说到的两个步骤,而this bar委托单只需要一个步骤,也可以说“委托单条件判断”和“委托单触发”两个步骤对于this bar委托单来说是一个步骤,“委托单条件判断”的同时,若条件成立就“委托单触发”立即发送到交易所;
另一个区别是,next bar有bar内模式、bar外模式,也就是说,next bar委托单可以基于bar的开盘状态、bar内状态、收盘状态、bar外状态进行“委托单条件判断”,基于bar的开盘状态、bar内状态、收盘状态、bar外状态进行“委托单触发”,而this bar只能基于收盘状态进行“委托单条件判断”和“委托单触发”。所以,在总体上this bar的使用是受限制的,不如next bar的使用功能丰富,但是从速度上说,this bar更快;若您对this bar和next bar的区别没有掌握或者说您没有完全掌握这篇帖子,那么建议您不要使用this bar委托语句。在本文的后面不再对this bar进行阐述,请参考next bar的阐述进行理解this bar的功能。
2. 自动交易进行中
这里要区分一个两个标题,“自动交易进行中”和“开启自动交易的瞬间”,这是因为next bar委托单需要两个步骤,当这两个步骤都发生在自动交易进行中的时候,就是“自动交易进行中”所要阐述的内容;当“委托单条件判断”这个步骤在开启自动交易之前,而“委托单触发”这个步骤发生在开启自动交易之后,就是“开启自动交易的瞬间”这个标题所要阐述的内容了。之所以这样分开,有两个考虑,一个是这两种情况下,next bar委托单表现的不一样,另一个是实盘有些技巧也是需要这部分内容的。
2.1 未开启bar内模式
未开启bar内模式,也就是非bar内模式;
非bar内模式与bar内模式的一个区别,就是非bar内模式下“委托单条件判断”这个步骤只能基于开盘状态或者收盘状态进行执行,而bar内模式下“委托单条件判断”这个步骤可以基于开盘状态、收盘状态、bar内状态进行执行,这个区别也正如它们的名称一样,前者是“bar外”,后者是“bar内”;
当然非bar内模式和bar内模式下,“委托单触发”这个步骤都可以基于开盘状态、收盘状态、bar内状态进行执行,而不能基于bar外状态进行执行。
Bar外模式下,这两个步骤都可以基于bar的开盘状态、bar内状态、bar的收盘状态、bar外状态进行执行,是否基于bar外状态进行这两个步骤的执行,是bar外模式与非bar内模式、bar内模式的区别。我们前面说过,bar有4个状态,bar的开盘状态、bar的收盘状态、bar内状态、bar外状态,这里为了下面的叙述严谨,我两次强调一点,bar的开盘状态是以接收到开盘tick为基准,而且这只是一个瞬间,并不是一个持续的状态;bar的收盘状态是以接收到收盘tick为基准,这也只是一个瞬间 ,并不是一个持续的状态;
bar内状态,是指在当根bar开盘之后并且在当根bar收盘之前,这个期间信号脚本执行的计算(对计算的驱动因素不限制);
bar外状态,是指在当根bar收盘之后并且在下一根bar开盘之前,这个期间信号脚本执行的计算(对计算的驱动因素不限制);
而信号脚本执行的计算,上面我们已经叙述了所有的信号脚本的计算驱动因素了。
在非bar内模式下,信号脚本基于收盘tick执行一次计算,这里计算执行的是“委托单条件判断”这个步骤,然后下一根bar的开盘tick执行“委托单触发”这个步骤,也许您可能会说,收盘状态之后并且在开盘状态之前,这中间还有bar外状态,那么bar外状态(也就是信号脚本在当根bar收盘之后,并且下一根bar开盘之前,这个期间信号脚本执行计算)是否可以执行“委托单触发”这个步骤,答案是不行,也就是bar外状态不会影响非bar内模式下委托单的两个步骤。在非bar内模式下,若信号脚本基于开盘tick执行计算(信号脚本中引用了下一根bar的数据,上文有说过),这时计算执行的是“委托单条件判断”这个步骤,因为开盘状态之后,只有两种可能的状态,即bar内状态和收盘状态,当然这两种状态都可以执行“委托单触发”这个步骤的执行,下面举例说明一下(这里最大bar设置为0)。
//信号代码 [ProcessMouseEvents=true] value1=getappinfo(aicalcreason); open next bar; if currentbar=605 then buy next bar at market; print("currentbar=",currentbar,",time=",time,",barstatus=",barstatus,",value1=",value1); //部分输出 currentbar= 600.00,time=1427.00,barstatus= 0.00,value1= 0.00 currentbar= 601.00,time=1437.00,barstatus= 0.00,value1= 0.00 currentbar= 602.00,time=1500.00,barstatus= 0.00,value1= 0.00 currentbar= 603.00,time=1501.00,barstatus= 0.00,value1= 0.00 currentbar= 604.00,time=1504.00,barstatus= 0.00,value1= 0.00
最大bar设置为0,此时bar的绝对编号等于相对编号,图表中最后一根bar的编号为605,而公式编译器中输出栏位中最后一根bar的编号是604,这里需要简单解释一下,信号脚本基于开盘tick执行计算,是指当接收到下一根bar的开盘tick时,信号脚本会基于当根bar执行计算信号脚本中的关键字currentbar、close等返回的信息都是当根bar的信息,而不是下一根bar的信息;在非bar内模式下,基于下一根bar开盘tick的计算,除了Open next bar、Date next bar、Time next bar、DateTime next bar、Time_s next bar返回的是下一根bar的信息(这5个关键字的信息可以通过下一根bar的第一笔tick直接可以获取到),其它关键字(例如,currentbar、close等等)返回的都是当根bar的信息。
这是一个非常不活跃的商品品种,图表上现在是15:05分,当编号为606的bar的开盘tick接收的时候(假设是在15:09:30时,当根bar的收盘时间为15:10分),信号脚本会执行一次,此时信号脚本中关键字currentbar返回的是605,那么“委托单条件判断”这个步骤被执行了;接下来,我们会采用几种可能的措施,以此来阐述不同的效果:
l 若在15:15分之前,没有接收到tick数据,因为我们在信号脚本中使用了语句[ProcessMouseEvents=true],所以当我们在图表上点击一下鼠标时,信号脚本会执行一次计算,也就是在编号为606的bar收盘之前执行一次计算,于是bar内状态执行了“委托单触发”这个动作,委托单被触发发送到交易所。
l 若在15:15分之前,没有执行鼠标点击动作,但是在15:09:50时接收到一笔tick,尽管信号脚本不会基于该笔bar内tick执行计算,但是仍然是bar内状态,即bar内状态执行了“委托单触发”这个动作,委托单被触发发送到交易所。
l 若在15:15分之前,没有执行鼠标点击动作,也没有接收到交易所的tick,底层产生一笔收盘tick,尽管信号脚本也不会执行计算,但是bar的收盘状态执行了“委托单触发”这个动作,委托单被发送到交易所了。
2.2 开启bar内模式
开启bar内模式,也就是信号代码中使用语句[IntrabarOrderGeneration=true],在bar内模式下,信号脚本的计算是每接收到一笔tick信号脚本都会执行一次计算(开盘tick、bar内tick、收盘tick),当然也可以使用上文中叙述的其它的计算驱动因素。对于委托单的两个步骤,用一句话来概括就是:信号脚本基于bar的开盘状态、收盘状态、bar内状态进行“委托单条件判断”,紧接着基于开盘状态、收盘状态、bar内状态进行“委托单触发”这个步骤。这个部分我不准备对于这一句话概括进行举例,因为很好理解,但是需要举例说明一下一直困扰和模糊的一个说法:条件单,条件满足就发单,条件不满足就撤单,价格变化就重发。下面的例子为叙述简单起见,除了tick行情驱动的信号脚本计算,不考虑其它计算的驱动因素
案例1:
//信号代码 [intrabarordergeneration=true] if time>=1400 and barstatus=0 then buy("first") next bar at close-10 limit; if time>=1400 then buy("second") next bar at close-20 limit;
假设当前bar的收盘时间为13:58,然后开启自动交易
l 接着在14:00:00时接收到收盘时间为1400的bar的开盘tick(即barstatus=0),开盘tick的价格是3710(假设商品合约是螺纹,周期为1分钟),信号脚本基于开盘tick执行计算,显然条件“time>=1400 and barstatus=0”是成立的,并且条件“time>=1400”也是成立的,也就是这两笔条件委托的“委托单条件判断”被执行了,并且都成立,就等待下一笔tick的触发
l 接着在14:00:30时接收到第一笔bar内tick(即barstatus=1),tick的价格是3700;经过前面的“委托单条件判断”这个步骤的执行,这笔bar内tick执行了“委托单触发”这个步骤,于是两个条件单都发送到交易所了;现在的问题是,两笔发送到交易所的价格分别是多少呢?
l 条件单的价格是在“委托单条件判断”这个步骤确定的,并不是在“委托单触发”这个步骤确定的,所以“first”条件单的限价是3710-10,即3700;“second”条件单的限价是3710-20,即3690
l 条件单的价格确定了,但是条件的问题又来了;因为14:00:30的这一笔tick的接收,导致信号脚本又执行一次计算,但是条件“time>=1400 and barstatus=0”不再成立,这样“first”委托单也会发送到交易所吗?答案是肯定的。但是信号仍然基于该笔tick执行了一次“委托单条件判断”这个步骤。
l 接着在14:00:50时接收到第二笔bar内tick(即barstatus=1),tick的价格是3670,此时这笔tick执行了“委托单触发”这个步骤,因为信号脚本基于上一笔tick(即14:00:30这笔tick)执行了“委托单条件判断)这个步骤,但是条件不再成交,所以这笔tick(即14:00:50这笔tick)触发了”first”条件单的撤单;另外,上一笔tick在执行“委托单条件判断”的同时也判断了条件单的价格的变化,所以这笔tick触发了条件单重发,也就是将”second”的条件单从交易所撤单,然后发送3700-10,即3680
l 通过上面的慢步骤的分析,进行小结一下:“委托单条件判断”这个步骤会判断委托单条件是否满足,以及确定条件单的价格,“委托单触发”这个步骤直接触发委托单;若条件满足,则第二个步骤触发之后,直接发送到交易所;若当前已经发送了条件单,当条件不再满足,则第二个步骤触发之后,将条件单撤单;若当前已经发送了条件单,当第一个步骤中确定价格变化了,则第二个步骤触发之后,将条件单撤单然后重发,重发的条件单的价格以第一个步骤中确定的价格为委托价格。
2.3 开启bar外模式
Bar外模式的开启,信号脚本中需要使用[AllowSendOrdersAlways=true],但是同时需要在信号脚本中使用[IntrabarOrderGeneration=true],也就是说bar外模式需要在开启bar内模式下才能开启。那么委托单的两个步骤在bar外模式下又是如何进行的呢?用一句话来概括就是:信号脚本中委托可以基于bar外状态进行“委托单条件判断”这个步骤,然后通过bar的开盘状态、收盘状态、bar内状态、bar外状态进行“委托单触发”这个步骤;
信号脚本中委托单基于bar的收盘状态进行“委托单条件判断”,委托单直接触发,也就是说在收盘状态“委托单条件判断”和“委托单触发”这两个步骤同时执行;
信号脚本中委托单基于bar的开盘状态、bar内状态进行“委托单条件判断”,然后通过bar内状态、bar的收盘状态进行“委托单触发”,不是两个步骤同时进行。
3. 开启自动交易的瞬间
3.1 未开启bar内模式
未开启bar内模式,基于收盘tick进行信号计算,假设图表周期为1分钟,前一根bar的收盘时间为13:30,当根bar的收盘时间为13:31(图表上最后一根bar,最新的bar),而且还没有走完(即barstatus=0或1),那么此时开启自动交易之后,条件单基于收盘时间为13:30的bar进行“委托单条件判断”,然后直接触发委托,也就是“委托单条件判断”和“委托单触发”这两个步骤同时进行,也就是开启自动交易之后条件单直接发送到交易所(但是市价单不会基于历史行情进行“委托单条件判断”,也不会基于历史行情进行“委托单触发”这两个步骤,市价单需要在开启自动交易之后执行“委托单条件判断”和“委托单触发”这两个步骤,请参考“自动交易进行中”这一节内容);
若当根bar(收盘时间为13:31)已经收盘,并且下一根bar还没有开盘,那些此时开启自动交易,条件单基于收盘时间为13:31的bar执行“委托单条件判断”,需要等到下一根bar第一笔tick(开盘tick)执行“委托单触发”这个步骤(市价单也会基于13:31的收盘bar执行“委托单条件判断”,需要等到下一根bar第一笔tick(开盘tick)执行“委托单触发”这个步骤)。
未开启bar内模式,基于下一根bar第一笔tick进行信号计算,当前bar的收盘时间为14:00(图表上最后一根bar,最新的bar),还没有收盘(即barstatus=0或1时),那么此时开启自动交易,条件单直接基于14:00的bar的开盘tick(即barstatus=0)进行“委托单条件判断”这个步骤,然后直接触发委托,也就是“委托单条件判断”和“委托单触发”这两个步骤同时进行,不需要等待最新的一笔tick的触发委托(市价单需要在开启自动交易之后进行“委托单条件判断”和“委托单触发”这个步骤,请参考“自动交易进行中”这一节);当前bar的收盘时间为14:00(图表上最后一根bar,最新的bar),已经收盘(即barstatus=2),并且还没有接收到下一根bar的开盘tick,那么此时开启自动交易,条件单需要等到下一根bar的开盘tick,基于下一根bar的barstatus=0进行“委托单条件判断”这个步骤,然后等待接下来bar内状态、bar的收盘状态、bar的开盘状态进行“委托单触发”这个步骤(市价单需要在开启自动交易之后,基于实时的开盘tick进行“委托单条件判断”,然后等待接下来bar内状态、bar的收盘状态、bar的 开盘状态进行“委托单触发”这个步骤)。
3.2 开启bar内模式
开启bar内模式,图表上最新的bar(假设是相对编号为14的bar)已经开盘,但是还没有收盘,那么此时开启自动交易,此时条件单基于开启自动交易之前最后一笔历史tick同时进行“委托单条件判断”和“委托单触发”这两个步骤,也就是说当“委托单条件判断”条件成立就直接发送到交易所(市价单在开启自动交易之后进行“委托单条件判断”和“委托单触发”这两个步骤);开启bar内模式,图表上最新的bar(假设是相对编号为14的bar)已经收盘,然后此时开启自动交易,此时条件单和市价单基于编号为14的bar的收盘tick进行“委托单条件判断”,然后等待下一根bar的开盘tick进行“委托单触发”这个步骤。
3.3 开启bar外模式
开启bar外模式,当前图表上新一根bar(假设相对编号为14),已经收盘,并且下一根bar还没有开盘,那么此时开启自动交易,条件单会基于开启自动交易前最后一笔tick进行“委托单条件判断”,然后直接发送到交易所,也就是说此时“委托单条件判断”和“委托单触发”这两个步骤同时进行(市价单会基于开启自动交易之前最后一笔tick进行“委托单条件判断,然后等待下一根bar的开盘tick进行“委托单触发”这个步骤,但是并不会基于bar外状态进行“委托单触发”这个步骤)。
开启bar外模式,当前图表上最新一根bar(假设相对编号为14),已经开盘,还没有收盘,那么此时开启自动交易,之后条件单和市价单的情况请参考上一节3.2的阐述。
【思维导图1】:委托单的发单机制包括两部分:
【思维导图2】:
对于this bar,“委托单条件判断”和“委托单触发”是一个步骤,委托单条件判断成立同时,同步“委托单触发”直接发送给交易所(this bar)。
对于next bar,“委托单条件判断”和“委托单触发”是两个步骤,“委托单条件判断成立同时”,异步观察“委托单触发”条件是否成立(next bar)
【思维导图3】:next bar和this bar适用于那种交易状态
【思维导图4】:自动交易进行中---开启bar内模式/未开启bar内模式---next bar基于开启bar内模式和未开启bar内模式的计算方式
【思维导图5】:自动交易进行中---开启bar外模式----next基于开盘状态和收盘状态的“条件判断”和“委托单执行”的不同
【思维导图6】:开启交易瞬间---开启bar内模式/未开启bar内模式---next bar基于开启bar内模式和未开启bar内模式的计算方式
【思维导图7】同思维导图5
【总结1】
开启自动化,尽量要在收盘之后,或者开盘之前。
交易模式分:非bar内模式、bar内模式、bar外模式
区别:非bar内模式,barStatus=0/2
区别:bar内模式,barStatus=0/1/2
区别:bar外模式,barStatus=-1
【备注】:造成bar外情况,也就是barStatus=-1,产生bar外模式,有可能在多周期,集合竞价时产生,此时的barStatus既不是开盘0,盘中1,收盘2,此时就会产生第四种状态barStatus=-1,如果要允许终端时间发单,那么就要开启bar外模式AllowSendOrdersAlways=true。
=================================================
之前的文章感谢大家的转载,希望转载时请注明出处,本人转自其它网站的图表一并感谢,谢谢~!
https://www.cnblogs.com/noah0532/