My EA does a double entry

 

I remember someone who had the same problem and use xxxx.

I could not find that thread, if anyone can help me out that would be a big thanks.

my codes as follow in 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);

It should enter 0.01 lot but entered 0.02 lot instead.

From the journal

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****': exchange buy 0.01 EURUSD at market placed for execution in 331 ms

2013.12.20 08:35:01 Trades '800****': deal #27731691 buy 0.01 EURUSD at 1.36353 done (based on order #40018326)

2013.12.20 08:35:00 Trades '800****': exchange buy 0.01 EURUSD at market

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

 

I finally found the thread https://www.mql5.com/en/forum/14327

it took me 2 hours just to find that thread... anyway is not EA not sleeping long enough that's why it does a double entry?

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

I remember someone who had the same problem and use xxxx.

I could not find that thread, if anyone can help me out that would be a big thanks.

my codes as follow in On_Tick()

It should enter 0.01 lot but entered 0.02 lot instead.

From the journal

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****': exchange buy 0.01 EURUSD at market placed for execution in 331 ms

2013.12.20 08:35:01 Trades '800****': deal #27731691 buy 0.01 EURUSD at 1.36353 done (based on order #40018326)

2013.12.20 08:35:00 Trades '800****': exchange buy 0.01 EURUSD at market

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

  • This isn't the log of the code you posted (where are the result of the Print statement ?).
  • Why do you need to use Sleep() ? It's unnecessary.
  • Why do you need a loop ? You don't even check the reason of the error, and so don't correct it.
  • You have to check ResultRetcode() and/or GetLastError() and not (only) ResultComment().
 
  • This isn't the log of the code you posted (where are the result of the Print statement ?).

Under the expert tab, there is no output from the print statement other than Position opened in EURUSD

the other thread seems to resolve it using sleep
  • You have to check ResultRetcode() and/or GetLastError() and not (only) ResultComment().

I will read up on these

 

But with if(!PositionSelect(Symbol()))

why is it still executing 2 times? 

 
doshur:
  • This isn't the log of the code you posted (where are the result of the Print statement ?).

Under the expert tab, there is no output from the print statement other than Position opened in EURUSD

Ok, so it's printed 2 times or not ?

the other thread seems to resolve it using sleep

Resolve what ?
  • You have to check ResultRetcode() and/or GetLastError() and not (only) ResultComment().

I will read up on these

 

But with if(!PositionSelect(Symbol()))

why is it still executing 2 times? 

We are trying to find the answer. Is this problem occurs each times you are opening a position ?
 

Yes, it printed 2 times > Position opened in EURUSD

 

Same problem reported by other user > https://www.mql5.com/en/forum/14327

resolved by using sleep with 350ms 

 

My EA made 2 other trades before this and are perfectly fine.

 

I'm thinking if my EA had already finished processing the order and the broker has yet to return me the trade details and my EA processed a new tick causing 2 entries?

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

Yes, it printed 2 times > Position opened in EURUSD

 

Same problem reported by other user > https://www.mql5.com/en/forum/14327

resolved by using sleep with 350ms 

 

My EA made 2 other trades before this and are perfectly fine.

 

I'm thinking if my EA had already finished processing the order and the broker has yet to return me the trade details and my EA processed a new tick causing 2 entries?

This seems a possible explanation, but if it's the case it's not normal. Are you using asynchronous mode ? If not, your EA must wait the reply of the server and then only continue and process the next tick.

If I understand well this is a random issue and you can't reproduce it ?

You can try to print more debug info by adding this line after the declaration of m_Trade :

m_Trade.LogLevel(LOG_LEVEL_ALL);
 
angevoyageur:

This seems a possible explication, but if it's the case it's not normal. Are you using asynchronous mode ? If not, your EA must wait the reply of the server and then only continue and process the next tick.

If I understand well this is a random issue and you can't reproduce it ?

You can try to print more debug info by adding this line after the declaration of m_Trade :

I'm using cTrade class. Is asynchronous mode on by default?

do you suggest I use this m_Trade.SetAsyncMode(false); 

I should set this inside on_init()? 

 
doshur:

I'm using cTrade class. Is asynchronous mode on by default?

do you suggest I use this m_Trade.SetAsyncMode(false); 

I should set this inside on_init()? 

Normally it's false by default. And with the code you are using it must be false.

What you reported is "interesting", in my opinion it's not a normal behavior, and it seems there is a bug somewhere. Have you the possibility to post a sample code to reproduce the error ? In any case I will investigate on this issue.

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.
 

Thanks for the help to investigate, I will attach my template where I used to develop my EA with. The Sleep() was at 100ms before, I just updated it to be 800 after reading the thread started by another user.

//+------------------------------------------------------------------+
//|                                                     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);
  }
 
Thank you I let you know if I find something.