了解MT4编程的同学应该都知道,MT4的EA编写中有三个最重要的系统函数OnInit(),OnTick() 和 OnDeinit(const int reason)。这三个函数分别会在EA初始化的时候,EA运行(接收到市场报价)的时候和EA退出(反初始化)的时候。如果我们在EA运行的途中去修改EA的参数、修改图表的周期或者品种时, EA会分别运行OnDeinit(const int reason)函数来反初始化EA,再重新运行OnInit()来重新按照新的参数、品种、周期来重新运行。
那么还有一种极端的情况,就是EA正在执行OnTick()函数里面的指令,这时MT4并不会强制终止OnTick()函数,而是会等到OnTick()函数执行完毕之后,再执行OnDeinit(const int reason)和OnInit()来重新初始化EA。
小编在发现这个细节的时候也是经历了一个大乌龙的。具体情况是这样:在写下单函数的时候,通常会把它封装在一个while循环中,目的就是如果需要下单的手数超出了平台单笔手数限制的时候,可以把单子拆分开来下单,保证总的手数与希望下单的手数保持一致。
在某年某月某日,小编在没有勾选“允许实时自动交易”选项的情况下,挂上了此EA,这时就出现了一个问题,由于没有允许EA下单,所以EA在运行下单函数的时候就会报错4109,而且一直没有走出这个while循环,没有意识到这个问题的小编在另一天修改了EA参数之后,勾上了“允许实时自动交易”按钮,点击确定,让EA按新的参数运行,然而EA先是按照旧的参数下了单子,把之前没有走完的while循环结束之后,才开始运行了新的参数。
刚开始遇到这个问题的时候小编还很纳闷,不知道为什么会出现这么个乌龙,后来冥思苦想了半天之后才恍然大悟,想起来MT4之前是进入了死循环,然后在换参数,勾选了“允许实时自动交易”的时候MT4才从这个死胡同里走出来。后来小编也使用了类似的代码验证了刚才的结论,测试代码和截图如下:
input string Symbols = "XAUUSD";
double lots = 0;
int OnInit() {
lots = 0.1;
return INIT_SUCCEEDED;
}
void OnTick() {
int myticket = 0;
while(lots) {
myticket = OrderSend(Symbols,OP_BUY,lots,Ask,10,0,0,"test",123456,0,clrBlue);
if(myticket >= 0) {
lots -= 0.1;
}
else {
Print("order send error: ", GetLastError());
}
}
}
本文作者:小土豆
发表评论