7.4 K棒开启的执行
预设上,EA是以每秒的实时时间执行的。但某些情况下,最好每个K棒只检查一次交易条件。借等待目前K棒的收盘,我们可以确认条件已发生且讯号是有效的。相对而言,在实时时间执行交易,我们对于错误信息会较敏感。
每个K棒交易一次也意味着Strategy Tester的结果将更准确和有意义。由于MetaTrader的Strategy Tester与生俱来的限制,用“每秒”作为测试模型导致不可靠的回复测试结果,因为每秒经常是依据M1资料而来。真实生活所发生的交易不需要和Strategy Tester中制作出的交易相符合。
但是,如果将交易放置于K棒的收盘处,并使用“仅限开仓价格”作为测试模型,我们可以得到更准确反映实时交易的测试结果。每个K棒交易一次的缺点是交易可能会被延迟执行,尤其在K棒有很多价格波动时。基本上,反应性和可靠性是鱼与熊掌不能兼得的。
要使每个K棒检查一次交易条件,我们就必须检验目前K棒的时间标记。我们将把这个时间标记储存为一个全局变量。在EA的每次执行,我们将比较所储存的时间标记和目前的时间标记。一旦目前K棒的时间标记改变了,表示新的K棒被开启,我们将再检查交易条件。
我们也必须调整指标函数中的位移参数、价格函数和数组,以回传前一个K棒的值。若指标函数或价格数组设定为检查目前的K棒,我们将把K棒指数平移1以检查前一个K棒。所有的指标和价格数组都必须让其位移参数增加1。
技术上,我们要在一个新的K棒的一开始检查交易条件,并检查前一个K棒的收盘值。当每个K棒仅检查一次时,我们不检查目前已开启的K棒。
下列的程序代码用来检查一个新K棒的开始。首先,我们执行一个外部变量CheckOncePerBar来打开或关掉这个特征。然后再执行一个datetime全局变量以储存目前K棒的时间标记,就是CurrentTimeStamp。
在init()函数中,我们将指定目前K棒的时间标记给CurrentTimeStamp。这样会导致事物査询的延迟直到下一个K棒出现。源代码如下:

下列的程序代码是在start()函数的一开始运作的,接于定时器之后。整数变量BarShift将决定是否设定指标和价格函数中的Shift值给目前或前一个K棒。布尔变量NewBar将决定是否检查我们的交易条件:

若CheckOncePerBar设定为真,我们则先把BaiShift设为1,这将设定所有的指标和价格函数/数组中的Shift参数到前一个K棒。接着,我们比较CurrentTimeStamp变量和Time[0]的值。后者是目前K棒的时间标记。若两个值不符合,我们将把Time[0]的值指派给CurrentTimeStamp并设NewBar为真,交易条件将很快被检查。
在随后的执行中,CurrentTimeStamp和Time[0]将会符合,这表示NewBar将被设为假,交易条件将不被检查直到新K棒开始。一旦新K棒开始,Time[0]的值将和CurrentTimeStamp值不同,NewBar将再一次被设为真。若CheckOncePerBar被设为假,NewBar将自动设为真,而BarShift将被设为“0”。这会像之前一样,每秒检查交易条件。BarShift变量需要指定到需要参照的K棒函数、价格函数或数组的Shift参数。应用范例为:

你应该能辨别出这些范例和之前的不同之处。我们不是检查目前的K棒,而是检查刚收盘的K棒,也就是前一个K棒。若你需要参照最近关闭K棒的前一个K棒,只要简单地把目前的shift参数加到BarShift即可。源代码如下:

若不需要每个K棒执行一次EA,将不需要加上这些程序代码。但对于许多指标基型交易系统,这可以让你的交易和回复测试结果更可靠。为控制交易的执行,我们需要在订单配置执行程序前检查NewBar的值。我们可以借前面为了定时器所放置的if区块做到这一点:

