量化投资_EasyLanguage/PowerLanguage教学课程__【第二篇专题】__【第十七章关于bar内交易的几个问题】
第十七章:关于bar内交易的几个问题
1、实时数据刷新打印和历史数据刷新打印
打印历史数据时会发现如下:
#cb 1.00 #bs 1.00 #t1109.00 #p 1.00 #mp 1.00 #mp[1] 0.00
#cb 1.00 #bs 2.00 #t1110.00 #p 1.00 #mp 1.00 #mp[1] 0.00 #cb 2.00 #bs 0.00 #t1110.00 #p 1.00 #mp 1.00 #mp[1] 1.00
打印实时数据时会发现如下:
#cb 108.00 #bs 2.00 #t1457.00 #p 0.00 #mp 0.00 #mp[1] 0.00 #cb 109.00 #bs 0.00 #t1458.00 #p 0.00 #mp 0.00 #mp[1] 0.00 #cb 109.00 #bs 1.00 #t1458.00 #p 0.00 #mp 0.00 #mp[1] 0.00
【分析】
1、在新bar开启时,打印历史数据时,上一个bar的收盘状态会放在下一个bar的time当中;而在打印实时数据时,上一个bar的收盘状态是放在上一个bar的time当中。
我们打印历史的收盘价价格
#cb 1.00 #bs 1.00 #t1109.00 #p 1.00 #mp 1.00 #mp[1] 0.00 #close3553.00
#cb 1.00 #bs 2.00 #t1110.00 #p 1.00 #mp 1.00 #mp[1] 0.00 #close3553.00
#cb 2.00 #bs 0.00 #t1110.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3553.00
多打印几个
#cb 3.00 #bs 1.00 #t1111.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3551.00
#cb 3.00 #bs 2.00 #t1112.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3551.00 #cb 4.00 #bs 0.00 #t1112.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3551.00 #cb 4.00 #bs 1.00 #t1112.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3552.00
#cb 78.00 #bs 1.00 #t1426.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3555.00
#cb 78.00 #bs 2.00 #t1427.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3555.00 #cb 79.00 #bs 0.00 #t1427.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3555.00 #cb 79.00 #bs 1.00 #t1427.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3554.00
#cb 98.00 #bs 1.00 #t1446.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3553.00
#cb 98.00 #bs 2.00 #t1447.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3553.00 #cb 99.00 #bs 0.00 #t1447.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3553.00 #cb 99.00 #bs 1.00 #t1447.00 #p 1.00 #mp 1.00 #mp[1] 1.00 #close3554.00
分别找到:它们的开盘价和收盘,发现是可以一一对应的。这就应征了最早之前所说的,是由于当根新开盘tick造成的上一个bar的收盘。这里显示在这里非常清楚的表明了这点。但是在实盘实时数据刷新是是看不到这个结果的。其实这个结果是一闪而现的。
2、开启精细模式时,时间对不起来了?
我们发现在找上门的收盘价时间的时候,在K线图上去找都是延后一个时间段。这是因为我们开启了精细模式所致(当然不开启精细模式也是这样),这是因为如下图所示:
在打印的时间,打印的是准确的时间,观察K线显示的是bar完成的时间。因此在后面解释bar上时间问题,就是这个原因
3、再分析最初的那段代码
A:原始代码打印结果分析
[IntrabarOrderGeneration=true] var:intrabarpersist mp(0),intrabarpersist mp1(0), intrabarpersist ma0(0), intrabarpersist ma1(0); mp=marketposition; ma0 = Average(close,5); ma1 = Average(close,20); if mp[1] <> 1 and ma0[1] > ma1[1] then buy 1 shares next bar at market; if mp[1] = 1 and ma0[1] < ma1[1] then sell 1 shares next bar at market; print("#cb ",currentbar," #bs",barstatus," #t",Time_, " #p",marketposition," #mp",mp," #mp[1]",mp[1]);
【分析】
1、我们分析第一次开仓时间
[cb] 1.00 [bs] 1.00 [t]1109.00 [p] 0.00 [mp] 0.00 [mp[1]] 0.00
[cb] 1.00 [bs] 1.00 [t]1109.00 [p] 0.00 [mp] 0.00 [mp[1]] 0.00
[cb] 1.00 [bs] 1.00 [t]1109.00 [p] 0.00 [mp] 0.00 [mp[1]] 0.00
[cb] 1.00 [bs] 1.00 [t]1109.00 [p] 0.00 [mp] 0.00 [mp[1]] 0.00
[cb] 1.00 [bs] 2.00 [t]1110.00 [p] 0.00 [mp] 0.00 [mp[1]] 0.00
[cb] 2.00 [bs] 0.00 [t]1110.00 [p] 0.00 [mp] 0.00 [mp[1]] 0.00
[cb] 2.00 [bs] 1.00 [t]1110.00 [p] 1.00 [mp] 1.00 [mp[1]] 0.00
[cb] 2.00 [bs] 1.00 [t]1110.00 [p] 1.00 [mp] 1.00 [mp[1]] 0.00
[cb] 2.00 [bs] 1.00 [t]1110.00 [p] 1.00 [mp] 1.00 [mp[1]] 0.00
[cb] 2.00 [bs] 1.00 [t]1110.00 [p] 1.00 [mp] 1.00 [mp[1]] 0.00
红色标注位置显示:【p】表示当前已经持有多单,【mp】与marketposition相等也是表示持有多单,【mp[1]】表示上一个bar没有持有仓位。
问题:这里为什么要显示在第一个bar内位置而不显示在开盘位置(显示在barstatus=1(第一个),而不显示在barStatus=0)?
回答:这是因为,单子确实是下在barStatus=0的这个位置,因为只要下单了之后才会显示持仓状态,因此要显示在barstat=1(第一个)的位置。
佐证:观察下图我们发现,价格是下在了3553的这个开盘价,我们打印价格时候发现barstatus=1时的价格为3554。因此证明了,价格是下在开盘价,而下单完成后,在下一个tick显示成交状态。
B:我们更改原始代码,要求上一个bar进场之后,如果当前的close价格(也就是精细模式中的当前tick)向下穿越上一个ma0(慢速均线),要求在下一个tick挂止损单出场(stop);
[IntrabarOrderGeneration=true] var:intrabarpersist mp(0),intrabarpersist mp1(0), intrabarpersist ma0(0), intrabarpersist ma1(0); mp=marketposition; ma0 = Average(close,5); ma1 = Average(close,20); if mp[1] <> 1 and ma0[1] > ma1[1] then buy 1 shares next bar at market; //if mp[1] = 1 and ma0[1] < ma1[1] then sell 1 shares next bar at market; if mp[1] = 1 and close crosses under ma0[1] then sell 1 shares next bar at market; print("[cb]",currentbar," [bs]",barstatus," [t]",Time_, " [p]",marketposition," [mp]",mp," [mp[1]]",mp[1],"[close]",Close);
【分析】
1、我们再来看一下上面的输出结果,只看出场部分,还是第一笔,只观察出场部分,从图表上我们可以找到出场是在1112(bar上时间是1113)。如下面所示:
2、从输出结果来看,我们是在bar内的3550价格出场的,在出场之后,marketposition/mp再下一个tick位置已经变换成了0,表示当根不再持仓,其中mp[1]表示上一个bar的状态还是1,并为改变。
【小结】
通过上面的例子我们得到如下几个结论:
1、在bar内模式下,我们在盘中突破买入或者卖出操作的时候,需要判断上一个bar的状态。如果不判断上一个bar的状态的话,很可能会不断的进场或者出场操作。在这里我们提取marketposition的值,并赋值给Intrabarpersist mp(用复合变量命名)变量,在对bar内进行开平仓操作的时候,我们需要判断mp[1]上一个bar的状态。如果采用mp当根tick的状态的话是有可能造成不断进出场的问题。这就是复合变量的妙用
2、通过上面例子,复合变量既能显示当根bar的的持仓状态,又能显示上一个bar的持仓状态,只需要通过[方括号]改变其复合变量的性质即可。
3、在print打印时间的时候。存在正在进行的数据和bar上的时间,在K线的逻辑下,bar上的时间会“慢”一刻,这是疑问K线上/bar上的时间是完成时间。在找相关bar对照的数据要注意这问题。
4、错误的应用
我们想到,bar内模式,开启的精细是按照逐笔的方式,在国内期货中:逐笔=tick级别。那我们改成Ticks来穿越可不可以?
[IntrabarOrderGeneration=true] var:intrabarpersist mp(0),intrabarpersist mp1(0), intrabarpersist ma0(0), intrabarpersist ma1(0); mp=marketposition; ma0 = Average(close,5); ma1 = Average(close,20); if mp[1] <> 1 and ma0[1] > ma1[1] then buy 1 shares next bar at market; //if mp[1] = 1 and ma0[1] < ma1[1] then sell 1 shares next bar at market; if mp[1] = 1 and Ticks crosses under ma0[1] then sell 1 shares next bar at market; print("[cb]",currentbar," [bs]",barstatus," [t]",Time_, " [p]",marketposition," [mp]",mp," [mp[1]]",mp[1],"[close]",Close);
答案显然是不行的,错误自己观察即可。
【分析】
按住F1帮助看一下tick的定义:
图表设置成交量基于成交笔数,则Ticks返回每根Bar的成交笔数。
图表设置成交量基于交易量,则Ticks返回每根Bar的成交股数(成交手数)。
图表设置成交量基于成交笔数:
- 1-tick图表中,当前tick的Ticks返回值为1。
-
多tick、量、时间周期的图表中,当前Bar的Ticks返回值为当前Bar的成交笔数。
图表设置成交量基于交易量:
- 1-tick图表中,当前tick的Ticks返回值为当前tick的成交股数。
-
多tick,量,时间周期的图表中,当前Bar的Ticks返回值为当前Bar的成交股数。
注意:许多历史数据源只提供有限的历史成交量和成交笔数的数据,实时存储数据可以确保成交量和成交笔数数据的有效性。
tick返回的成交笔数,所以不可以,因此在bar内模式下,close价格=逐笔成交价格,而不是tick ≠逐笔成交价格。
=================================================
之前的文章感谢大家的转载,希望转载时请注明出处,本人转自其它网站的图表一并感谢,谢谢~!
https://www.cnblogs.com/noah0532/
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。