Mon EA fait une double entrée

 

Je me souviens de quelqu'un qui avait le même problème et qui utilisait xxxx.

Je n'ai pas pu trouver ce fil de discussion, si quelqu'un peut m'aider, ce serait un grand merci.

Mes codes sont les suivants dans 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);

Il devrait entrer 0,01 lot mais il est entré 0,02 lot à la place.

Dans le 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****' : échange acheter 0.01 EURUSD au marché placé pour exécution en 331 ms

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

2013.12.20 08:35:00 Trades '800****' : échange achat 0.01 EURUSD au marché

2013.12.20 08:35:00 Trades '800****' : échange d'achat 0.01 EURUSD au marché placé pour exécution dans 313 ms

2013.12.20 08:35:00 Transactions '800****' : échange achat 0.01 EURUSD au marché

 

J'ai enfin trouvé le fil de discussion https://www.mql5.com/en/forum/14327

il m'a fallu 2 heures juste pour trouver ce fil... de toute façon ce n'est pas parce que EA ne dort pas assez longtemps qu'il fait une double entrée ?

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

Je me souviens de quelqu'un qui avait le même problème et qui utilisait xxxx.

Je n'ai pas pu trouver ce fil de discussion, si quelqu'un peut m'aider, ce serait un grand merci.

Mes codes sont les suivants dans On_Tick()

Il devrait entrer 0,01 lot mais il est entré 0,02 lot à la place.

Dans le 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****' : échange acheter 0.01 EURUSD au marché placé pour exécution en 331 ms

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

2013.12.20 08:35:00 Trades '800****' : échange achat 0.01 EURUSD au marché

2013.12.20 08:35:00 Trades '800****' : échange d'achat 0.01 EURUSD au marché placé pour exécution dans 313 ms

2013.12.20 08:35:00 Transactions '800****' : échange d'achat 0.01 EURUSD au marché

  • Ce n'est pas le log du code que vous avez posté (où sont les résultats de l'instruction Print ?).
  • Pourquoi avez-vous besoin d'utiliser Sleep() ? C'est inutile.
  • Pourquoi avez-vous besoin d'une boucle ? Vous ne vérifiez même pas la raison de l'erreur, et donc ne la corrigez pas.
  • Vous devez vérifier ResultRetcode() et/ou GetLastError() et non (seulement) ResultComment().
 
  • Ce n'est pas le journal du code que vous avez posté (où sont les résultats de l'instruction d'impression ?).

Dans l'onglet expert, il n'y a pas de résultat de l'instruction d'impression autre que laposition ouverte en EURUSD.

L'autre sujet semble résoudre le problème en utilisant sleep
  • Vous devez vérifier ResultRetcode() et/ou GetLastError() et non (seulement) ResultComment().

Je vais me documenter sur ces questions.

Mais avecif( !PositionSelect(Symbol()))

pourquoi est-ce qu'il s'exécute encore 2 fois ?

 
doshur:
  • Ce n'est pas le journal du code que vous avez posté (où sont les résultats de l'instruction d'impression ?).

Dans l'onglet expert, il n'y a pas de résultat de l'instruction d'impression autre que laposition ouverte en EURUSD.

Ok, donc c'est imprimé 2 fois ou pas ?

L'autre sujet semble résoudre le problème en utilisant sleep

Résoudre quoi ?
  • Vous devez vérifier ResultRetcode() et/ou GetLastError() et non (seulement) ResultComment().

Je vais me documenter sur ces questions.

Mais avecif( !PositionSelect(Symbol()))

pourquoi est-ce qu'il s'exécute encore 2 fois ?

Nous essayons de trouver la réponse. Ce problème se produit-il chaque fois que vous ouvrez une position ?
 

Oui, il s'est imprimé 2 fois >Position ouverte en EURUSD

Même problème signalé par un autre utilisateur >https://www.mql5.com/en/forum/14327

résolu en utilisant sleep avec 350ms

Mon EA a fait 2 autres transactions avant cela et tout va bien.

Je pense que si mon EA avait déjà fini de traiter l'ordre et que le courtier ne m'a pas encore renvoyé les détails de la transaction, mon EA a traité un nouveau tick causant 2 entrées ?

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

Oui, il s'est imprimé 2 fois >Position ouverte en EURUSD

Même problème signalé par un autre utilisateur >https://www.mql5.com/en/forum/14327

résolu en utilisant sleep avec 350ms

Mon EA a fait 2 autres transactions avant cela et tout va bien.

Je pense que si mon EA avait déjà fini de traiter l'ordre et que le courtier ne m'a pas encore renvoyé les détails de la transaction, mon EA a traité un nouveau tick causant 2 entrées ?

Cela semble une explication possible, mais si c'est le cas, ce n'est pas normal. Utilisez-vous le mode asynchrone ? Si non, votre EA doit attendre la réponse du serveur et ensuite seulement continuer et traiter le prochain tick.

Si je comprends bien, il s'agit d'un problème aléatoire et vous ne pouvez pas le reproduire ?

Vous pouvez essayer d'imprimer plus d'informations de débogage en ajoutant cette ligne après la déclaration de m_Trade :

m_Trade.LogLevel(LOG_LEVEL_ALL);
 
angevoyageur:

Cela semble une explication possible, mais si c'est le cas, ce n'est pas normal. Utilisez-vous le mode asynchrone ? Si non, votre EA doit attendre la réponse du serveur et ensuite seulement continuer et traiter le prochain tick.

Si je comprends bien, il s'agit d'un problème aléatoire et vous ne pouvez pas le reproduire ?

Vous pouvez essayer d'imprimer plus d'informations de débogage en ajoutant cette ligne après la déclaration de m_Trade :

J'utilise la classe cTrade. Lemode asynchrone est-ilactivé par défaut ?

Suggérez-vous que j'utilise ceci : m_Trade.SetAsyncMode(false);

Je dois mettre cela dans on_init() ?

 
doshur:

J'utilise la classe cTrade. Lemode asynchrone est-ilactivé par défaut ?

Suggérez-vous que j'utilise ceci m_Trade.SetAsyncMode(false);

Je dois le définir dans on_init() ?

Normalement c'est false par défaut. Et avec le code que vous utilisez, il doit être false.

Ce que vous avez signalé est "intéressant", à mon avis ce n'est pas un comportement normal, et il semble qu'il y ait un bug quelque part. Avez-vous la possibilité de poster un exemple de code pour reproduire l'erreur ? Dans tous les cas, je vais enquêter sur ce problème.

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.
 

Merci pour l'aide à l'investigation, je vais joindre mon modèle avec lequel j'ai développé mon EA. Le Sleep() était à 100 ms auparavant, je viens de le mettre à 800 après avoir lu le fil de discussion lancé par un autre utilisateur.

//+------------------------------------------------------------------+
//|                                                     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);
  }
 
Merci, je vous ferai savoir si je trouve quelque chose.