Мой эксперт выполняет двойную запись

Dua Yong Rew  

Я помню, что у кого-то была такая же проблема и он использовал 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 Trades '800****': deal #27731692 buy 0.01 EURUSD at 1.36354 done(based on order #40018327)

2013.12.20 08:35:01 Trades '800****': обмен buy 0.01 EURUSD на рынке размещен для исполнения через 331 мс

2013.12.20 08:35:01 Trades '800****': сделка #27731691 buy 0.01 EURUSD at 1.36353 выполнена (на основе ордера #40018326)

2013.12.20 08:35:00 Trades '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****': биржевая покупка 0.01 EURUSD на рынке

Dua Yong Rew  

Я наконец-то нашел эту тему 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.
Alain Verleyen  
doshur:

Я помню, что у кого-то была такая же проблема и он использовал xxxx.

Я не смог найти эту тему, если кто-то может мне помочь, это было бы большой благодарностью.

мои коды в On_Tick() следующие

Он должен ввести 0.01 лот, но вместо этого вводится 0.02 лот.

Из журнала

2013.12.20 08:35:01 Trades '800****': deal #27731692 buy 0.01 EURUSD at 1.36354 done(based on order #40018327)

2013.12.20 08:35:01 Trades '800****': обмен buy 0.01 EURUSD на рынке размещен для исполнения через 331 мс

2013.12.20 08:35:01 Trades '800****': сделка #27731691 buy 0.01 EURUSD at 1.36353 выполнена (на основе ордера #40018326)

2013.12.20 08:35:00 Trades '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 Trades '800****': exchange buy 0.01 EURUSD at market

  • Это не лог кода, который вы разместили (где результат оператора Print?).
  • Зачем вам нужно использовать Sleep()? Это лишнее.
  • Зачем вам нужен цикл? Вы даже не проверяете причину ошибки, и поэтому не исправляете ее.
  • Вы должны проверять ResultRetcode() и/или GetLastError(), а не (только) ResultComment().
Dua Yong Rew  
  • Это не лог кода, который вы опубликовали (где результат оператора Print?).

На вкладке эксперт нет никакого вывода из оператора печати, кромепозиции, открытой в EURUSD.

В другом потоке, похоже, проблема решена с помощью sleep.
  • Вы должны проверить ResultRetcode() и/или GetLastError(), а не (только) ResultComment().

Я прочитаю об этом подробнее

Ноесли if(!PositionSelect(Symbol())))

почему он все еще выполняется 2 раза?

Alain Verleyen  
doshur:
  • Это не лог кода, который вы опубликовали (где результат оператора Print?).

На вкладке эксперт нет никакого вывода из оператора печати, кромепозиции, открытой в EURUSD.

Хорошо, так он печатается 2 раза или нет ?

В другом потоке, похоже, проблема решена с помощью sleep.

Что решить?
  • Вы должны проверить ResultRetcode() и/или GetLastError(), а не (только) ResultComment().

Я прочитаю об этом подробнее

Ноесли if(!PositionSelect(Symbol())))

почему он все еще выполняется 2 раза?

Мы пытаемся найти ответ. Эта проблема возникает каждый раз, когда вы открываете позицию?
Dua Yong Rew  

Да, он напечатался 2 раза >Позиция открыта в EURUSD

Та же проблема, о которой сообщил другой пользователь >https://www.mql5.com/en/forum/14327

решена с помощью sleep с периодом 350 мс

До этого мой советник совершил 2 другие сделки, и они в полном порядке.

Я думаю, что если мой советник уже закончил обработку ордера, а брокер еще не вернул мне детали сделки, и мой советник обработал новый тик, вызвав 2 входа?

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

Да, он напечатался 2 раза >Позиция открыта в EURUSD

Та же проблема, о которой сообщил другой пользователь >https://www.mql5.com/en/forum/14327

решена с помощью sleep с периодом 350 мс

До этого мой советник совершил 2 другие сделки, и они в полном порядке.

Я думаю, что если мой советник уже закончил обработку ордера, а брокер еще не вернул мне детали сделки, и мой советник обработал новый тик, вызвав 2 входа?

Это кажется возможным объяснением, но если это так, то это ненормально. Используете ли вы асинхронный режим? Если нет, то ваш советник должен ждать ответа сервера, а затем только продолжать и обрабатывать следующий тик.

Если я правильно понимаю, это случайная проблема, и вы не можете ее воспроизвести?

Вы можете попробовать вывести больше отладочной информации, добавив эту строку после объявления m_Trade :

m_Trade.LogLevel(LOG_LEVEL_ALL);
Dua Yong Rew  
angevoyageur:

Это кажется возможным объяснением, но если это так, то это ненормально. Используете ли вы асинхронный режим? Если нет, то ваш советник должен ждать ответа сервера, а затем только продолжать и обрабатывать следующий тик.

Если я правильно понимаю, это случайная проблема, и вы не можете ее воспроизвести?

Вы можете попробовать вывести больше отладочной информации, добавив эту строку после объявления m_Trade:

Я использую класс cTrade.Включен лиасинхронный режим по умолчанию?

Вы предлагаете мне использовать это m_Trade.SetAsyncMode(false);

Я должен установить это внутри on_init()?

Alain Verleyen  
doshur:

Я использую класс cTrade.Включен лиасинхронный режим по умолчанию?

Вы предлагаете мне использовать это m_Trade.SetAsyncMode(false);

Я должен установить это внутри on_init()?

Обычно по умолчанию это false. А в том коде, который вы используете, он должен быть false.

То, что вы сообщили, "интересно", на мой взгляд, это не нормальное поведение, и, похоже, где-то есть ошибка. Есть ли у вас возможность опубликовать пример кода, чтобы воспроизвести ошибку? В любом случае, я проведу расследование по этому вопросу.

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.
Dua Yong Rew  

Спасибо за помощь в расследовании, я приложу свой шаблон, на котором я разрабатывал советника. Sleep() до этого был 100 мс, я просто обновил его до 800 после прочтения темы, начатой другим пользователем.

//+------------------------------------------------------------------+
//|                                                     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);
  }
Alain Verleyen  
Спасибо, я дам вам знать, если найду что-нибудь.
Причина обращения: