Loop e chiusura o cancellazione di ordini

 

Questo è uno degli errori più comuni che vedo, probabilmente dovuto in parte a spazzatura come Expert Advisor Builder. Così ho pensato che fosse il momento di un thread dedicato all'argomento in modo che possa essere collegato per riferimenti futuri.

Il problema

Facciamo un semplice esempio; vogliamo una funzione per chiudere tutti gli ordini aperti per il nostro EA, ci sono molti esempi ma creiamone uno da zero.

Abbiamo bisogno di un ciclo perché vogliamo chiudere tutti i nostri ordini per uno specifico EA, all'interno di questo ciclo avremo del codice per selezionare l'ordine, il codice per controllare che sia il simbolo e il numero magico corretti e infine il codice per chiudere l'ordine:

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

Questo codice è cattivo . . . NON USATELO. . . Spiegherò perché nella prossima sezione . . .

La spiegazione

Lavoriamo attraverso il codice di cui sopra . . . linea per linea, ordine per ordine . . .

Supponiamo di avere i seguenti ordini che vogliamo chiudere, tutti hanno lo stesso numero magico e simbolo del nostro EA, quindi vogliamo che il nostro codice li chiuda tutti:

Posizione Numero d'ordine
0111
1222
2 333
3444
4555

1a esecuzione del ciclo:

il valore iniziale di PositionIndex è 0 quindi viene selezionato l'ordine alla posizione 0, il biglietto numero 111, questo ordine viene cancellato con successo e gli ordini rimanenti cambiano posizione come segue:

Posizione Numero del biglietto
0222
1 333
2444
3555

2a esecuzione del ciclo:

ora il valore di PositionIndex è 1 quindi viene selezionato l'ordine in posizione 1, il ticket numero 333, questo ordine viene cancellato con successo e i restanti ordini cambiano posizione come segue:

Posizione Numero del biglietto
0222
1 444
2555

3a esecuzione del ciclo:

ora il valore di PositionIndex è 2 quindi viene selezionato l'ordine in posizione 2, il biglietto numero 555, questo ordine viene cancellato con successo e gli ordini rimanenti cambiano posizione come segue:

Posizione Numero del biglietto
0222
1 444

4a esecuzione del ciclo:

ora il valore di PositionIndex è 3 OrderSelect() cerca di selezionare l'ordine alla posizione 3 e fallisce, il continue porta l'esecuzione del codice al valore successivo nel ciclo .


5° e ultima esecuzione del ciclo:

ora il valore diPositionIndex è 4 OrderSelect() cerca di selezionare l'ordine alla posizione 4 e fallisce, il continue porta l'esecuzione del codice al prossimo valore nel ciclo . . . il ciclo è finito.


Ora siamo rimasti con 2 ordini, i biglietti 222 e 444 che avrebbero dovuto essere chiusi ma non lo sono stati . . . poi, come risolvere questo problema.

La soluzione

Il codice seguente è l'approccio corretto quando si chiudono gli ordini aperti o si cancellano gli ordini in sospeso. . .

La differenza chiave è che il ciclo decrementa da ( TotalNumberOfOrders - 1 ) a 0

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

Ancora una volta lavoriamo attraverso il codice di cui sopra ... linea per linea, ordine per ordine ...

Abbiamo gli stessi ordini di prima:

Posizione Numero del biglietto
0111
1222
2333
3444
4555

1a esecuzione del ciclo:

il valore iniziale di PositionIndex è TotalNumberOfOrders - 1 che è uguale a 5 - 1 = 4, quindi viene selezionato l'ordine in posizione 4, numero di ticket 555, questo ordine viene cancellato con successo e gli ordini rimanenti cambiano posizione come segue:

Posizione Numero del biglietto
0111
1222
2333
3444

2a esecuzione del ciclo:

ora il valore di PositionIndex è 3 quindi viene selezionato l'ordine in posizione 3, il biglietto numero 444, questo ordine viene cancellato con successo e gli ordini rimanenti cambiano posizione come segue:

Posizione Numero del biglietto
0111
1222
2333

3a esecuzione del ciclo:

ora il valore di PositionIndex è 2 quindi viene selezionato l'ordine in posizione 2, il biglietto numero 333, questo ordine viene cancellato con successo e i restanti ordini cambiano posizione come segue:

Posizione Numero del biglietto
0111
1222

4a esecuzione del ciclo:

ora il valore di PositionIndex è 1 quindi viene selezionato l'ordine in posizione 1, il biglietto numero 222, questo ordine viene cancellato con successo e i restanti ordini cambiano posizione come segue:

Posizione Numero del biglietto
0111

5° e ultimo giro del ciclo:

ora il valore di PositionIndex è 0 quindi viene selezionato l'ordine in posizione 0, biglietto numero 111, questo ordine viene cancellato con successo, il valore 0 è l'ultimo valore valido per il ciclo . . . il ciclo è finito .

Abbiamo cancellato con successo tutti i nostri ordini corrispondenti . . .

Link a questo thread: Loop e chiusura o cancellazione di ordini

 

Facciamo un esempio più complesso...

Supponiamo di avere i seguenti ordini che vogliamo chiudere, tutti hanno lo stesso numero magico ma alcuni hanno un simbolo diverso dal nostro EA, vogliamo che il nostro codice chiuda gli ordini per lo stesso simbolo del nostro EA, EURUSD:

Posizione Numero del biglietto Simbolo
0111 EURUSD
1222 EURUSD
2333GBPUSD
3444 EURUSD
4555 EURUSD


1a esecuzione del ciclo:

il valore iniziale di PositionIndex è TotalNumberOfOrders - 1 che è uguale a 5 - 1 = 4, quindi viene selezionato l'ordine in posizione 4, numero di ticket 555, questo ordine corrisponde al numero magico e al simbolo quindi viene cancellato con successo e gli ordini rimanenti cambiano posizione come segue:

Posizione Numero del biglietto Simbolo
0111EURUSD
1222EURUSD
2333GBPUSD
3444EURUSD

2a esecuzione del ciclo:

ora il valore di PositionIndex è 3 quindi viene selezionato l'ordine in posizione 3, numero di ticket 444, questo ordine corrisponde al numero magico e al simbolo quindi viene cancellato con successo e gli ordini rimanenti cambiano posizione come segue:

Posizione Numero del biglietto Simbolo
0111EURUSD
1222EURUSD
2333GBPUSD


3a esecuzione del ciclo:

ora il valore di PositionIndex è 2 quindi viene selezionato l'ordine in posizione 2, numero di ticket 333, questo ordine corrisponde al numero magico ma NON alsimbolo quindi non viene cancellato, i restanti ordini non cambiano:

Posizione Numero del biglietto Simbolo
0111EURUSD
1222EURUSD
2333GBPUSD

4a esecuzione del ciclo:

ora il valore di PositionIndex è 1 quindi viene selezionato l'ordine in posizione 1, numero di ticket 222, questo ordine corrisponde al numero magico e al simbolo quindi viene cancellato con successo e gli ordini rimanenti cambiano posizione come segue:

Posizione Numero del biglietto Simbolo
0111EURUSD
1333GBPUSD

5° e ultima esecuzione del ciclo:

ora il valore di PositionIndex è 0 quindi viene selezionato l'ordine in posizione 0, il ticket numero 111, questo ordine viene cancellato con successo, il valore 0 è l'ultimo valore valido per il ciclo . .. il ciclo è finito.

Abbiamo cancellato con successo tutti i nostri ordini corrispondenti lasciando l'unico ordine che non corrispondeva al nostro simbolo, il ticket numero 333 ora in posizione 0 . . .

Posizione Numero del biglietto Simbolo
0333GBPUSD


Collegamento a questo thread: Loop e chiusura o cancellazione di ordini

 
Vedi anche perché devi fare il conto alla rovescia E testare lo stato di OrderSelect
 

Grazie a Raptor per questa importante spiegazione.

Y.

 
Questo è estremamente utile per me, re dei costruttori di expert advisor spazzatura! Oh, come mi diverto a lavorare sul codice risultante. Molte grazie.
 

Caspita. Tutte quelle informazioni per chiudere un ordine.

Mi chiedo quante informazioni ci vorrebbero per ottenere 50+ pips al giorno, costantemente, ogni giorno (in media) - senza fallire, negli ultimi 137 trade.

Mostrami come fare qualcosa del genere, e lo considererei un'informazione estremamente utile e Guru, sarà il tuo titolo, per sempre, Amen.

 
CFx:

Caspita. Tutte quelle informazioni per chiudere un ordine.

Mi chiedo quante informazioni ci vorrebbero per ottenere 50+ pips al giorno, costantemente, ogni giorno (in media) - senza fallire, negli ultimi 137 scambi.

Non mi interessano i pips...cosa posso farci? Non posso spenderli, qual è il tasso di GBPPIPS? Dimostri la tua ignoranza contando il successo in pips . . .
 
CFx:

Mi chiedo quante informazioni ci vorrebbero per ottenere 50+ pips al giorno, costantemente, ogni giorno (in media) - senza fallire, negli ultimi 137 scambi.

Mostrami come fare una cosa del genere, e la considererò un'informazione estremamente utile e Guru, sarà il tuo titolo, per sempre, Amen.

  1. Non dirottare il thread con informazioni fuori tema
  2. NON ti mostreremo questo perché non hai letto le regole Tutte le discussioni che non riguardano MetaQuotes Language 4 e l'auto trading sono proibite
 

Raptor, so al primo sguardo del tuo post che sei abbastanza esperto in mql4. questo thread aiuta di nuovo a chiarire i miei dubbi!

 

Solo un'altra idea:

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


Saluti.

 
abstract_mind:


Solo un'altra idea:


Saluti.

sì, capire la logica dietro di MT4, è fino a voi per il codice aumentare o diminuire contatore.