: | : | :期货程序化 | :期货程序化研究 | :期货量化学习 | :期货量化 |
返回列表 发帖

信号脚本计算机制(第二部分)

信号脚本计算机制(第二部分)

四、信号脚本计算的驱动因素

信号脚本计算的驱动因素有如下几种方式,通常的方式是第一种方式,即tick驱动的计算:开启bar内模式下,信号脚本是基于每笔tick进行计算,包括开盘tickbartick、收盘tick;而未开启bar内模式,信号脚本是基于收盘tick或者开盘tick进行计算。

除了tick驱动的计算,信号脚本还可以基于鼠标点击、关键字recalclastbarafter、经纪商部位变化、策略部位变化进行计算,但是需要都需要进行额外的代码处理或者特别的设置,这里需要注意的是,除了tick驱动的计算外,其它计算方式不能用于回测中。

1.
当新的bar/tick出现时

我们知道一根bar由一笔开盘tick、若干笔bartick、一笔收盘tick组成,而开盘tickbartick都是从交易所接收的,只有收盘tickMC底层产生的;在开启bar内模式下,信号脚本会基于每笔tick执行一次计算。

在未开启bar内模式下,信号脚本基于每根bar只会计算一次,或者基于开盘tick进行计算,或者基于收盘tick进行计算;是基于开盘tick还是收盘tick是基于信号脚本的代码中是否含有Open next barDate next barTime next barDateTime next barTime_s next bar5个语句之一,也就是引用下一根bar的数据;当信号脚本中含有引用下一根bar数据的语句时(至少含有5个语句之一),信号脚本会基于下一根bar的开盘tick执行计算;当信号脚本中不含有引用下一根bar数据的语句时,信号脚本会基于当根bar的收盘tick执行计算。(“Set系列关键字”这篇帖子中也提到引用下一根bar数据的语句)。

    Bar内模式与非bar内模式的区别之一就是是否基于bartick执行信号计算,这个从表面意思上也可以意会。

2. 鼠标在图表上点击

当在信号脚本中加入语句“[processmouseevents=true]”时,我们可以用鼠标在图表上进行点击,点击之后,信号脚本就会基于这个点击的操作进行计算,每点击一次信号就执行一次计算,每次计算都是基于最新的bar最新的行情执行计算;可以用鼠标左键点击图表执行计算,也可以使用鼠标右键点击图表执行计算。

3. Recalclastbarafter

信号代码中若出现recalclastbarafter(20);”这个语句,那么当信号脚本超过20秒没有执行计算时,那么信号脚本就会执行一次计算;recalclastbarafter(N);”,关键字recalclastbarafter后面的参数N是以秒为单位的,N需要自行设置,可以是整数也可以是小数,这个语句的作用就是当信号脚本超过N秒没有执行计算,该语句就会促使信号脚本执行一次计算;举例,当交易所收盘后,没有tick行情驱动信号执行计算并且没有其它因素驱动信号执行计算,那么信号脚本会每隔N秒执行一次计算。

4. 经纪商部位变化和策略部分变化

关于经纪商部位和策略部位这两个概念,可以在帖子“图表部位、策略部位、经纪商部位”中学习一下;当经纪商部位变化或者策略部分变化时,若需要让信号脚本执行相应的计算,我们需要在“策略属性”-“自动交易”-“重新计算”中进行设置一下,如下图所示:

001.png


3. 重新计算

  图3中圈出来的地方,有两个选项:当勾选“市场部位变动”时,那么当委托单在交易所实际成交了,也就是经纪商部位变动了,那么信号就会基于经纪商部位的变动执行一次计算;当勾选“委托单成交”时,那么当策略部位变动了,那么信号就会基于策略部位的变动执行一次计算。

5. 关键字getappinfo

关键字getappinfo的用法,在这里并不打算系统阐述,该关键字后面可以有各种参数,我们只里只介绍参数aicalcreason的用法;“getappinfo(aicalcreason);”返回信号脚本执行计算的原因,上面我们已经介绍了信号脚本执行计算的各种驱动因素,也就是各种原因,每种原因都会对应getappinfo(aicalcreason);”的一个返回值:

l
当信号脚本基于tick驱动执行计算时,“value1=getappinfo(aicalcreason);”语句中value1等于0,也就是getappinfo(aicalcreason)返回的值是0

l
当信号脚本基于鼠标在图表上左击而执行计算时,“value1=getappinfo(aicalcreason);”语句中value1等于1,也就是getappinfo(aicalcreason)返回的值是1

l
当信号脚本基于鼠标在图表上右击而执行计算时,“value1=getappinfo(aicalcreason);”语句中value1等于2,也就是getappinfo(aicalcreason)返回的值是2

l
当信号脚本基于关键字recalclastbarafter而执行计算时,“value1=getappinfo(aicalcreason);”语句中value1等于3,也就是getappinfo(aicalcreason)返回的值是3

l
当信号脚本基于经纪商部位变动而执行计算时,“value1=getappinfo(aicalcreason);”语句中value1等于4,也就是getappinfo(aicalcreason)返回的值是4

l
当信号脚本基于策略部位变动而执行计算时,“value1=getappinfo(aicalcreason);”语句中value1等于5,也就是getappinfo(aicalcreason)返回的值是5

通过getappinfo(aicalcreason)的使用,我们可以在信号脚本中对当前信号计算的驱动因素进行识别和判断,并且信号在后续的计算中执行相应的逻辑,例如,当getappinfo(aicalcreason)返回值为4时,在信号中就可以判断当前的委托单在交易所实际成交了。

五、委托单的发单机制

终于写到第五部分内容了,我想说这部分内容是最难的,也是最难测试的,花费了一个月时间进行测试,因为需要等到极端的行情才能测试出结果,有些还需要进行测试好几遍以便进行对比确认,而这部分内容也很难归纳,如果只是简单的将测试结果进行罗列,那样会很不容易理解。

对于这一章节,前4节的内容的阐述都是以实盘情况进行阐述,不涉及到回测的内容;若需要涉及到回测,我要特别强调一下。

1. 委托单条件判断和委托单触发

这里首先我们需要理解两个概念,一个是“委托单条件判断”,另一个是“委托单触发”,这两个概念会贯穿这部分的内容,我们先来看一下代码例子,如下:

if condition1 then


buy next bar at market;

条件condition1next bar委托语句的判断条件,当条件condition1成立时,还需要等待下一笔tick的触发,才能将买入市价单发送出去;也就是说买入市价单是否能发送到交易所,涉及两个步骤,缺一不可,那就是首先信号脚本执行计算必须进行“委托单条件判断”这个步骤,并且条件成立,然后需要“委托单触发”这个步骤,才可以将next bar的委托单发送到交易所;这里只是通过一个简单的例子来阐述这两个概念,那么对于“委托单条件判断”和“委托单触发”就光这两个步骤在非bar内模式、bar内模式、bar外模式、信号脚本不同的计算驱动因素会表现的不一样。

This barnext bar主要有两点区别,一个区别就是,thisnext的区别,这正如它们的名称一样,next bar委托单需要经过两个步骤才能发送到交易所,也就是上面说到的两个步骤,而this bar委托单只需要一个步骤,也可以说“委托单条件判断”和“委托单触发”两个步骤对于this bar委托单来说是一个步骤,“委托单条件判断”的同时,若条件成立就“委托单触发”立即发送到交易所;另一个区别是,next barbar内模式、bar外模式,也就是说,next bar委托单可以基于bar的开盘状态、bar内状态、收盘状态、bar外状态进行“委托单条件判断”,基于bar的开盘状态、bar内状态、收盘状态、bar外状态进行“委托单触发”,而this bar只能基于收盘状态进行“委托单条件判断”和“委托单触发”。所以,在总体上this bar的使用是受限制的,不如next bar的使用功能丰富,但是从速度上说,this bar更快;若您对this barnext 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内模式的区别。我们前面说过,bar4个状态,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


4. 开盘tick

4中,最大bar设置为0,此时bar的绝对编号等于相对编号,图表中最后一根bar的编号为605,而公式编译器中输出栏位中最后一根bar的编号是604,这里需要简单解释一下,信号脚本基于开盘tick执行计算,是指当接收到下一根bar的开盘tick时,信号脚本会基于当根bar执行计算信号脚本中的关键字currentbarclose等返回的信息都是当根bar的信息,而不是下一根bar的信息;在非bar内模式下,基于下一根bar开盘tick的计算,除了Open next barDate next barTime next barDateTime next barTime_s next bar返回的是下一根bar的信息(这5个关键字的信息可以通过下一根bar的第一笔tick直接可以获取到),其它关键字(例如,currentbarclose等等)返回的都是当根bar的信息。

这是一个非常不活跃的商品品种,图表上现在是1505分,当编号为606bar的开盘tick接收的时候(假设是在150930时,当根bar的收盘时间为1510分),信号脚本会执行一次,此时信号脚本中关键字currentbar返回的是605,那么“委托单条件判断”这个步骤被执行了;接下来,我们会采用几种可能的措施,以此来阐述不同的效果:

l
若在1515分之前,没有接收到tick数据,因为我们在信号脚本中使用了语句[ProcessMouseEvents=true],所以当我们在图表上点击一下鼠标时,信号脚本会执行一次计算,也就是在编号为606bar收盘之前执行一次计算,于是bar内状态执行了“委托单触发”这个动作,委托单被触发发送到交易所。

l
若在1515分之前,没有执行鼠标点击动作,但是在150950时接收到一笔tick,尽管信号脚本不会基于该笔bartick执行计算,但是仍然是bar内状态,即bar内状态执行了“委托单触发”这个动作,委托单被触发发送到交易所。

l
若在1515分之前,没有执行鼠标点击动作,也没有接收到交易所的tick,底层产生一笔收盘tick,尽管信号脚本也不会执行计算,但是bar的收盘状态执行了“委托单触发”这个动作,委托单被发送到交易所了。

2.2 开启bar内模式

开启bar内模式,也就是信号代码中使用语句[IntrabarOrderGeneration=true],在bar内模式下,信号脚本的计算是每接收到一笔tick信号脚本都会执行一次计算(开盘tickbartick、收盘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;

l
假设当前bar的收盘时间为1358,然后开启自动交易

l
接着在140000时接收到收盘时间为1400bar的开盘tick(即barstatus=0),开盘tick的价格是3710(假设商品合约是螺纹,周期为1分钟),信号脚本基于开盘tick执行计算,显然条件“time>=1400 and barstatus=0”是成立的,并且条件“time>=1400”也是成立的,也就是这两笔条件委托的“委托单条件判断”被执行了,并且都成立,就等待下一笔tick的触发

l
接着在140030时接收到第一笔bartick(即barstatus=1),tick的价格是3700;经过前面的“委托单条件判断”这个步骤的执行,这笔bartick执行了“委托单触发”这个步骤,于是两个条件单都发送到交易所了;现在的问题是,两笔发送到交易所的价格分别是多少呢?

l
条件单的价格是在“委托单条件判断”这个步骤确定的,并不是在“委托单触发”这个步骤确定的,所以“first”条件单的限价是3710-10,即3700;“second”条件单的限价是3710-20,即3690

l
条件单的价格确定了,但是条件的问题又来了;因为14:00:30的这一笔tick的接收,导致信号脚本又执行一次计算,但是条件“time>=1400 and barstatus=0”不再成立,这样“first”委托单也会发送到交易所吗?答案是肯定的。但是信号仍然基于该笔tick执行了一次“委托单条件判断”这个步骤。

l
接着在140050时接收到第二笔bartick(即barstatus=1),tick的价格是3670,此时这笔tick执行了“委托单触发”这个步骤,因为信号脚本基于上一笔tick(即140030这笔tick)执行了“委托单条件判断)这个步骤,但是条件不再成交,所以这笔tick(即140050这笔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的收盘时间为1330,当根bar的收盘时间为13:31(图表上最后一根bar,最新的bar),而且还没有走完(即barstatus=01),那么此时开启自动交易之后,条件单基于收盘时间为13:30bar进行“委托单条件判断”,然后直接触发委托,也就是“委托单条件判断”和“委托单触发”这两个步骤同时进行,也就是开启自动交易之后条件单直接发送到交易所(但是市价单不会基于历史行情进行“委托单条件判断”,也不会基于历史行情进行“委托单触发”这两个步骤,市价单需要在开启自动交易之后执行“委托单条件判断”和“委托单触发”这两个步骤,请参考“自动交易进行中”这一节内容);

若当根bar(收盘时间为1331)已经收盘,并且下一根bar还没有开盘,那些此时开启自动交易,条件单基于收盘时间为1331bar执行“委托单条件判断”,需要等到下一根bar第一笔tick(开盘tick)执行“委托单触发”这个步骤(市价单也会基于1331的收盘bar执行“委托单条件判断”,需要等到下一根bar第一笔tick(开盘tick)执行“委托单触发”这个步骤)。

未开启bar内模式,基于下一根bar第一笔tick进行信号计算,当前bar的收盘时间为1400(图表上最后一根bar,最新的bar),还没有收盘(即barstatus=01时),那么此时开启自动交易,条件单直接基于1400bar的开盘tick(即barstatus=0)进行“委托单条件判断”这个步骤,然后直接触发委托,也就是“委托单条件判断”和“委托单触发”这两个步骤同时进行,不需要等待最新的一笔tick的触发委托(市价单需要在开启自动交易之后进行“委托单条件判断”和“委托单触发”这个步骤,请参考“自动交易进行中”这一节);当前bar的收盘时间为1400(图表上最后一根bar,最新的bar),已经收盘(即barstatus=2),并且还没有接收到下一根bar的开盘tick,那么此时开启自动交易,条件单需要等到下一根bar的开盘tick,基于下一根barbarstatus=0进行“委托单条件判断”这个步骤,然后等待接下来bar内状态、bar的收盘状态、bar的开盘状态进行“委托单触发”这个步骤(市价单需要在开启自动交易之后,基于实时的开盘tick进行“委托单条件判断”,然后等待接下来bar内状态、bar的收盘状态、bar的开盘状态进行“委托单触发”这个步骤)。

3.2 开启bar内模式

开启bar内模式,图表上最新的bar(假设是相对编号为14bar)已经开盘,但是还没有收盘,那么此时开启自动交易,此时条件单基于开启自动交易之前最后一笔历史tick同时进行“委托单条件判断”和“委托单触发”这两个步骤,也就是说当“委托单条件判断”条件成立就直接发送到交易所(市价单在开启自动交易之后进行“委托单条件判断”和“委托单触发”这两个步骤);开启bar内模式,图表上最新的bar(假设是相对编号为14bar)已经收盘,然后此时开启自动交易,此时条件单和市价单基于编号为14bar的收盘tick进行“委托单条件判断”,然后等待下一根bar的开盘tick进行“委托单触发”这个步骤。

3.3 开启bar外模式

开启bar外模式,当前图表上新一根bar(假设相对编号为14),已经收盘,并且下一根bar还没有开盘,那么此时开启自动交易,条件单会基于开启自动交易前最后一笔tick进行“委托单条件判断”,然后直接发送到交易所,也就是说此时“委托单条件判断”和“委托单触发”这两个步骤同时进行(市价单会基于开启自动交易之前最后一笔tick进行“委托单条件判断,然后等待下一根bar的开盘tick进行“委托单触发”这个步骤,但是并不会基于bar外状态进行“委托单触发”这个步骤)。


开启bar外模式,当前图表上最新一根bar(假设相对编号为14),已经开盘,还没有收盘,那么此时开启自动交易,之后条件单和市价单的情况请参考上一节3.2的阐述。


论坛官方微信、群(期货热点、量化探讨、开户与绑定实盘)
 
期货论坛 - 版权/免责声明   1.本站发布源码(包括函数、指标、策略等)均属开放源码,用意在于让使用者学习程序化语法撰写,使用者可以任意修改语法內容并调整参数。仅限用于个人学习使用,请勿转载、滥用,严禁私自连接实盘账户交易
  2.本站发布资讯(包括文章、视频、历史记录、教材、评论、资讯、交易方案等)均系转载自网络主流媒体,内容仅为作者当日个人观点,本网转载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网不对该类信息或数据做任何保证。不对您构成任何投资建议,不能依靠信息而取代自身独立判断,不对因使用本篇文章所诉信息或观点等导致的损失承担任何责任。
  3.本站发布资源(包括书籍、杂志、文档、软件等)均从互联网搜索而来,仅供个人免费交流学习,不可用作商业用途,本站不对显示的内容承担任何责任。请在下载后24小时内删除。如果喜欢,请购买正版,谢谢合作!
  4.龙听期货论坛原创文章属本网版权作品,转载须注明来源“龙听期货论坛”,违者本网将保留追究其相关法律责任的权力。本论坛除发布原创文章外,亦致力于优秀财经文章的交流分享,部分文章推送时若未能及时与原作者取得联系并涉及版权问题时,请及时联系删除。联系方式:http://www.qhlt.cn/thread-262-1-1.html
如何访问权限为100/255贴子:/thread-37840-1-1.html;注册后仍无法回复:/thread-23-1-1.html;微信/QQ群:/thread-262-1-1.html;网盘链接失效解决办法:/thread-93307-1-1.html

返回列表