Schleifen und Schließen oder Löschen von Aufträgen

 

Dies ist einer der häufigsten Fehler, die ich sehe, wahrscheinlich zum Teil auf die wie Müll wie Expert Advisor Builder. So dachte ich, es war Zeit für einen Thread zu diesem Thema gewidmet, so dass es für zukünftige Referenz verlinkt werden kann.

Das Problem

Nehmen wir ein einfaches Beispiel; wir wollen eine Funktion, um alle offenen Aufträge für unsere EA zu schließen, gibt es viele Beispiele, aber lassen Sie uns eine von Grund auf neu erstellen.

Wir brauchen eine Schleife, weil wir alle unsere Aufträge für einen bestimmten EA schließen wollen. Innerhalb dieser Schleife haben wir Code, um den Auftrag auszuwählen, Code, um zu prüfen, ob es das richtige Symbol und die richtige magische Zahl ist und schließlich Code, um den Auftrag zu schließen:

int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = 0; PositionIndex < TotalNumberOfOrders; PositionIndex++)  //  <-- for loop to loop through all Orders
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?

      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      
   } //  end of For loop

Dieser Code ist schlecht . . . VERWENDEN SIE IHN NICHT. . . Ich werde im nächsten Abschnitt erklären, warum...

Die Erläuterung

Gehen wir den obigen Code durch, Zeile für Zeile, Auftrag für Auftrag...

Nehmen wir an, wir haben die folgenden Aufträge, die wir schließen wollen. Sie haben alle die gleiche magische Zahl und das gleiche Symbol wie unser EA, also soll unser Code sie alle schließen:

Position Ticket-Nummer
0111
1222
2 333
3444
4555

Erster Durchlauf durch die Schleife:

Der Anfangswert von PositionIndex ist 0, so dass der Auftrag an Position 0 ausgewählt wird, Ticketnummer 111, dieser Auftrag wird erfolgreich gelöscht und die verbleibenden Aufträge ändern ihre Position wie folgt:

Position Ticket-Nummer
0222
1 333
2444
3555

Zweiter Durchlauf durch die Schleife:

Der Wert von PositionIndex ist jetzt 1, so dass der Auftrag an Position 1 ausgewählt wird, Ticketnummer 333, dieser Auftrag wird erfolgreich gelöscht und die verbleibenden Aufträge ändern ihre Position wie folgt:

Position Ticket-Nummer
0222
1 444
2555

3. Durchlauf durch die Schleife:

Jetzt istder Wert von PositionIndex 2, so dass der Auftrag an Position 2 ausgewählt wird, Ticketnummer 555, dieser Auftrag wird erfolgreich gelöscht und die verbleibenden Aufträge ändern ihre Position wie folgt:

Position Ticket-Nummer
0222
1 444

4. Durchlauf durch die Schleife:

jetzt ist der Wert von PositionIndex 3 OrderSelect() versucht, die Order an Position 3 auszuwählen und scheitert, der continue nimmt die Ausführung des Codes zum nächsten Wert in der Schleife . .


5. und letzter Durchlauf der Schleife:

jetzt ist der Wert von PositionIndex gleich 4 OrderSelect() versucht, die Order an Position 4 auszuwählen und schlägt fehl, der Continue führt den Code zum nächsten Wert in der Schleife aus . . . die Schleife ist beendet.


Wir haben jetzt noch 2 Aufträge, die Tickets 222 und 444, die eigentlich hätten abgeschlossen werden müssen, es aber nicht wurden ... und nun die Frage, wie man dieses Problem lösen kann.

Die Lösung

Der folgende Code ist der richtige Ansatz, wenn offene Aufträge geschlossen oder schwebende Aufträge gelöscht werden sollen.

Der wesentliche Unterschied besteht darin, dass die Schleife von ( TotalNumberOfOrders - 1 ) auf 0 dekrementiert

int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      
   } //  end of For loop

Gehen wir noch einmal den obigen Code durch - Zeile für Zeile, Auftrag für Auftrag.

Wir haben die gleichen Aufträge wie zuvor:

Position Ticket-Nummer
0111
1222
2333
3444
4555

1. Durchlauf durch die Schleife:

Der Anfangswert von PositionIndex ist TotalNumberOfOrders - 1, was gleich 5 - 1 = 4 ist, also wird der Auftrag an Position 4 ausgewählt, Ticketnummer 555, dieser Auftrag wird erfolgreich gelöscht und die verbleibenden Aufträge ändern ihre Position wie folgt:

Position Ticket-Nummer
0111
1222
2333
3444

Zweiter Durchlauf durch die Schleife:

Der Wert von PositionIndex ist jetzt 3, also wird die Bestellung an Position 3 ausgewählt, Ticketnummer 444, diese Bestellung wird erfolgreich gelöscht und die verbleibenden Bestellungen ändern ihre Position wie folgt:

Position Ticket-Nummer
0111
1222
2333

3. Durchlauf durch die Schleife:

Der Wert von PositionIndex istjetzt 2, so dass der Auftrag an Position 2 ausgewählt wird, Ticketnummer 333, dieser Auftrag wird erfolgreich gelöscht und die verbleibenden Aufträge ändern ihre Position wie folgt:

Position Ticket-Nummer
0111
1222

4. Durchlauf durch die Schleife:

Der Wert von PositionIndex istjetzt 1 , so dass der Auftrag an Position 1 ausgewählt wird, Ticketnummer 222, dieser Auftrag wird erfolgreich gelöscht und die verbleibenden Aufträge ändern ihre Position wie folgt:

Position Ticket-Nummer
0111

5. und letzter Durchlauf durch die Schleife:

jetzt ist der Wert von PositionIndex 0 also wird der Auftrag an Position 0 ausgewählt, Ticketnummer 111, dieser Auftrag wird erfolgreich gelöscht, Wert 0 ist der letzte gültige Wert für die Schleife ... die Schleife ist beendet.

Wir haben alle übereinstimmenden Aufträge erfolgreich gelöscht...

Link zu diesem Thema: Schleifen und Schließen oder Löschen von Aufträgen

 

Nehmen wir ein komplexeres Beispiel....

Nehmen wir an, wir haben die folgenden Aufträge, die wir schließen wollen, sie haben alle die gleiche magische Nummer, aber einige haben ein anderes Symbol als unser EA, wir wollen, dass unser Code die Aufträge für das gleiche Symbol wie unser EA, EURUSD, schließt:

Position Ticket-Nummer Symbol
0111 EURUSD
1222 EURUSD
2333GBPUSD
3444 EURUSD
4555 EURUSD


1. Durchlauf durch die Schleife:

Der anfängliche Wert von PositionIndex ist TotalNumberOfOrders - 1, was gleich 5 - 1 = 4 ist, also wird die Order an Position 4 ausgewählt, Ticketnummer 555, diese Order stimmt mit der magischen Nummer und dem Symbol überein und wird daher erfolgreich gelöscht und die verbleibenden Orders ändern ihre Position wie folgt:

Position Ticket-Nummer Symbol
0111EURUSD
1222EURUSD
2333GBPUSD
3444EURUSD

2. Durchlauf durch die Schleife:

jetzt ist der Wert von PositionIndex 3, also wird die Order an Position 3 ausgewählt, Ticketnummer 444, diese Order stimmt mit der magischen Nummer und dem Symbol überein und wird dahererfolgreich gelöscht und die verbleibenden Orders ändern ihre Position wie folgt:

Position Ticket-Nummer Symbol
0111EURUSD
1222EURUSD
2333GBPUSD


3. Durchlauf durch die Schleife:

jetzt istder Wert von PositionIndex 2, also wird die Order an Position 2 ausgewählt, Ticketnummer 333, diese Order stimmt mit der magischen Nummer überein, aber NICHT mitdem Symbol, alsowirdsie nicht gelöscht, die übrigen Orders ändern sich nicht:

Position Ticket Nummer Symbol
0111EURUSD
1222EURUSD
2333GBPUSD

4. Durchlauf durch die Schleife:

Der Wert von PositionIndex istjetzt 1 , also wird die Order an Position 1 ausgewählt, Ticketnummer 222, diese Order stimmt mit der magischen Nummer und dem Symbol überein, alsowird erfolgreich gelöscht und die verbleibenden Orders ändern ihre Position wie folgt:

Position Ticket-Nummer Symbol
0111EURUSD
1333GBPUSD

5. und letzter Durchlauf durch die Schleife:

Der Wert von PositionIndex ist jetzt 0 , also wird der Auftrag an Position 0 ausgewählt, Ticketnummer 111, dieser Auftrag wird erfolgreich gelöscht, der Wert 0 ist der letzte gültige Wert für die Schleife ... die Schleife ist beendet.

Wir haben alle übereinstimmenden Aufträge erfolgreich gelöscht, bis auf den einen Auftrag, der nicht mit unserem Symbol übereinstimmte, Ticketnummer 333, der jetzt an Position 0 steht ...

Position Ticket-Nummer Symbol
0333GBPUSD


Link zu diesem Thema: Schleifen und Schließen oder Löschen von Aufträgen

 
Siehe auch, warum Sie den OrderSelect-Status abwärts zählen UND testen müssen
 

Vielen Dank, Raptor, für diese wichtige Erklärung.

Y.

 
Das ist äußerst hilfreich für mich, den König der Müll-Expert Advisor Builder! Oh, wie sehr ich es genieße, auf den resultierenden Code herumzuhacken. Vielen Dank!
 

Wow! All diese Informationen für das Schließen eines Auftrags.

Ich frage mich, wie viele Informationen es bräuchte, um 50+ Pips pro Tag zu erzielen, konsistent, jeden Tag (im Durchschnitt) - ohne Fehler, durch die letzten 137 Trades.

Zeigen Sie mir, wie man so etwas macht, und ich würde es als äußerst hilfreiche Information betrachten, und Guru, soll Ihr Titel sein, für immer und ewig, Amen.

 
CFx:

Wow! All diese Informationen für das Schließen eines Auftrags.

Ich frage mich, wie viele Informationen es braucht, um 50+ Pips pro Tag zu erzielen, und zwar jeden Tag (im Durchschnitt) - ohne Fehler, über die letzten 137 Trades.

Ich habe kein Interesse an Pips ... was kann ich mit ihnen machen? Ich kann sie nicht ausgeben, wie hoch ist die GBPPIPS-Rate? Sie zeigen Ihre Unwissenheit, indem Sie den Erfolg in Pips zählen...
 
CFx:

Ich frage mich, wie viele Informationen es braucht, um 50+ Pips pro Tag zu erzielen, konstant, jeden Tag (im Durchschnitt) - ohne Fehler, durch die letzten 137 Trades.

Zeigen Sie mir, wie man so etwas macht, und ich würde es als äußerst hilfreiche Information betrachten, und Guru, soll Ihr Titel sein, für immer und ewig, Amen.

  1. Don't Hijack Thread mit off topic Informationen
  2. Wir werden Ihnen das NICHT zeigen, weil Sie die Regeln nicht gelesen haben. Alle Diskussionen, die nicht MetaQuotes Language 4 und den automatischen Handel betreffen, sind verboten.
 

Raptor, ich weiß auf den ersten Blick von ur Post, dass u r ganz n Experte in mql4.this Thread wieder hilft klar meine Zweifel! halten Sie die guten works.tnx

 

Nur eine weitere Idee:

for(PositionIndex = 0; PositionIndex < OrdersTotal() ; PositionIndex ++)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
         add_trade_to_close_queue( OrderTicket());  // <--  You need to model the queue mechanism ...
      
   } //  end of For loop


Mit freundlichen Grüßen.

 
abstract_mind:


Nur eine weitere Idee:


Mit freundlichen Grüßen.

ja, verstehen Sie die Logik hinter MT4, es ist bis zu Ihnen, um Code erhöhen oder verringern Zähler.
Grund der Beschwerde: