EA 在 MQL4 中打开的订单多于预期

问题描述

一切看起来都很好。但是 EA 通常会在同一秒内打开多个交易...我构建它的方式非常线性,我似乎无法发现逻辑错误。它基本上是一个随机鞅 EA 来测试东西。任何指标(这就是我称之为随机的原因,我自己还没有决定)都可以放在那里。

基本思想是它有一个上限和下限,决定了它何时处于买入区和何时处于卖出区。一旦它处于任一区域,如果趋势与它相反(由指标的价值决定,而不是交易品种的价格),它会以初始订单的相同 SL/TP 开启另一笔交易。它还会检查初始交易是否仍在运行,因此它不会打开其他交易,并且一旦初始交易打开。之后,其余交易的标准(与交易背道而驰的则不同)。

问题在于它有时不应该打开多笔交易,或者在同一秒或两秒内进行 3-4 笔交易。知道为什么会发生这种情况吗?

#property copyright "Copyright 2020,MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

input int stepValue = 5;
input double lotsize = 0.01;
input int stoploss = 2000;
input int takeprofit = 140;
input int slippage = 10;
input double upper_border = 60.0;
input double lower_border = 40.0;

const string EAComment = "Xind";

string mode = "";
bool first_trade = false;
int InitTicket = 1;
double X = 0.0;
double X_Last = 0.0;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

int OnInit()
  {
//---
      first_trade = false;
//---
   return(INIT_SUCCEEDED);
  }
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+

void OnDeinit(const int reason)
  {
//---

  }
  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+

void OnTick()
  {
//---
      SearchSignal();
      if (mode == "Buy")
         {
            if (first_trade == false)
            {
               Buy();
            }
            if (first_trade == true)
            {
               MartinCheck();
               CloseCheck();
            }
         }
      if (mode == "Sell")
         {
            if (first_trade == false)
            {
               Sell();
            }
            if (first_trade == true)
            {
               MartinCheck();
               CloseCheck();
            }
         }
  }
//+------------------------------------------------------------------+
void Buy()
  {
      X_Last = X;
      first_trade = true;
      InitTicket = OrderSend(NULL,OP_BUY,lotsize,Ask,slippage,Ask-stoploss*Point,Ask+takeprofit*Point,EAComment,1,clrDarkBlue);
  }
//---
void Sell()
  {
      X_Last = X;
      first_trade = true;
      InitTicket = OrderSend(NULL,OP_SELL,Bid,Bid+stoploss*Point,Bid-takeprofit*Point,clrDarkRed);
  }
//---
void MartinBuy()
  {
      if (OrderSelect(InitTicket,SELECT_BY_TICKET) == true)
         {      
            double new_SL = OrderStopLoss();
            double new_TP = OrderTakeProfit();
            int dont_care = OrderSend(NULL,new_SL,new_TP,EAComment+" martin",clrDarkBlue);
         }
  }
//---
void MartinSell()
  {
      if (OrderSelect(InitTicket,clrDarkRed);
         }
  }
//---
void SearchSignal()
{
   X = 0.0; //where 0.0,put here the iCustom for external indicators,or some built-in indicator
   if (X >= upper_border)
      {
         mode = "Sell";
      }
   else if (X <= lower_border)
      {
         mode = "Buy";
      }
   else
      {
         mode = "";
         first_trade = false;
         InitTicket = 1;
         X_Last = 0.0;
      }
}
//---
void CloseCheck()
{
    if (OrderSelect(InitTicket,SELECT_BY_TICKET))
    {

       if (OrderCloseTime() == 0)
          {
             first_trade = true;
          }
       else if (OrderCloseTime() != 0)
          {
             first_trade = false;
          }
       else
          {
             return;
          }
    }
}
//---
void MartinCheck()
{
   if (mode == "Buy")
      {
         if ((X_Last - stepValue) >= X)
            {
               X_Last = X;
               MartinBuy();
            }
      }
   if (mode == "Sell")
      {
         if ((X_Last + stepValue) <= X)
            {
               X_Last = X;
               MartinSell();
            }
      }
}

解决方法

您的代码布局使得多个进程可以在同一个滴答上按顺序发生,我认为这是您不想要的。尝试将您的代码最初更改为此并从那里开始工作:

void OnTick()
{
    SearchSignal();
    if(mode=="Buy")
    {
       if(!first_trade) Buy();
       else
       {
          MartinCheck();
          CloseCheck();
       }
    }
    else if(mode=="Sell")
    {
       if(!first_trade) Sell();
       else
       {
           MartinCheck();
           CloseCheck();
       }
    }
}

记住使用 if(...) else 停止执行所有函数,当它只应该是一个非此即彼的情况时。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...