Besoin d'aide pour repérer une légère erreur. - page 2

 
Si quelqu'un veut donner un coup de main, il peut le faire à l'adresse ......
 

Une partie du problème est la façon dont vous avez écrit ce code avec de longues conditions if pleines de &&, ||, et des appels de fonction après appel de fonction, ce qui le rend difficile à déboguer, vous auriez de la chance si quelqu'un avait le temps de démêler ce fouillis. Vous devriez regarder les exemples de codage dans les docs pour voir comment le code devrait être formaté en lignes beaucoup plus courtes et commenté.

 

" Makes it difficult to debug " ?? :( Je n'ai jamais entendu parler de cela, est-ce réel ? ....

Le compilateur a également du mal à déboguer mon code :( ?

Si c'est la raison, je dois repenser toute mon idée de codage pour cette partie. Alors cela va devenir une chose totalement différente ...... :( :(

 

Oui, il est difficile de déboguer, par exemple, regardez ce code pour le trailing stop. Il est facile de voir ce que fait chaque ligne et donc de repérer les erreurs.

   int total=OrdersTotal();
   
   for(int cnt=0; cnt<total; cnt++)
   {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
    {if(OrderType()==OP_BUY)
     {if(TrailingStop>0)
      {if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {if(OrderStopLoss()<Bid-Point*TrailingStop)
        {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
         {Print("OrderModify error ",GetLastError());
          return;
   }}}}}}}
 
J'ai essayé de supprimer la condition && et de les mettre dans une instruction if comme après ..... Mais cela ne fonctionne toujours pas, parfois le stop loss n'est déplacé qu'une seule fois, parfois cela fonctionne parfaitement pour les ordres d' achat et de vente.
 
SDC: Oui, il est difficile de déboguer, par exemple, regardez ce code pour le trailing stop. Il est facile de voir ce que fait chaque ligne et donc de repérer les erreurs.
   int total=OrdersTotal();
   
   for(int cnt=0; cnt<total; cnt++)
   {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
    {if(OrderType()==OP_BUY)
     {if(TrailingStop>0)
      {if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {if(OrderStopLoss()<Bid-Point*TrailingStop)
        {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
         {Print("OrderModify error ",GetLastError());
          return;
   }}}}}}}
  1. Vous DEVEZ compter à rebours lors de la fermeture/suppression en présence de plusieurs ordres. Pensez à l'EA sur d'autres graphiques. Prenez-en l'habitude.
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
        {if(OrderType()==OP_BUY)
         {if(TrailingStop>0)
          {if(Bid-OrderOpenPrice()>Point*TrailingStop)
           {if(OrderStopLoss()<Bid-Point*TrailingStop)
            {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
             {Print("OrderModify error ",GetLastError());
              return;
       }}}}}}}
    Préférez également ++x à x++ (surtout lorsqu'il s'agit de classes).
  2. Le langage est constitué d'instructions for() et if(), il est donc peu logique de mettre des accolades autour d'une seule instruction.
    Vous n'écririez pas
    mais
    { i = 1 + 2; }
    { if(i == 3) { Print(i); } }
    i = 1 + 2;
    if(i == 3) Print(i);
    Simplifions donc
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       if(OrderType()==OP_BUY)
       if(TrailingStop>0)
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  3. Maintenant que "&&" (et "||") sont des opérateurs de court-circuit, n'enchaînez pas les "si".
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && TrailingStop>0)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  4. Voulez-vous modifier l'ordre lorsque la sélection de l'ordre a échoué?
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(O rderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && TrailingStop>0)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  5. Retirez de la boucle tous les tests qui ne changent pas.
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
    }
  6. Ne calculez pas toujours la même chose.
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,O...
    Déterminez ce que vous voulez faire et si vous devez le faire.
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY){
          double SL = Bid - Point*TrailingStop;
          if(SL > OrderOpenPrice()    // Start trailing above open price
          && SL > OrderStopLoss()     // And it moves up ONLY
          && !OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Green))
          {  Print("OrderModify error ",GetLastError());
             return;
          }
       }
    }
  7. Qu'en est-il des autres cas ? Qu'en est-il des autres graphiques et EAs?
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)
       && OrderMagicNumber() == MyExternal
       && OrderSymbol()      == Symbol()  
       ){  
          if(OrderType()==OP_BUY)
          {
             double SL = Bid - Point*TrailingStop;
             if(SL > OrderOpenPrice()    // Start trailing above open price
             && SL > OrderStopLoss()     // And it moves up ONLY
             && !OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Green))
             {  Print("OrderModify error ",GetLastError());
                return;
             }
          }  // OP_BUY
          else // OP_SELL (or pending)
          { ...                       
          }                           
       }  // OrderSelect
    }  // Trailing

 
WHRoeder:
  1. Vous DEVEZ compter à rebours lors de la fermeture/suppression en présence de plusieurs ordres. Pensez à l'EA sur d'autres graphiques. Préférez également ++x à x++ (surtout lorsque vous traitez avec des classes).
  2. Le langage est composé d'instructions for(), if(), il est donc peu logique de mettre des accolades autour d'une seule instruction.
    Vous n'écririez pas
    mais
    Alors simplifiez
  3. Maintenant que "&&" (et "||") sont des opérateurs de court-circuit, n'enchaînez pas les ifs.
  4. Voulez-vous modifier la commande lorsque la sélection de la commande a échoué?
  5. Retirez de la boucle tous les tests qui ne changent pas.
  6. Ne calculez pas toujours la même chose. Déterminez ce que vous voulez faire et si vous devez le faire.
  7. Qu'en est-il des autres cas ? Qu'en est-il des autres graphiques et EAs?

J'ai posté ce code juste comme un exemple de code facile à lire, il ne s'agissait pas d'un exemple de fonction autonome complète.

Il s'agit de la section des ordres d'achat du code du trailing stop de l'exemple d'EA MACD de MetaQuotes inclus dans MT4.

1) C'est faux, vous pouvez compter vers le haut ou vers le bas, la boucle est plus efficace, OrdersTotal() est appelé une fois et assigné à une variable locale.

 
SDC: J'ai posté ce code juste à titre d'exemple.
J'ai posté juste un agrandissement du sujet.
 

Merci SDC . Merci aussi pour les conseils de WHRoeder. C'est utile.

J'ai essayé de remplacer OrderClosePrice() par MarketInfo dans le code précédent et le code modifié (en supprimant la condition && et en les plaçant dans une instruction if comme après, celle de la deuxième boucle for), mais le résultat est encore parfois efficace, parfois non efficace.

La boucle for pour compter le nombre total d'ordres dans le pool utilise une boucle de décompte mais avec x-- . Je ne comprends pas pourquoi vous suggérez --x cependant .

J'ai cherché sur Google "opérateurs de court-circuit" mais je ne comprends pas vraiment ce que cela signifie pour mql4, pouvez-vous m'expliquer un peu ^_^ ? ? Pourquoi est-ce mauvais de chaîner des 'if' ?

Au fait, le code ci-dessus suggéré par SDC n'est pas le code que j'utilise >.< .

 

Il n'est pas mauvais d'enchaîner les ifs. Les développeurs du langage MQL4 ont écrit le code que j'ai posté ci-dessus. C'est du code que j'ai coupé de leur exemple d'EA macd à titre d'exemple.

WHR faisait référence à un changement récent dans la façon dont les conditions && || sont évaluées, ce qui les rend désormais aussi efficaces que les conditions if enchaînées. Auparavant, elles étaient moins efficaces. Vous pouvez utiliser l'une ou l'autre méthode. Les ifs enchaînés sont utiles lorsqu'il y a des divergences dans le code et que vous pouvez utiliser 'else'.

Les longues lignes de conditions if( && || ) peuvent créer une confusion entre les parenthèses, ce qui rend la recherche d'erreurs plus difficile, c'est pourquoi je n'aime pas le faire. Il existe également une norme acceptée pour le codage qui stipule qu'il ne doit pas faire plus de 80 caractères. Beaucoup de codeurs ne prennent pas la peine d'adhérer à cette norme, et les développeurs de MQL4 continuent à créer des identifiants énumérés avec des noms très longs à utiliser dans leurs appels de fonctions avec des noms tout aussi longs, ce qui n'aide pas beaucoup le formatage du code.