我的EA做了一个重复输入

 

我记得有人有同样的问题,用的是XXXX。

我找不到那条线,如果有人能帮助我,那将是非常感谢的。

我在On_Tick()中的代码如下

if(!PositionSelect(Symbol()))
            do
            {
               Price = SymbolInfoDouble(Symbol(), SYMBOL_ASK);

               if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0))
               {
                  Print("Position opened in ", Symbol());
                  Sleep(100);

                  break;
               }
               else
               {
                  ErrorCount++;

                  printf("Error opening BUY position in %s : '%s'", Symbol(), m_Trade.ResultComment());
               }

               if(ErrorCount == ErrCnt)
               {
                  Print("Error count = ", ErrCnt);
               }
            }
            while(ErrorCount < ErrCnt);

它应该输入0.01手,但却输入了0.02手。

从日志上看

2013.12.20 08:35:01 交易 '800****': 交易#27731692在1.36354买入0.01欧元兑美元完成(基于订单#40018327)。

2013.12.20 08:35:01 交易 '800****': exchange buy 0.01 EURUSD at market placed for execution in 331 ms

2013.12.20 08:35:01 交易 '800****': 交易#27731691在1.36353买入0.01 EURUSD完成(根据订单#40018326)。

2013.12.20 08:35:00 交易 '800****': 交易所在市场上买入0.01 EURUSD

2013.12.20 08:35:00 Trades '800****': exchange buy 0.01 EURUSD at market placed for execution in 313 ms

2013.12.20 08:35:00 交易 '800****': Exchange buy 0.01 EURUSD at market

 

我终于找到了那条线 https://www.mql5.com/en/forum/14327

我花了2个小时才找到那条线......总之,是不是EA睡得不够久,所以才会出现重复输入?

Problem: Multiple Trades at brokerX
Problem: Multiple Trades at brokerX
  • www.mql5.com
Problem: Multiple Trades at brokerX.
 
doshur:

我记得有人有同样的问题,用的是XXXX。

我找不到那条线,如果有人能帮助我,那将是非常感谢的。

我在On_Tick()中的代码如下

它应该输入0.01手,但却输入了0.02手。

从日志上看

2013.12.20 08:35:01 交易 '800****': 交易#27731692在1.36354买入0.01欧元兑美元完成(基于订单#40018327)。

2013.12.20 08:35:01 交易 '800****': exchange buy 0.01 EURUSD at market placed for execution in 331 ms

2013.12.20 08:35:01 交易 '800****': 交易#27731691在1.36353买入0.01 EURUSD完成(根据订单#40018326)。

2013.12.20 08:35:00 交易 '800****': 交易所在市场上买入0.01 EURUSD

2013.12.20 08:35:00 Trades '800****': exchange buy 0.01 EURUSD at market placed for execution in 313 ms

2013.12.20 08:35:00 交易 '800****': Exchange buy 0.01 EURUSD at market

  • 这不是你发布的代码的日志(Print语句的结果在哪里?)
  • 为什么你需要使用Sleep()?这是不需要的。
  • 为什么你需要一个循环?你甚至没有检查错误的原因,所以也没有纠正它。
  • 你必须检查ResultRetcode()和/或GetLastError(),而不是(仅)ResultComment()。
 
  • 这不是你发布的代码的日志(打印语句的结果在哪里?)

在专家标签下,除了在欧元兑美元打开的头寸,没有打印语句的输出。

其他线程似乎用sleep解决了这个问题
  • 你必须检查ResultRetcode()和/或GetLastError(),而不是(仅)ResultComment()。

我将阅读这些内容

但是如果(!PositionSelect(Symbol()))

为什么还在执行2次?

 
doshur:
  • 这不是你发布的代码的日志(打印语句的结果在哪里?)

在专家标签下,除了在欧元兑美元打开的头寸,没有打印语句的输出。

好吧,那么它到底有没有被打印出来?

其他线程似乎用sleep解决了这个问题

解决什么问题?
  • 你必须检查ResultRetcode()和/或GetLastError(),而不是(仅)ResultComment()。

我将阅读这些内容

但是如果(!PositionSelect(Symbol()))

为什么还在执行2次?

我们正在努力寻找答案。这个问题是否在你每次开仓时都会出现?
 

是的,它打印了2次 >在欧元兑美元建立的头寸

其他用户报告的同样问题 >https://www.mql5.com/en/forum/14327

通过使用 350ms的睡眠 来解决

在这之前,我的EA还做了2次交易,完全正常。

我在想,如果我的EA已经完成了订单的处理,而经纪人还没有把交易细节返回给我,我的EA处理了一个新的tick,造成了2个条目?

Problem: Multiple Trades at brokerX
Problem: Multiple Trades at brokerX
  • www.mql5.com
Problem: Multiple Trades at brokerX.
 
doshur:

是的,它打印了2次 >在欧元兑美元建立的头寸

其他用户报告的同样问题 >https://www.mql5.com/en/forum/14327

通过使用 350ms的睡眠 来解决

在这之前,我的EA还做了2次交易,完全正常。

我在想,如果我的EA已经完成了订单的处理,而经纪人还没有把交易细节返回给我,我的EA处理了一个新的tick,造成了2个条目?

这似乎是一个可能的解释,但如果是这样,就不正常了。你是否使用异步模式?如果不是,你的EA必须等待服务器的回复,然后才继续处理下一个tick。

如果我理解得好,这是一个随机的问题,你不能重现它?

你可以尝试在m_Trade的声明后添加这一行来打印更多调试信息。

m_Trade.LogLevel(LOG_LEVEL_ALL);
 
angevoyageur:

这似乎是一种可能的解释,但如果是这种情况,就不正常了。你是否使用异步模式?如果不是,你的EA必须等待服务器的回复,然后才继续处理下一个tick。

如果我理解得好,这是一个随机的问题,你不能重现它?

你可以尝试在m_Trade的声明后添加这一行来打印更多调试信息。

我正在使用cTrade 类。默认情况下,异步模式是打开的吗?

你是否建议我使用这个 m_Trade.SetAsyncMode(false)

我应该在on_init()中设置这个吗?

 
doshur:

我在使用cTrade类。默认情况下,异步模式打开的吗?

你是否建议我使用这个 m_Trade.SetAsyncMode(false)

我应该在on_init()中设置这个吗?

通常情况下,它默认为假。而你所使用的代码肯定是假的。

你报告的情况很 "有趣",在我看来,这不是一个正常的行为,似乎在某个地方有一个错误。你是否有可能发布一个代码样本来重现这个错误?无论如何,我将对这个问题进行调查。

Get in touch with developers using Service Desk!
Get in touch with developers using Service Desk!
  • www.mql5.com
We therefore attach great importance to all user reports about issues in our programs and try to answer each one of them.
 

谢谢你的帮助调查,我将附上我的模板,我曾经用它来开发我的EA。Sleep()之前是100ms,我在看了另一个用户发起的主题后,把它更新为800ms。

//+------------------------------------------------------------------+
//|                                                     Template.mq5 |
//|                                                           doshur |
//|                                     http://tradeaud.blogspot.com |
//+------------------------------------------------------------------+
#property copyright "doshur"
#property link      "http://tradeaud.blogspot.com"
#property version   "1.00"

#include <Trade\Trade.mqh>

#define   ErrCnt   5

//--- Input Parameters
input int    TP        = 50;
input int    SL        = 40;
input double LotSize   = 0.01;

//--- Buffers
double   MA_Fast[];
double   MA_Slow[];

//--- Handles
int      h_MA_Fast;
int      h_MA_Slow;

//--- Globals
double   AdjPoints;

CTrade   m_Trade;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

   h_MA_Fast = iDEMA(Symbol(), 0, 3, 0, PRICE_CLOSE);
   h_MA_Slow = iDEMA(Symbol(), 0, 5, 0, PRICE_CLOSE);

//---

   long   SymDigits;
   double SymPoints;

   SymPoints = SymbolInfoDouble(Symbol(), SYMBOL_POINT);
   SymDigits = SymbolInfoInteger(Symbol(), SYMBOL_DIGITS);

   if(SymDigits == 3 || SymDigits == 5)
   {
        AdjPoints = SymPoints * 10;
   }
   else
   {
        AdjPoints = SymPoints;
   }

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

   IndicatorRelease(h_MA_Fast);
   IndicatorRelease(h_MA_Slow);

//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

   if(!CopyBufferAsSeries(h_MA_Fast, 0, 0, 3, true, MA_Fast)) return;
   if(!CopyBufferAsSeries(h_MA_Slow, 0, 0, 3, true, MA_Slow)) return;

//---

   double   Price;
   ulong    SymSpread;
   int      ErrorCount;

   ErrorCount = 0;
   SymSpread  = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);

   m_Trade.SetDeviationInPoints(SymSpread);

   MqlDateTime sTime;
   TimeCurrent(sTime);

//---

   if(!PositionSelect(Symbol()))
   if(TradeCount(PERIOD_CURRENT) == 0)
   {
      // Open BUY Position
      if(MA_Fast[0] > MA_Slow[0] && MA_Fast[1] < MA_Slow[1])
      {
         //
         {
            do
            {
               Price = SymbolInfoDouble(Symbol(), SYMBOL_ASK);

               if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0))
               {
                  Print("Position opened in ", Symbol());
                  Sleep(800);

                  break;
               }
               else
               {
                  ErrorCount++;

                  Print("Error opening BUY position in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
               }

               if(ErrorCount == ErrCnt)
               {
                  Print("Error count = ", ErrCnt);
               }
            }
            while(ErrorCount < ErrCnt);
         }
      }

      // Open SELL Position
      if(MA_Fast[0] < MA_Slow[0] && MA_Fast[1] > MA_Slow[1])
      {
         //
         {
            do
            {
               Price = SymbolInfoDouble(Symbol(), SYMBOL_BID);

               if(m_Trade.PositionOpen(Symbol(), ORDER_TYPE_SELL, LotSize, Price, 0, 0))
               {
                  Print("Position opened in ", Symbol());
                  Sleep(800);

                  break;
               }
               else
               {
                  ErrorCount++;

                  Print("Error opening SELL position in ", Symbol(), " - ", m_Trade.ResultComment(), "\n", "Return Code Desc - ", m_Trade.ResultRetcodeDescription());
               }

               if(ErrorCount == ErrCnt)
               {
                  Print("Error count = ", ErrCnt);
               }
            }
            while(ErrorCount < ErrCnt);
         }
      }
   }

//---

   long     Pos_OT, Pos_HT;
   double   Pos_OP;

   if(PositionSelect(Symbol()))
   {
      Pos_OT = PositionGetInteger(POSITION_TIME);
      Pos_HT = TimeCurrent() - Pos_OT;
      Pos_OP = PositionGetDouble(POSITION_PRICE_OPEN);
      Price  = PositionGetDouble(POSITION_PRICE_CURRENT);

      if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
      {
         // Take Profit
         if(Price - Pos_OP >= TP * AdjPoints)
         {
            m_Trade.PositionClose(Symbol(), SymSpread);

            Sleep(800);
         }

         // Stop Loss
         if(Pos_OP - Price >= SL * AdjPoints)
         {
            m_Trade.PositionClose(Symbol(), SymSpread);

            Sleep(800);
         }
      }

      if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
      {
         // Take Profit
         if(Pos_OP - Price >= TP * AdjPoints)
         {
            m_Trade.PositionClose(Symbol(), SymSpread);

            Sleep(800);
         }

         // Stop Loss
         if(Price - Pos_OP >= SL * AdjPoints)
         {
            m_Trade.PositionClose(Symbol(), SymSpread);

            Sleep(800);
         }
      }
   }

//---
  }
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
//---
  }
//+------------------------------------------------------------------+
//| Copy Buffer As Series                                            |
//+------------------------------------------------------------------+
bool CopyBufferAsSeries(int handle, int buffer, int start, int number, bool asSeries, double &M[])
  {
//---

   if(CopyBuffer(handle, buffer, start, number, M) <= 0) return(false);

   ArraySetAsSeries(M, asSeries);

   return(true);

//---
  }
//+------------------------------------------------------------------+
//| Trade Count                                                      |
//+------------------------------------------------------------------+
int TradeCount(ENUM_TIMEFRAMES TimeFrame)
  {
//---

   int      Cnt;
   ulong    Ticket;
   long     EntryType;
   datetime DT[1];

   Cnt = 0;

   if(CopyTime(Symbol(), TimeFrame, 0, 1, DT) <= 0)
   {
      Cnt = -1;
   }
   else
   {
      HistorySelect(DT[0], TimeCurrent());

      for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
      {
         Ticket    = HistoryDealGetTicket(i);
         EntryType = HistoryDealGetInteger(Ticket, DEAL_ENTRY);

         if(EntryType == DEAL_ENTRY_IN)
         if(Symbol() == HistoryDealGetString(Ticket, DEAL_SYMBOL))
         {
            Cnt++;
         }
      }
   }

//---
   return(Cnt);
  }
 
谢谢你,如果我发现什么,我会让你知道。
原因: