【FX581原创】如何阻止EA程序运行
2021-07-08 15:14:58
一看到标题就会有人问:EA程序不是为了赚钱的吗?为什么还要让它停止?

这个问题其实还要根据实际情况来看,一般情况下,EA程序是为我们带来利润的工具,但行情波动有时候确实让不少投资者损失惨重,尤其是无人值守的时候,发生的大波动极端行情,这时候我们需要去把控风险,让EA在出现账户大规模亏损时自动停止。
首先我们来看一种简单的实现:
bool isrun;//全局变量,通过改变状态来控制EA运行
int OnInit()
{
   isrun = true;//初始化时为真,也就是可以运行状态
   return(INIT_SUCCEEDED);
}
void OnTick()
{
   if(!isrun)//当状态是假时,每次新价格到来都时都会直接返回
   {
      return;
   }
   //若触发某个条件后将isrun变量设置为false
   if(触发条件)
   {
      isrun = false;
   }
}
 
至于触发EA停止的条件,我们可以设计成整个账户浮亏到20%时自动触发全部平仓,然后让EA停止运行,甚至还可以发出声音和发送邮件。代码片段如下:
 
double profit = 0;
   for(int i=OrdersTotal()-1;i >= 0;i--)
   {
      if(OrderSelect(i,SELECT_BY_POS) == false) continue;
      if(OrderSymbol() == Symbol())
      {
         profit += OrderProfit() + OrderCommission() + OrderSwap();
      }
   }
   double money = AccountBalance() * 0.2;//计算账户的百分之20钱数
   if(profit + money <= 0)
   {
      //全平,代码略
      //设置状态,停止EA
      isrun = false;
   }
 
这段代码初看之下确实没有问题但会有隐患,事实上EA程序在运行时会受到诸如手动切换时间周期、修改EA参数、甚至重启MT4等操作,这些操作最终会导致EA程序重新执行初始化函数,让整个状态重置,原本已经停止的EA却又开始执行。
 
那么如何避免上述情况呢?如果是切换时间周期和修改EA参数导致的EA程序重新初始化,我们可以通过修改代码来避免:
bool isrun = true;//全局变量,通过改变状态来控制EA运行
 
将声明全局变量的地方附上初值,删掉OnInit()函数中的赋值语句即可避免这种情况的发生。
但是如果将MT4重启这样的办法显然不能避免,这时候又该如何做呢? 
众所周知,我们将MT4软件重启,任何在上面运行的程序都将重新清零,这时候之前运行中所改变的变量都会重新初始化,内存被清除后是无法再找回数据的,我们可以采用保存到文件的方法来做到保存这个状态:
 
int filehandle = FileOpen(要保存的文件名,FILE_WRITE|FILE_TXT);
   if(filehandle > 0)
   {
      FileWriteString(filehandle, 要保存的内容);
      FileClose(filehandle);
   }
 
当重新调用初始化函数的时候,我们只需读取这个文件,判断这个文件中的值即可知道EA的运行状态。这个办法已经接近完美,不过我们还有更有效的办法:直接将EA移除掉。
 
ExpertRemove()
这是MT4官方提供给我们的函数,目的是将自身程序卸载掉,这样当账户发生严重亏损时,立刻将此EA直接移除,就可以保证程序不再执行。
只是,这个函数的说明中有这么一句话:
 
The Expert Advisor is not stopped immediately as you call ExpertRemove(); just a flag to stop the EA operation is set.
意思是说这个函数不会立刻让EA程序停止,它只是设置了一个退出操作的标志。
那么我们难道没有其他办法将EA程序立刻停止掉吗?
答案是有的。
程序开发人员思维是灵活的,我们要利用其他方法来将程序彻底停下来,所以我们不妨换个思路:
 
int stop[1];
   stop[10] = 1;
上面两行代码很明显会发生错误,因为运行到第二句后MT4会报发生严重错误的提示,因为我们让数组越界访问了,根据MT4软件的规则,当程序遇到严重错误时EA会立刻停止运行,这样其实就间接的让整个EA程序瞬间停了下来,如此一来我们就达到了预想的目的。