Minha EA faz uma entrada dupla

 

Eu me lembro de alguém que tinha o mesmo problema e usava xxxx.

Eu não conseguia encontrar esse fio, se alguém pudesse me ajudar isso seria um grande agradecimento.

meus códigos como segue em 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);

Deve entrar 0,01 lote, mas em vez disso entrou 0,02 lote.

A partir da revista

2013.12.20 08:35:01 Negociações '800****': negócio #27731692 compra 0.01 EURUSD a 1.36354 feito(com base no pedido #40018327)

2013.12.20 08:35:01 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado colocado para execução em 331 ms

2013.12.20 08:35:01 Negociações '800****': negócio #27731691 compra 0.01 EURUSD a 1.36353 feito (com base no pedido #40018326)

2013.12.20 08:35:00 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado

2013.12.20 08:35:00 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado colocado para execução em 313 ms

2013.12.20 08:35:00 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado

 

Finalmente encontrei o fio https://www.mql5.com/en/forum/14327

demorei 2 horas só para encontrar esse fio... de qualquer forma não é a EA não dormir o tempo suficiente, por isso faz uma entrada dupla?

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

Eu me lembro de alguém que tinha o mesmo problema e usava xxxx.

Eu não conseguia encontrar esse fio, se alguém pudesse me ajudar isso seria um grande agradecimento.

meus códigos como segue em On_Tick()

Deve entrar 0,01 lote, mas em vez disso entrou 0,02 lote.

A partir da revista

2013.12.20 08:35:01 Negociações '800****': negócio #27731692 compra 0.01 EURUSD a 1.36354 feito(com base no pedido #40018327)

2013.12.20 08:35:01 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado colocado para execução em 331 ms

2013.12.20 08:35:01 Negociações '800****': negócio #27731691 compra 0.01 EURUSD a 1.36353 feito (com base no pedido #40018326)

2013.12.20 08:35:00 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado

2013.12.20 08:35:00 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado colocado para execução em 313 ms

2013.12.20 08:35:00 Negociações '800****': compra de câmbio 0.01 EURUSD no mercado

  • Este não é o registro do código que você postou (onde está o resultado da declaração de impressão ?).
  • Por que você precisa usar Sleep() ? É desnecessário.
  • Por que você precisa de um loop ? Você nem mesmo verifica o motivo do erro, e por isso não o corrige.
  • Você tem que verificar ResultRetcode() e/ou GetLastError() e não (somente) ResultComment().
 
  • Este não é o registro do código que você postou (onde está o resultado da declaração de impressão ?).

Sob a guia de especialista, não há saída da declaração de impressão que não seja aposição aberta em EURUSD

o outro fio parece resolvê-lo usando o sono
  • Você tem que verificar ResultRetcode() e/ou GetLastError() e não (somente) ResultComment().

Eu vou ler sobre estes

Mas comif(!PositionSelect(Symbol()))

por que ele ainda está executando 2 vezes?

 
doshur:
  • Este não é o registro do código que você postou (onde está o resultado da declaração de impressão ?).

Sob a guia de especialista, não há saída da declaração de impressão que não seja aposição aberta em EURUSD

Ok, então é impresso 2 vezes ou não ?

o outro fio parece resolvê-lo usando o sono

Resolver o que ?
  • Você tem que verificar ResultRetcode() e/ou GetLastError() e não (somente) ResultComment().

Eu vou ler sobre estes

Mas comif(!PositionSelect(Symbol()))

por que ele ainda está executando 2 vezes?

Estamos tentando encontrar a resposta. Este problema ocorre cada vez que você está abrindo uma posição?
 

Sim, ele imprimiu 2 vezes >Posição aberta em EURUSD

Mesmo problema relatado por outro usuário >https://www.mql5.com/en/forum/14327

resolvido usando o sono com 350ms

Minha EA fez 2 outros negócios antes disso e estão perfeitamente bem.

Estou pensando se minha EA já tinha terminado de processar o pedido e o corretor ainda não me devolveu os detalhes comerciais e minha EA processou um novo tick causando 2 entradas?

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

Sim, ele imprimiu 2 vezes >Posição aberta em EURUSD

Mesmo problema relatado por outro usuário >https://www.mql5.com/en/forum/14327

resolvido usando o sono com 350ms

Minha EA fez 2 outros negócios antes disso e estão perfeitamente bem.

Estou pensando se minha EA já tinha terminado de processar o pedido e o corretor ainda não me devolveu os detalhes comerciais e minha EA processou um novo tick causando 2 entradas?

Esta parece ser uma explicação possível, mas se for o caso, não é normal. Você está usando o modo assíncrono? Se não, seu EA deve esperar a resposta do servidor e então apenas continuar e processar o próximo tick.

Se eu entender bem, esta é uma questão aleatória e você não pode reproduzi-la?

Você pode tentar imprimir mais informações de depuração adicionando esta linha após a declaração do m_Trade :

m_Trade.LogLevel(LOG_LEVEL_ALL);
 
angevoyageur:

Isto parece uma explicação possível, mas se for o caso, não é normal. Você está usando o modo assíncrono? Se não, seu EA deve esperar a resposta do servidor e então apenas continuar e processar o próximo tick.

Se eu entender bem, esta é uma questão aleatória e você não pode reproduzi-la?

Você pode tentar imprimir mais informações de depuração adicionando esta linha após a declaração do m_Trade :

Eu estou usando a classe cTrade. Omodo assíncrono está ligado por padrão?

você sugere que eu use este m_Trade.SetAsyncMode(false);

Devo configurar isto dentro de on_init()?

 
doshur:

Eu estou usando a classe cTrade. Omodo assíncrono está ligado por padrão?

você sugere que eu use este m_Trade.SetAsyncMode(false);

Devo configurar isto dentro de on_init()?

Normalmente é falso por padrão. E com o código que você está usando, deve ser falso.

O que você relatou é "interessante", na minha opinião não é um comportamento normal, e parece que há um bug em algum lugar. Você tem a possibilidade de postar um código de amostra para reproduzir o erro? Em qualquer caso, vou investigar sobre este assunto.

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.
 

Obrigado pela ajuda para investigar, vou anexar meu modelo onde eu costumava desenvolver minha EA. O Sleep() estava a 100ms antes, eu só o atualizei para 800 após a leitura da thread iniciada por outro usuário.

//+------------------------------------------------------------------+
//|                                                     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);
  }
 
Obrigado, se eu encontrar alguma coisa, eu o informarei.