Structure d'une Transaction de Trading (MqlTradeTransaction)

Lors de l'exécution de certains actions définies sur un compte de trading, son état change. De telles actions incluent :

  • L'envoi d'une demande de trading depuis n'importe application MQL5 dans le terminal client avec les fonctions OrderSend et OrderSendAsync et son exécution ;
  • L'envoi d'une demande de trading vie l'interface graphique du terminal et son exécution ;
  • L'activation des ordres en attente et des stops sur le serveur ;
  • Effectuer des opérations du côté du serveur de trades.

Les transactions de trading suivantes sont effectuées suite à ces actions :

  • traitement d'une demande de trading ;
  • changement des ordres ouverts ;
  • changement de l'historique des ordres ;
  • changement de l'historique des transactions ;
  • changement des positions.

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. Toutes ces actions sont des transactions de trading.

Le gestionnaire spécial OnTradeTransaction() est fourni dans MQL5 pour récupérer les transactions de trading appliquées à un compte. Le premier paramètre du gestionnaire est la structure MqlTradeTransaction décrivant les transactions de trading.

struct MqlTradeTransaction
  {
   ulong                         deal;             // Ticket de la transaction
   ulong                         order;            // Ticket de l'ordre
   string                        symbol;           // Symbole de trading name
   ENUM_TRADE_TRANSACTION_TYPE   type;             // Type de la transaction de trading
   ENUM_ORDER_TYPE               order_type;       // Type d'ordre
   ENUM_ORDER_STATE              order_state;      // Etat de l'ordre
   ENUM_DEAL_TYPE                deal_type;        // Type de la transaction
   ENUM_ORDER_TYPE_TIME          time_type;        // Durée de vie de l'ordre
   datetime                      time_expiration;  // Heure d'expiration de l'ordre
   double                        price;            // Prix 
   double                        price_trigger;    // Prix d'activation de l'ordre Stop limit
   double                        price_sl;         // Niveau du Stop Loss
   double                        price_tp;         // Niveau du Take Profit
   double                        volume;           // Volume en lots
   ulong                         position;         // Ticket de la position
   ulong                         position_by;      // Ticket d'une position opposée
  };

Description des Champs

Champ

Description

deal

Ticket de la transaction.

ordre

Ticket de l'ordre.

symbol

Le nom du symbole de trading, pour lequel une transaction est effectuée.

type

Type de la transaction de trading. La valeur peut être l'une des valeur de l'énumération ENUM_TRADE_TRANSACTION_TYPE.

order_type

Type de l'ordre de trading. La valeur peut être l'une des valeur de l'énumération ENUM_ORDER_TYPE.

order_state

Etat de l'ordre de trading. La valeur peut être l'une des valeur de l'énumération ENUM_ORDER_STATE.

deal_type

Type de la transaction. La valeur peut être l'une des valeur de l'énumération ENUM_DEAL_TYPE.

time_type

Durée de vie de l'ordre. La valeur peut être l'une des valeur de l'énumération ENUM_ORDER_TYPE_TIME.

time_expiration

Expiration de l'ordre en attente (pour les ordres de type ORDER_TIME_SPECIFIED et ORDER_TIME_SPECIFIED_DAY).

prix

Prix. Suivant le type de la transaction de trading, il peut être le prix d'un ordre, d'une transaction ou d'une position.

price_trigger

Prix stop (d'activation) d'un ordre stop limit (ORDER_TYPE_BUY_STOP_LIMIT et ORDER_TYPE_SELL_STOP_LIMIT).

price_sl

Prix du Stop Loss. Suivant le type de la transaction de trading, il peut être relatif à un ordre, à une transaction ou à une position.

price_tp

Prix du Take Profit. Suivant le type de la transaction de trading, il peut être relatif à un ordre, à une transaction ou à une position.

volume

Volume en lots. Suivant le type de la transaction de trading, il peut indiquer le volume actuel d'un ordre, d'une transaction ou d'une position.

position

Le ticket de la position affectée par la transaction.

position_by

Le ticket de la position opposée. Utilisé lors de la fermeture d'une position par une position opposée, c'est à dire par une position sur le même symbole ouvert dans une direction opposée.

Le principal paramètre pour l'analyse de la transaction reçue est son type spécifié dans le champ type. Par exemple, si une transaction est de type TRADE_TRANSACTION_REQUEST (un résultat du traitement de la demande a été reçue du serveur), la structure n'a qu'un seul champ rempli - type. Les autres champs ne sont pas analysés. Dans ce cas, nous pouvons analyser deux paramètres supplémentaires request et result soumis par le gestionnaire OnTradeTransaction(), comme montré ci-dessous.

Avec les données sur le type de l'opération de trading, vous pouvez décider de l'analyse de l'état actuel des ordres, des positions et des transactions sur un compte de trading. N'oubliez pas qu'une demande de trade envoyée au serveur depuis le terminal peut générer plusieurs nouvelles transactions. La priorité de leur arrivée au terminal n'est pas garantie.

La structure MqlTradeTransaction est remplie de différentes façons suivant le type (ENUM_TRADE_TRANSACTION_TYPE) de la transaction :

TRADE_TRANSACTION_ORDER_* et TRADE_TRANSACTION_HISTORY_*

Les champs suivants de la structure MqlTradeTransaction sont remplis pour les transactions de trading relatives au traitement des ordres d'ouverture (TRADE_TRANSACTION_ORDER_ADD, TRADE_TRANSACTION_ORDER_UPDATE and TRADE_TRANSACTION_ORDER_DELETE) et à l'historique des ordres (TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_HISTORY_UPDATE, TRADE_TRANSACTION_HISTORY_DELETE) :

  • order - ticket de l'ordre ;
  • symbol - nom du symbole de l'ordre ;
  • type - type de la transaction ;
  • order_type - type de l'ordre ;
  • orders_state - état actuel de l'ordre ;
  • time_type - type d'expiration de l'ordre ;
  • time_expiration - date/heure d'expiration de l'ordre (pour les ordres ayant les types d'expiration ORDER_TIME_SPECIFIED et ORDER_TIME_SPECIFIED_DAY) ;
  • price - prix de l'ordre spécifié par un client ;
  • price_trigger - prix stop de l'ordre stop limit (seulement pour ORDER_TYPE_BUY_STOP_LIMIT et ORDER_TYPE_SELL_STOP_LIMIT) ;
  • price_sl - prix du Stop Loss (rempli, si spécifié dans l'ordre) ;
  • price_tp - prix du Take Profit (rempli, si spécifié dans l'ordre) ;
  • volume - volume actuel de l'ordre (non rempli). Le volume initial de l'ordre peut être trouvé dans l'historique des ordres avec la fonction HistoryOrders* .
  • position - le ticket de la position qui a été ouverte, modifiée ou fermée comme étant le résultat de l'exécution de l'ordre. Il n'est rempli que pour les ordres au marché, il n'est pas rempli pour TRADE_TRANSACTION_ORDER_ADD.
  • position_by - le ticket de la position opposée. Il n'est rempli que pour les ordres 'close by' (pour fermer une position par une position opposée).

TRADE_TRANSACTION_DEAL_*

Les champs suivants de la structure MqlTradeTransaction sont remplis pour les transactions relatives au traitement des deals (TRADE_TRANSACTION_DEAL_ADD, TRADE_TRANSACTION_DEAL_UPDATE et TRADE_TRANSACTION_DEAL_DELETE) :

  • deal - ticket de la transaction ;
  • order - ticket de l'ordre, sur la base duquel une transaction a été effectuée ;
  • symbol - nom du symbole de la transaction ;
  • type - type de la transaction ;
  • deal_type - type de la transaction;
  • price - prix de la transaction ;
  • price_sl - prix du Stop Loss (rempli, si spécifié dans l'ordre, sur la base duquel une transaction a été effectuée) ;
  • price_tp - prix du Take Profit (rempli, si spécifié dans l'ordre, sur la base duquel une transaction a été effectuée) ;
  • volume - volume de la transaction en lots.
  • position - le ticket de la position qui a été ouverte, modifiée ou fermée comme étant le résultat de l'exécution du deal.
  • position_by - le ticket de la position opposée. Il n'est rempli que pour les deals 'out by' (fermeture d'une position par une position opposée).

TRADE_TRANSACTION_POSITION

Les champs suivants de la structure MqlTradeTransaction sont remplis pour les transactions de trading relatives au changement des positions non connectées à l'exécution des transactions (TRADE_TRANSACTION_POSITION):

  • symbol - nom du symbole de la position ;
  • type - type de la transaction ;
  • deal_type - type de la position (DEAL_TYPE_BUY ou DEAL_TYPE_SELL);
  • price - prix d'ouverture moyen pondéré de la position ;
  • price_sl - prix du Stop Loss ;
  • price_tp - prix du Take Profit ;
  • volume - volume de la position en lots, s'il a été changéif it has been changed.

Le changement de la position (ajout, changement ou clôture), comme étant le résultat de l'exécution d'une transaction, ne mène pas à une transaction TRADE_TRANSACTION_POSITION.

TRADE_TRANSACTION_REQUEST

Seul un champ de la structure MqlTradeTransaction est rempli pour les transactions décrivant le fait qu'une demande de trade a été traitée par un serveur et que le résultat a été reçu (TRADE_TRANSACTION_REQUEST):

  • type - type de la transaction ;

Un seul champ (type de la transaction de trading) doit être analysé pour ces transactions. Les deuxième et troisième paramètres de la fonction OnTradeTransaction (demande et résultat) doivent être analysés pour obtenir des données supplémentaires.

Exemple :

input int MagicNumber=1234567;
 
//--- active la classe de trading CTrade et déclare une variable de cette classe
#include <Trade\Trade.mqh>
CTrade trade;
//--- flags pour installer et supprimer l'ordre en attente
bool pending_done=false;
bool pending_deleted=false;
//--- le ticket de l'ordre en attente sera stocké ici
ulong order_ticket;
//+----------------------------------------------------------------------------------------------------+
//| Fonction d'initialisation de l'expert                                                              |
//+----------------------------------------------------------------------------------------------------+
int OnInit()
  {
//--- définit le MagicNumber pour marquer nos ordres
   trade.SetExpertMagicNumber(MagicNumber);
//--- les demandes de trade seront envoyées en mode asynchrone en utilisant la fonction OrderSendAsync()
   trade.SetAsyncMode(true);
//--- initialise la variable à zéro
   order_ticket=0;
//---
   return(INIT_SUCCEEDED);
  }
//+----------------------------------------------------------------------------------------------------+
//| Fonction de tick de l'Expert                                                                       |
//+----------------------------------------------------------------------------------------------------+
void OnTick()
  {
//--- installation d'un ordre en attente
   if(!pending_done)
     {
      double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
      bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
      //--- si la fonction BuyStop() a été effectuée avec succès
      if(res)
        {
         pending_done=true;
         //--- récupère le résultat de l'envoi de la demande depuis ctrade
         MqlTradeResult trade_result;
         trade.Result(trade_result);
         //--- récupère le request_id pour la demande envoyée
         uint request_id=trade_result.request_id;
         Print("La demande pour un ordre en attente a été envoyée. Request_ID=",request_id);
         //--- stockage du ticket de l'ordre (sera zéro si le mode asynchrone est utilisé pour l'envoi à CTrade)
         order_ticket=trade_result.order;
         //--- tout est fait, sortie rapide du handler OnTick()
         return;
        }
     }
//--- supprime l'ordre en attente
   if(!pending_deleted)
      //--- vérification supplémentaire
      if(pending_done && (order_ticket!=0))
        {
         //--- essaye de supprimer l'ordre en attente
         bool res=trade.OrderDelete(order_ticket);
         Print("OrderDelete=",res);
         //--- lorsque la demande de suppression est envoyée avec succès
         if(res)
           {
            pending_deleted=true;
            //--- récupère le résultat de l'exécution de la demande
            MqlTradeResult trade_result;
            trade.Result(trade_result);
            //--- récupère le request ID du résultat
            uint request_id=trade_result.request_id;
            //--- affichage dans le Journal
            Print("La demande de suppression de l'ordre en attente #",order_ticket,
                  " a été envoyée. Request_ID=",request_id,
                  "\r\n");
            //--- récupère le ticket de l'ordre depuis le résultat de la demande
            order_ticket=trade_result.order;
           }
        }
//---        
  }
//+----------------------------------------------------------------------------------------------------+
//| Fonction TradeTransaction                                                                          |
//+----------------------------------------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- récupère le type de la transaction comme une valeur de l'énumération
   ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;
//--- si la transaction est le résultat du traitement de la demande, seul son nom est affiché
   if(type==TRADE_TRANSACTION_REQUEST)
     {
      Print(EnumToString(type));
      //--- affiche le nom de la demande gérée
      Print("------------RequestDescription\r\n",RequestDescription(request));
      //--- affiche la description du résultat de la demande
      Print("------------ResultDescription\r\n",TradeResultDescription(result));
      //--- stocke le ticket de l'ordre pour sa suppression au prochain appel de OnTick()
      if(result.order!=0)
        {
         //--- supprime cet ordre par son ticket au prochain appel de OnTick()
         order_ticket=result.order;
         Print(" Ticket de l'ordre en attente ",order_ticket,"\r\n");
        }
     }
   else // affiche la description complète pour les transactions d'un autre type
//--- affiche la description de la transaction reçue dans le Journal
      Print("------------TransactionDescription\r\n",TransactionDescription(trans));
 
//---     
  }
//+----------------------------------------------------------------------------------------------------+
//| Retourne la description textuelle de la transaction                                                |
//+----------------------------------------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
  {
//--- 
   string desc=EnumToString(trans.type)+"\r\n";
   desc+="Symbole : "+trans.symbol+"\r\n";
   desc+="Ticket de la transaction : "+(string)trans.deal+"\r\n";
   desc+="Type de la transaction : "+EnumToString(trans.deal_type)+"\r\n";
   desc+="Ticket de l'ordre : "+(string)trans.order+"\r\n";
   desc+="Type de l'ordre : "+EnumToString(trans.order_type)+"\r\n";
   desc+="Etat de l'ordre : "+EnumToString(trans.order_state)+"\r\n";
   desc+="Type d'expiration de l'ordre : "+EnumToString(trans.time_type)+"\r\n";
   desc+="Expiration de l'ordre : "+TimeToString(trans.time_expiration)+"\r\n";
   desc+="Prix : "+StringFormat("%G",trans.price)+"\r\n";
   desc+="Déclenchement du prix : "+StringFormat("%G",trans.price_trigger)+"\r\n";
   desc+="Stop Loss : "+StringFormat("%G",trans.price_sl)+"\r\n";
   desc+="Take Profit : "+StringFormat("%G",trans.price_tp)+"\r\n";
   desc+="Volume : "+StringFormat("%G",trans.volume)+"\r\n";
   desc+="Position : "+(string)trans.position+"\r\n";
   desc+="Position by : "+(string)trans.position_by+"\r\n";
//--- retourne la chaîne de caractères obtenue
   return desc;
  }
//+----------------------------------------------------------------------------------------------------+
//| Retourne la description textuelle de la demande de trade                                           |
//+----------------------------------------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
  {
//---
   string desc=EnumToString(request.action)+"\r\n";
   desc+="Symbole : "+request.symbol+"\r\n";
   desc+="Magic Number : "+StringFormat("%d",request.magic)+"\r\n";
   desc+="Ticket de l'ordre : "+(string)request.order+"\r\n";
   desc+="Type de l'ordre : "+EnumToString(request.type)+"\r\n";
   desc+="Remplissage de l'ordre : "+EnumToString(request.type_filling)+"\r\n";
   desc+="Type d'expiration de l'ordre : "+EnumToString(request.type_time)+"\r\n";
   desc+="Expiration de l'ordre : "+TimeToString(request.expiration)+"\r\n";
   desc+="Prix : "+StringFormat("%G",request.price)+"\r\n";
   desc+="Déviation en points : "+StringFormat("%G",request.deviation)+"\r\n";
   desc+="Stop Loss : "+StringFormat("%G",request.sl)+"\r\n";
   desc+="Take Profit : "+StringFormat("%G",request.tp)+"\r\n";
   desc+="Stop Limit : "+StringFormat("%G",request.stoplimit)+"\r\n";
   desc+="Volume : "+StringFormat("%G",request.volume)+"\r\n";
   desc+="Commentaire : "+request.comment+"\r\n";
//--- retourne la chaîne de caractères obtenue
   return desc;
  }
//+----------------------------------------------------------------------------------------------------+
//| Retourne la description textuelle du résultat du traitement de la demande                          |
//+----------------------------------------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
  {
//---
   string desc="Retcode "+(string)result.retcode+"\r\n";
   desc+="Request ID : "+StringFormat("%d",result.request_id)+"\r\n";
   desc+="Ticket de l'ordre : "+(string)result.order+"\r\n";
   desc+="Ticket de la transaction : "+(string)result.deal+"\r\n";
   desc+="Volume : "+StringFormat("%G",result.volume)+"\r\n";
   desc+="Prix : "+StringFormat("%G",result.price)+"\r\n";
   desc+="Ask : "+StringFormat("%G",result.ask)+"\r\n";
   desc+="Bid : "+StringFormat("%G",result.bid)+"\r\n";
   desc+="Commentaire : "+result.comment+"\r\n";
//--- retourne la chaîne de caractères obtenue
   return desc;
  }

Voir aussi

Types de Transaction de Trading, OnTradeTransaction()