Mi EA hace una doble entrada

 

Recuerdo que alguien tuvo el mismo problema y uso xxxx.

No he podido encontrar ese hilo, si alguien me puede ayudar sería un gran agradecimiento.

Mis códigos son los siguientes en 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);

Debería introducir 0,01 lote pero en su lugar introduce 0,02 lote.

Desde el diario

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****': intercambio comprar 0.01 EURUSD en el mercado colocado para la ejecución en 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****': intercambio comprar 0.01 EURUSD en el mercado

2013.12.20 08:35:00 Operaciones '800****': intercambio de comprar 0.01 EURUSD en el mercado colocado para la ejecución en 313 ms

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

 

Finalmente encontré el hilo https://www.mql5.com/en/forum/14327

me tomó 2 horas sólo para encontrar ese hilo ... de todos modos no es EA no dormir lo suficiente es por eso que hace una doble entrada?

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

Recuerdo que alguien tuvo el mismo problema y uso xxxx.

No he podido encontrar ese hilo, si alguien me puede ayudar sería un gran agradecimiento.

Mis códigos son los siguientes en On_Tick()

Debería introducir 0,01 lote pero en su lugar introduce 0,02 lote.

Desde el diario

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****': intercambio comprar 0.01 EURUSD en el mercado colocado para la ejecución en 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****': intercambio comprar 0.01 EURUSD en el mercado

2013.12.20 08:35:00 Operaciones '800****': intercambio de comprar 0.01 EURUSD en el mercado colocado para la ejecución en 313 ms

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

  • Este no es el registro del código que has puesto (¿dónde está el resultado de la sentencia Print?).
  • ¿Por qué necesitas usar Sleep()? Es innecesario.
  • ¿Por qué necesitas un bucle? Ni siquiera compruebas el motivo del error, y por tanto no lo corriges.
  • Tienes que comprobar ResultRetcode() y/o GetLastError() y no (sólo) ResultComment().
 
  • Este no es el registro del código que has publicado (¿dónde está el resultado de la sentencia Print?).

En la pestaña de expertos, no hay ninguna salida de la sentencia de impresión aparte de laposición abierta en EURUSD

el otro hilo parece resolverlo usando sleep
  • Tienes que comprobar ResultRetcode() y/o GetLastError() y no (sólo) ResultComment().

Voy a leer sobre esto

Pero conif(!PositionSelect(Symbol()))

¿por qué se sigue ejecutando 2 veces?

 
doshur:
  • Este no es el registro del código que has publicado (¿dónde está el resultado de la sentencia Print?).

En la pestaña de expertos, no hay ninguna salida de la sentencia de impresión aparte de laposición abierta en EURUSD

Ok, ¿se imprime 2 veces o no?

el otro hilo parece resolverlo usando sleep

¿Resolver qué?
  • Tienes que comprobar ResultRetcode() y/o GetLastError() y no (sólo) ResultComment().

Voy a leer sobre esto

Pero conif(!PositionSelect(Symbol()))

¿por qué se sigue ejecutando 2 veces?

Estamos tratando de encontrar la respuesta. ¿Este problema ocurre cada vez que se abre una posición?
 

Sí, se imprimió 2 veces >Posición abierta en EURUSD

El mismo problema reportado por otro usuario >https://www.mql5.com/en/forum/14327

resuelto usando sleep con 350ms

Mi EA hizo otras 2 operaciones antes de esto y están perfectamente bien.

Estoy pensando si mi EA ya había terminado de procesar la orden y el corredor aún no me ha devuelto los detalles de la operación y mi EA procesó un nuevo tick causando 2 entradas?

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

Sí, se imprimió 2 veces >Posición abierta en EURUSD

El mismo problema reportado por otro usuario >https://www.mql5.com/en/forum/14327

resuelto usando sleep con 350ms

Mi EA hizo otras 2 operaciones antes de esto y están perfectamente bien.

Estoy pensando si mi EA ya había terminado de procesar la orden y el broker aún no me ha devuelto los detalles de la operación y mi EA procesó un nuevo tick causando 2 entradas?

Esto parece una posible explicación, pero si es el caso no es normal. ¿Está utilizando el modo asíncrono? Si no es así, tu EA debe esperar la respuesta del servidor y luego sólo continuar y procesar el siguiente tick.

¿Si entiendo bien, este es un problema aleatorio y no puedes reproducirlo?

Puede intentar imprimir más información de depuración añadiendo esta línea después de la declaración de m_Trade :

m_Trade.LogLevel(LOG_LEVEL_ALL);
 
angevoyageur:

Esto parece una posible explicación, pero si es el caso no es normal. ¿Está utilizando el modo asíncrono? Si no es así, tu EA debe esperar la respuesta del servidor y luego sólo continuar y procesar el siguiente tick.

¿Si entiendo bien, este es un problema aleatorio y no puedes reproducirlo?

Puede intentar imprimir más información de depuración añadiendo esta línea después de la declaración de m_Trade :

Estoy usando la clase cTrade. ¿Está elmodo asíncrono activado por defecto?

sugieres que use esto m_Trade.SetAsyncMode(false);

¿Debo establecer esto dentro de on_init()?

 
doshur:

Estoy usando la clase cTrade. ¿Está elmodo asíncrono activado por defecto?

sugieres que use esto m_Trade.SetAsyncMode(false);

¿Debo establecer esto dentro de on_init()?

Normalmente es falso por defecto. Y con el código que estás usando debe ser falso.

Lo que reportas es "interesante", en mi opinión no es un comportamiento normal, y parece que hay un bug en alguna parte. ¿Tienes la posibilidad de publicar un código de ejemplo para reproducir el error? En cualquier caso voy a investigar sobre este tema.

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.
 

Gracias por la ayuda para investigar, adjuntaré mi plantilla con la que desarrollé mi EA. El Sleep() estaba en 100ms antes, Acabo de actualizar a ser 800 después de leer el hilo iniciado por otro usuario.

//+------------------------------------------------------------------+
//|                                                     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);
  }
 
Gracias, te aviso si encuentro algo.