Boucles et fermeture ou suppression d'ordres

 

C'est l'une des erreurs les plus courantes que je vois, probablement due en partie à des déchets tels que Expert Advisor Builder. J'ai donc pensé qu'il était temps de consacrer un fil de discussion à ce sujet afin de pouvoir y faire référence à l'avenir.

Le problème

Prenons un exemple simple ; nous voulons une fonction pour fermer tous les ordres ouverts pour notre EA, il y a beaucoup d'exemples mais créons-en un à partir de zéro.

Nous avons besoin d'une boucle parce que nous voulons fermer tous nos ordres pour un EA spécifique, dans cette boucle nous aurons du code pour sélectionner l'ordre, du code pour vérifier que le symbole et le numéro magique sont corrects et enfin du code pour fermer l'ordre :

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

Ce code est mauvais. . . NE L'UTILISEZ PAS. . . Je vais vous expliquer pourquoi dans la section suivante...

L'explication

Travaillons à travers le code ci-dessus... ligne par ligne, ordre par ordre....

Supposons que nous avons les ordres suivants que nous voulons clôturer, ils ont tous le même numéro magique et le même symbole que notre EA, donc nous voulons que notre code les clôture tous :

Position Numéro de ticket
0111
1222
2 333
3444
4555

1er passage dans la boucle :

la valeur initiale de PositionIndex est 0 donc l'ordre en position 0 est sélectionné, le ticket numéro 111, cet ordre est supprimé avec succès et les ordres restants changent de position comme suit :

Position Numéro de ticket
0222
1 333
2444
3555

2ème passage dans la boucle :

maintenant la valeur de PositionIndex est 1 donc l'ordre en position 1 est sélectionné, le ticket numéro 333, cet ordre est supprimé avec succès et les ordres restants changent de position comme suit:

Position Numéro de ticket
0222
1 444
2555

3ème passage dans la boucle :

maintenant la valeur de PositionIndex est 2 donc l'ordre en position 2 est sélectionné, le ticket numéro 555, cet ordre est supprimé avec succès et les ordres restants changent de position comme suit:

Position Numéro de ticket
0222
1 444

4ème exécution de la boucle :

maintenant la valeur de PositionIndex est 3 OrderSelect() essaie de sélectionner l'ordre à la position 3 et échoue, le continue prend l'exécution du code à la valeur suivante dans la boucle ...


5e et dernière exécution de la boucle :

maintenant la valeur de PositionIndex est 4 OrderSelect() essaie de sélectionner l'Ordre à la position 4 et échoue, le continue prend l'exécution du code à la valeur suivante dans la boucle ... la boucle est terminée.


Nous nous retrouvons avec deux commandes, les tickets 222 et 444, qui auraient dû être fermés mais ne l'ont pas été... Comment résoudre ce problème ?

La solution

Le code suivant est l'approche correcte pour fermer des ordres ouverts ou supprimer des ordres en attente...

La différence essentielle est que la boucle décrémente de ( TotalNumberOfOrders - 1 ) à 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

Reprenons le code ci-dessus... ligne par ligne, ordre par ordre...

Nous avons les mêmes ordres que précédemment :

Position Numéro de ticket
0111
1222
2333
3444
4555

1er passage dans la boucle :

la valeur initiale de PositionIndex est TotalNumberOfOrders - 1 qui est égal à 5 - 1 = 4, donc l'ordre en position 4 est sélectionné, ticket numéro 555, cet ordre est supprimé avec succès et les ordres restants changent de position comme suit :

Position Numéro de ticket
0111
1222
2333
3444

2ème passage dans la boucle :

maintenant la valeur de PositionIndex est 3 donc l'ordre en position 3 est sélectionné, le ticket numéro 444, cet ordre est supprimé avec succès et les ordres restants changent de position comme suit:

Position Numéro de ticket
0111
1222
2333

3ème passage dans la boucle :

maintenant la valeur de PositionIndex est 2 donc l'ordre en position 2 est sélectionné, le ticket numéro 333, cet ordre est supprimé avec succès et les ordres restants changent de position comme suit:

Position Numéro de ticket
0111
1222

4ème passage dans la boucle :

maintenant la valeur de PositionIndex est 1 donc l'ordre en position 1 est sélectionné, le ticket numéro 222, cet ordre est supprimé avec succès et les ordres restants changent de position comme suit:

Position Numéro de ticket
0111

5ème et dernière exécution de la boucle :

maintenant la valeur de PositionIndex est 0 donc l'ordre en position 0 est sélectionné, ticket numéro 111, cet ordre est supprimé avec succès, la valeur 0 est la dernière valeur valide pour la boucle ... la boucle est terminée.

Nous avons supprimé avec succès tous les ordres correspondants....

Lien vers cette discussion : Boucles et fermeture ou suppression d'ordres

 

Prenons un exemple plus complexe....

Supposons que nous ayons les ordres suivants que nous voulons fermer, ils ont tous le même numéro magique mais certains ont un symbole différent de notre EA, nous voulons que notre code ferme les ordres pour le même symbole que notre EA, EURUSD :

Position Numéro de ticket Symbole
0111 EURUSD
1222 EURUSD
2333GBPUSD
3444 EURUSD
4555 EURUSD


1er passage dans la boucle :

la valeur initiale de PositionIndex est TotalNumberOfOrders - 1 qui est égal à 5 - 1 = 4, donc l'ordre en position 4 est sélectionné, numéro de ticket 555, cet ordre correspond au numéro magique et au symbole donc est supprimé avec succès et les ordres restants changent de position comme suit :

Position Numéro de ticket Symbole
0111EURUSD
1222EURUSD
2333GBPUSD
3444EURUSD

2ème passage dans la boucle :

maintenant la valeur de PositionIndex est 3 donc l'ordre en position 3 est sélectionné, numéro de ticket 444, cet ordre correspond au numéro magique et au symbole donc est supprimé avec succès et les ordres restants changent de position comme suit:

Position Numéro de ticket Symbole
0111EURUSD
1222EURUSD
2333GBPUSD


3ème passage dans la boucle :

maintenant la valeur de PositionIndex est 2 donc l'ordre en position 2 est sélectionné, numéro de ticket 333, cet ordre correspond au numéro magique mais PAS au symbole donc il n'est pas supprimé, les ordres restants ne changent pas:

Position Numéro de ticket Symbole
0111EURUSD
1222EURUSD
2333GBPUSD

4ème passage dans la boucle :

maintenant la valeur de PositionIndex est 1 donc l'ordre en position 1 est sélectionné, numéro de ticket 222, cet ordre correspond au numéro magique et au symbole donc est supprimé avec succès et les ordres restants changent de position comme suit:

Position Numéro de ticket Symbole
0111EURUSD
1333GBPUSD

5ème et dernière exécution de la boucle :

maintenant la valeur de PositionIndex est 0 donc l'ordre en position 0 est sélectionné, ticket numéro 111, cet ordre est supprimé avec succès, la valeur 0 est la dernière valeur valide pour la boucle ... la boucle est terminée.

Nous avons supprimé avec succès tous nos ordres correspondants, laissant le seul ordre qui ne correspondait pas à notre symbole, le ticket numéro 333, maintenant en position 0....

Position Numéro de ticket Symbole
0333GBPUSD


Lien vers cette discussion : Boucles et fermeture ou suppression d'ordres

 
Voir aussi pourquoi vous devez faire un compte à rebours ET tester le statut de l'OrderSelect.
 

Merci à Raptor pour cette importante explication.

Y.

 
Ceci est extrêmement utile pour moi, le roi de l'ordure expert conseiller constructeur ! Oh, comme j'aime bien m'attaquer au code qui en résulte. Merci beaucoup.
 

Wow. Toutes ces informations pour fermer un ordre.

Je me demande combien d'informations il faudrait pour obtenir plus de 50 pips par jour, de façon constante, tous les jours (en moyenne) - sans faute, au cours des 137 dernières transactions.

Montrez-moi comment faire quelque chose comme ça, et je considérerais cela comme une information extrêmement utile et Gourou, sera votre titre, pour toujours et à jamais, Amen.

 
CFx:

Wow. Toutes ces informations pour fermer un ordre.

Je me demande combien d'informations il faudrait pour obtenir plus de 50 pips par jour, de façon constante, tous les jours (en moyenne) - sans faute, au cours des 137 dernières transactions.

Les pips ne m'intéressent pas... que puis-je en faire ? Je ne peux pas les dépenser, quel est le taux de GBPPIPS ? vous montrez votre ignorance en comptant le succès en pips....
 
CFx:

Je me demande combien d'informations il faudrait pour obtenir plus de 50 pips par jour, de façon constante, tous les jours (en moyenne) - sans faute, au cours des 137 dernières transactions.

Montrez-moi comment faire quelque chose comme ça, et je considérerais cela comme une information extrêmement utile et Gourou, sera votre titre, pour toujours et à jamais, Amen.

  1. Ne détournez pas le fil de discussion avec des informations hors sujet.
  2. Nous n'allons PAS vous montrer cela parce que vous n'avez pas lu les règles. Toutes les discussions autres que celles concernant le langage MetaQuotes 4 et le trading automatique sont interdites.
 

Raptor, je sais au premier coup d'oeil de votre post que vous êtes tout à fait un expert dans mql4.ce fil de discussion encore aide à clarifier mes doutes!continuez le bon travail.tnx

 

Juste une autre idée :

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


Salutations.

 
abstract_mind:


Juste une autre idée :


Salutations.

Oui, comprenez la logique de MT4, c'est à vous de coder l'augmentation ou la diminution du compteur.