Ich brauche Hilfe, um einen kleinen Fehler zu finden. - Seite 2

 
Kann mir jemand helfen? .....
 

Ein Teil des Problems ist die Art und Weise, wie Sie den Code geschrieben haben, mit langen if-Bedingungen voller &&, || und Funktionsaufrufe nach Funktionsaufrufen, was die Fehlersuche erschwert. Sie können sich glücklich schätzen, wenn Sie jemanden finden, der die Zeit hat, dieses Chaos zu entwirren. Sie sollten sich die Programmierbeispiele in der Dokumentation ansehen, um zu sehen, wie der Code in viel kürzeren Zeilen formatiert und kommentiert werden sollte.

 

" Macht es schwierig zu debuggen" :( Ich habe noch nie davon gehört, ist das wirklich ....

Der Compiler hat auch Schwierigkeiten, meinen Code zu debuggen :( ?

Wenn das der Grund ist, bedeutet das, dass ich meine ganze Kodierungsidee für diesen Teil überdenken muss :? Dann wird es eine ganz andere Sache ...... :( :(

 

Ja, es ist schwer zu debuggen. Sehen Sie sich zum Beispiel diesen Code für den Trailing-Stop an. Es ist leicht zu sehen, was jede Zeile tut daher leicht, Fehler zu erkennen.

   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;
   }}}}}}}
 
Ich habe versucht, die &&-Bedingung zu entfernen und sie in eine if-Anweisung nach .... zu setzen. Aber trotzdem funktionierte es nicht immer, manchmal wurde der Stop-Loss nur einmal verschoben, manchmal funktionierte es sowohl bei Kauf- als auch bei Verkaufsaufträgen einwandfrei.
 
SDC: Ja, es ist schwer zu debuggen. Sehen Sie sich zum Beispiel diesen Code für den Trailing Stop an. Es ist leicht zu sehen, was jede Zeile tut, daher leicht, Fehler zu erkennen.
   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. Sie MÜSSEN beim Schließen/Löschen bei Vorhandensein mehrerer Aufträge abwärts zählen. Denken Sie an den EA auf anderen Charts. Gewöhnen Sie sich daran.
       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;
       }}}}}}}
    Ziehen Sie auch ++x gegenüber x++ vor (vor allem beim Umgang mit Klassen)
  2. Die Sprache besteht aus for()-Anweisungen und if()-Anweisungen, so dass es wenig Sinn macht, geschweifte Klammern um eine einzelne Anweisung zu setzen.
    Sie würden nicht schreiben
    sondern
    { i = 1 + 2; }
    { if(i == 3) { Print(i); } }
    i = 1 + 2;
    if(i == 3) Print(i);
    Vereinfachen Sie also
       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. Da "&&" (und "||") nun Kurzschlussoperatoren sind, sollten Sie keine Wenns verketten
       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. Wollen Sie die Reihenfolge ändern, wenn die Auswahl der Reihenfolge fehlgeschlagen ist?
       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. Entfernen Sie alle Tests, die sich nicht ändern, aus der Schleife.
    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. Berechnen Sie nicht immer wieder das Gleiche.
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,O...
    Finden Sie heraus, was Sie tun wollen und ob Sie es tun sollten.
    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. Was ist mit den anderen Fällen? Was ist mit anderen Charts und 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. Sie MÜSSEN beim Schließen/Löschen in Anwesenheit mehrerer Aufträge abwärts zählen. Denken Sie an den EA auf anderen Charts. Bevorzugen Sie auch ++x gegenüber x++ (vor allem beim Umgang mit Klassen).
  2. Die Sprache besteht aus for()-Anweisungen und if()-Anweisungen, so dass es wenig Sinn macht, geschweifte Klammern um eine einzelne Anweisung zu setzen.
    Sie würden nicht schreiben
    sondern
    Vereinfachen Sie also
  3. Da "&&" (und "||") nun Kurzschlussoperatoren sind, sollten Sie keine ifs verketten.
  4. Möchten Sie die Reihenfolge ändern, wenn die Auswahl der Reihenfolge fehlgeschlagen ist?
  5. Entfernen Sie alle Tests, die sich nicht ändern, aus der Schleife.
  6. Berechnen Sie nicht immer wieder das Gleiche. Finden Sie heraus, was Sie tun wollen und ob Sie es tun sollten.
  7. Was ist mit den anderen Fällen? Was ist mit anderen Charts und EAs?

Ich habe diesen Code nur als Beispiel für einen leicht zu lesenden Code gepostet, er sollte kein Beispiel für eine abgeschlossene eigenständige Funktion sein.

Es handelt sich um den Abschnitt für Kaufaufträge des Trailing-Stop-Codes aus dem MetaQuotes MACD-Beispiel-EA, der in MT4 enthalten ist.

1) Stimmt nicht, Sie können hoch- oder runterzählen, die Schleife ist effizienter, OrdersTotal() wird einmal aufgerufen und einer lokalen Variable zugewiesen.

 
SDC: Ich habe diesen Code nur als Beispiel gepostet o
Ich habe nur eine Vergrößerung des Themas gepostet.
 

Vielen Dank SDC . Danke auch für die Tipps WHRoeder . Es ist nützlich .

Ich habe versucht, OrderClosePrice() mit dem MarketInfo im vorherigen Code zu tauschen und den Code zu bearbeiten (die &&-Bedingung zuentfernen und sie als if-Anweisung nach der in der zweiten for-Schleife zu setzen), aber das Ergebnis ist immer noch manchmal funktionierend, manchmal nicht funktionierend.

Die for-Schleife für die Zählung der Gesamtbestellungen im Pool verwendet eine Countdown-Schleife, aber mit x-- . Ich verstehe nicht, warum du --x vorschlägst.

Ich habe "Kurzschlussoperatoren" gegoogelt, aber ich verstehe nicht wirklich, was das bei mql4 bedeutet, könntest du mir das ein bisschen erklären ^_^? Warum ist es schlecht, 'if' zu verketten?

Übrigens, der obige Code, den SDC vorgeschlagen hat, ist nicht der Code, den ich verwende >.< .

 

Es ist nicht schlecht, ifs zu verketten. Die Entwickler der MQL4 Sprache schrieb den Code, den ich oben gepostet. Es ist ein Code, den ich als Beispiel aus ihrem macd-Beispiel EA ausgeschnitten habe.

WHR bezog sich auf eine kürzlich vorgenommene Änderung der Art und Weise, wie && || Bedingungen ausgewertet werden, wodurch sie jetzt genauso effizient sind wie verkettete if-Bedingungen. Zuvor waren sie weniger effizient. Sie können beide Methoden verwenden. Verkettete if-Bedingungen sind nützlich, wenn es Abweichungen im Code gibt, so dass Sie 'else' verwenden können.

Lange Zeilen mit if( && || )-Bedingungen können Klammern verwirren, was die Fehlersuche erschwert, weshalb ich das nicht gerne mache. Außerdem gibt es einen anerkannten Standard für die Kodierung, der besagt, dass sie nicht länger als 80 Zeichen sein sollte. Viele Programmierer halten sich jedoch nicht an diesen Standard, und die MQL4-Entwickler erstellen immer wieder Aufzählungsbezeichner mit langen Namen, die in ihren Funktionsaufrufen für Funktionen mit ebenso langen Namen verwendet werden, was bei der Codeformatierung nicht gerade hilfreich ist.