OrderSend

La fonction OrderSend() est utilisée pour exécuter des opérations de trading en envoyant des demandes à un serveur de trades.

bool  OrderSend(
   MqlTradeRequest&  request,      // structure de la demande
   MqlTradeResult&   result        // structure de la réponse
   );

Parameters

request

[in]  Un pointeur vers une structure de type MqlTradeRequest qui décrit l'activité de trading du client.

result

[in,out]  Un pointeur vers une structure de type MqlTradeResult qui décrit le résultat d'une opération de trading en cas d'exécution réussie de la fonction (si true est retourné).

Valeur de Retour

Si la vérification de base des structures réussit (vérification des pointeurs), elle retourne true. Cependant, ce n'est pas le signe de l'exécution réussie d'une opération de trading. Pour une description plus détaillée du résultat de l'exécution de la fonction, analysez les champs de la structure result .

Note

Les demandes de trades passent par plusieurs étapes de vérification sur le serveur de trades. Premièrement, il vérifie que tous les champs requis des paramètres de la requête sont remplis correctement. S'il n'y a pas d'erreur, le serveur accepte l'ordre pour son traitement ultérieur. Si l'ordre est accepté par le serveur de trades, la fonction OrderSend() retourne true.

Il est recommandé de vérifier la requête avant de l'envoyer au serveur de trades. Pour vérifier les demandes, utilisez la fonction OrderCheck(). Il vérifie s'il y a des fonds suffisants pour exécuter l'opération de trading, et retourne différents paramètres utiles dans les résultats de vérification de la demande de trade :

  • le code de retour contenant les information sur les erreurs dans la requête vérifiée ;
  • le solde qui apparaîtra après l'exécution de l'opération de trading ;
  • la valeur des fonds qui apparaîtra après l'exécution de l'opération de trading ;
  • la valeur du point qui apparaîtra après l'exécution de l'opération de trading ;
  • la marge requise pour l'opération de trading ;
  • montant des capitaux libres qui resteront après l'exécution de l'opération de trading ;
  • le niveau de marge qui sera déterminé après l'exécution de l'opération de trading ;
  • commentaire au code de réponse, descriptionde l'erreur.

Lors de l'envoi d'un ordre au marché (MqlTradeRequest.action=TRADE_ACTION_DEAL), le succès de la fonction OrderSend() ne signifie pas que l'ordre a été exécuté (les trades correspondants ont été effectués). Dans ce cas, 'true' ne signifie que que l'ordre a été placé avec succès dans le système de trading pour son exécution ultérieure. Le serveur de trades peut remplir les valeurs du champ de la transaction ou de l'ordre dans la structure de résultat retournée, si ces données sont connues au moment de la formation de la réponse à un appel à OrderSend(). Généralement, les évènements d'exécution des trades correspondant à un ordre peuvent se produire après l'envoi d'une réponse à l'appel OrderSend(). Pour n'importe quel type de demande de trade, lorsque vous recevez le résultat de l'exécution de OrderSend(), vous devriez donc vérifier d'abord le retcode du code de réponse du serveur de trades et le code de réponse du système externe retcode_external (si nécessaire) disponible dans la structure result obtenue.

Chaque ordre accepté est stocké sur le serveur de trades en attendant sont traitement jusqu'à ce que l'une des conditions pour son exécution se produise :

  • expiration,
  • arrivée d'une demande opposée,
  • exécution de l'ordre lorsque le prix d'exécution apparaît,
  • arrivée d'une demande pour annuler l'ordre.

Au moment du traitement de l'ordre, le serveur de trades envoie un message au terminal à propos de l'occurence de l'évènement Trade, qui peut être traité par la fonction OnTrade().

Le résultat de l'exécution de la demande de trade sur un serveur envoyé par la fonction OrderSend() peut être suivi avec la fonction de gestion OnTradeTransaction. Il est à noter que la fonction OnTradeTransaction sera appelée plusieurs fois lors de l'exécution d'une demande de trade.

Par exemple, lors de l'envoi d'un ordre d'achat, il est pris en compte par le gestionnaire, un ordre d'achat correspondant est créé pour le compte, l'ordre est ensuite exécuté et supprimé de la liste des ordres ouverts, puis il est ajouté à l'historique des ordres, une transaction correspondante est ajoutée à l'hisorique et une nouvelle position est créée. La fonction OnTradeTransaction sera appelée pour chacun de ces évènements.

Exemple :

//--- valeur de ORDER_MAGIC
input long order_magic=55555;
//+------------------------------------------------------------------+
//| Fonction de démarrage du script                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- on s'assure que c'est un compte de démo
   if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
     {
      Alert("L'utilisation d'un script n'est pas autorisée sur un compte réel !");
      return;
     }
//--- place ou suprimer des ordres
   if(GetOrdersTotalByMagic(order_magic)==0) 
     {
      //--- aucun ordre en cours, place un ordre
      uint res=SendRandomPendingOrder(order_magic);
      Print("Code de retour du serveur de trades ",res);
     }
   else // il y a des ordres, supprime les ordres
     {
      DeleteAllOrdersByMagic(order_magic);
     }
//---
  }
//+------------------------------------------------------------------+
//| Retourne le nombre d'ordres en cours avec l'ORDER_MAGIC spécifié |
//+------------------------------------------------------------------+
int GetOrdersTotalByMagic(long const magic_number)
  {
   ulong order_ticket;
   int total=0;
//--- parcours tous les ordres en attente
   for(int i=0;i<OrdersTotal();i++)
      if((order_ticket=OrderGetTicket(i))>0)
         if(magic_number==OrderGetInteger(ORDER_MAGIC)) total++;
//---
   return(total);
  }
//+------------------------------------------------------------------+
//| Supprime tous les ordres en attente avec l'ORDER_MAGIC spécifié  |
//+------------------------------------------------------------------+
void DeleteAllOrdersByMagic(long const magic_number)
  {
   ulong order_ticket;
//--- parcours tous les ordres en attente
   for(int i=OrdersTotal()-1;i>=0;i--)
      if((order_ticket=OrderGetTicket(i))>0)
         //--- ordre avec l'ORDER_MAGIC spécifié
         if(magic_number==OrderGetInteger(ORDER_MAGIC))
           {
            MqlTradeResult result={};
            MqlTradeRequest request={};
            request.order=order_ticket;
            request.action=TRADE_ACTION_REMOVE;
            OrderSend(request,result);
            //--- écrit la réponse du serveur dans le journal
            Print(__FUNCTION__,": ",result.comment," code de réponse ",result.retcode);
           }
//---
  }
//+------------------------------------------------------------------+
//| Définit un ordre en attente de façon aléatoire                   |
//+------------------------------------------------------------------+
uint SendRandomPendingOrder(long const magic_number)
  {
//--- prépare une requête
   MqlTradeRequest request={};
   request.action=TRADE_ACTION_PENDING;         // définit un ordre en attente
   request.magic=magic_number;                  // ORDER_MAGIC
   request.symbol=_Symbol;                      // symbole
   request.volume=0.1;                          // volume de 0,1 lots
   request.sl=0;                                // le Stop Loss n'est pas spécifié
   request.tp=0;                                // le Take Profit n'est pas spécifié     
//--- définit le type de l'ordre
   request.type=GetRandomType();                // type de l'ordre
//--- définit le prix de l'ordre en attente
   request.price=GetRandomPrice(request.type);  // prix d'ouverture
//--- envoie la demande de trade
   MqlTradeResult result={};
   OrderSend(request,result);
//--- écrit la réponse du serveur dans le journal  
   Print(__FUNCTION__," :",result.comment);
   if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- code de retour de la réponse du serveur de trade
   return result.retcode;
  }
//+------------------------------------------------------------------+
//| Retourne un type d'ordre en attente de façon aléatoire           |
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE GetRandomType()
  {
   int t=MathRand()%4;
//---   0<=t<4
   switch(t)
     {
      case(0):return(ORDER_TYPE_BUY_LIMIT);
      case(1):return(ORDER_TYPE_SELL_LIMIT);
      case(2):return(ORDER_TYPE_BUY_STOP);
      case(3):return(ORDER_TYPE_SELL_STOP);
     }
//--- valeur incorrecte
   return(WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Retourne un prix de façon aléatoire                              |
//+------------------------------------------------------------------+
double GetRandomPrice(ENUM_ORDER_TYPE type)
  {
   int t=(int)type;
//--- niveaux de stops pour le symbole
   int distance=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
//--- récupère les données du dernier tick
   MqlTick last_tick={};
   SymbolInfoTick(_Symbol,last_tick);
//--- calcule le prix selon le type
   double price;
   if(t==2 || t==5) // ORDER_TYPE_BUY_LIMIT ou ORDER_TYPE_SELL_STOP
     {
      price=last_tick.bid; // à partir du prix Bid
      price=price-(distance+(MathRand()%10)*5)*_Point;
     }
   else             // ORDER_TYPE_SELL_LIMIT ou ORDER_TYPE_BUY_STOP
     {
      price=last_tick.ask; // à partir du price Ask
      price=price+(distance+(MathRand()%10)*5)*_Point;
     }
//---
   return(price);
  }

Voir également

Types d'une Opération de Trading, Structure de Demande de Trade, Structure de Résultat de la Vérification d'une Demande, Structure de Résultat d'une Demande de Trade