OnTradeTransaction

La fonction est appelée dans les EA lorsque l'évènement TradeTransaction apparaît. La fonction permet de traiter les résultats de l'exécution des demandes de trade.

void  OnTradeTransaction()
   const MqlTradeTransaction&    trans,     // structure de la transaction de trade
   const MqlTradeRequest&        request,   // structure de la demande
   const MqlTradeResult&         result     // structure de la réponse
   );

Parameters

trans

[in]  variable de type MqlTradeTransaction décrivant une transaction effectuée sur un compte de trading.

request

[in]  variable de type MqlTradeRequest décrivant une demande de trade qui a conduit à une transaction. Elle contient les valeurs pour la transaction de type TRADE_TRANSACTION_REQUEST uniquement.

result

[in]  variable de type MqlTradeResult contenant le résultat de l'exécution d'une demande de trade qui a conduit à une transaction. Elle contient les valeurs pour la transaction de type TRADE_TRANSACTION_REQUEST uniquement.

Valeur de Retour

Aucune valeur de retour

Note

OnTradeTransaction() est appelé pour traiter l'évènement TradeTransaction envoyé par le serveur de trades au terminal dans les cas suivants :

  • envoi d'une demande de trade depuis un programme MQL5 en utilisant les fonctions OrderSend()/OrderSendAsync() et leur exécution ultérieure ;
  • envoi d'une demande de trade manuellement via l'interface utiliteur et son exécution ultérieure ;
  • activations des ordres en attente et des ordres stop sur le serveur ;
  • opérations sur le serveur de trades.

 

Les données sur le type transaction sont contenues dans le champ type de la variable trans. Les types de transactions de trades sont décrits dans l'énumération ENUM_TRADE_TRANSACTION_TYPE :

  • TRADE_TRANSACTION_ORDER_ADD — ajout d'un nouvel ordre actif
  • TRADE_TRANSACTION_ORDER_UPDATE — changement d'un ordre existant
  • TRADE_TRANSACTION_ORDER_DELETE — suppression d'un ordre de la liste des ordres actifs
  • TRADE_TRANSACTION_DEAL_ADD — ajout d'une transaction dans l'historique
  • TRADE_TRANSACTION_DEAL_UPDATE — changement d'une transaction dans l'historique
  • TRADE_TRANSACTION_DEAL_DELETE — suppression d'une transaction dans l'historique
  • TRADE_TRANSACTION_HISTORY_ADD — ajout d'un ordre dans l'historique en résultat d'une exécution ou d'une annulation
  • TRADE_TRANSACTION_HISTORY_UPDATE — changement d'un ordre dans l'historique des ordres
  • TRADE_TRANSACTION_HISTORY_DELETE — suppression d'un ordre dans l'historique des ordres
  • TRADE_TRANSACTION_POSITION — changement d'une position non lié à l'exécution d'un trade
  • TRADE_TRANSACTION_REQUEST — notification qu'une demande de trade a été traitée par le serveur et le résultat de son traitement a été reçu.

Lors du traitement des transactions de type TRADE_TRANSACTION_REQUEST, il est nécessaire d'analyser les 2ème et 3ème paramètres de la fonction OnTradeTransaction() — la demande et le résultat — pour récupérer des informations supplémentaires.

L'envoi d'une demande de trade entraîne une chaîne de transactions de trade sur un compte de trading : 1) la demande est acceptée pour traitement, 2) un ordre d'achat approprié est créé pour le compte, 3) l'ordre est ensuite exécuté, 4) l'ordre exécuté est supprimé de la liste des ordres actifs, 5) ajout à l'historique des ordres, 6) la transaction suivante est ajoutée à l'historique et 7) une nouvelle position est créée. Toutes ces étapes sont des transactions de trade. L'arrivée de chacune de ces transactions dans le terminal est l'évènement TradeTransaction. La priorité de l'arrivée de ces transactions dans le terminal n'est pas garantie. Vous ne devez donc pas vous attendre à ce qu'un groupe de transactions arrive l'un après l'autre lors du développement de votre algorithme de trading.

Lorsque les transactions sont traitées par la fonction OnTradeTransaction() de l'EA, le terminal continue à gérer les transactions de trade entrantes. Le status du compte de trading peut donc changer pendant l'exécution de OnTradeTransaction(). Par exemple, pendant qu'un programme MQL5 gère l'ajout d'un nouvel ordre, il peut être exécuté, supprimé de la liste des ordres ouverts et déplacé dans l'historique. Le programme est notifié de tous ces évènements.

La longueur de la queue de transactions est de 1024 éléments. Si OnTradeTransaction() traite déjà une autre transaction depuis longtemps, les précédentes peuvent être remplacées par de nouvelles transactions dans la queue.

La fonction OnTrade() est appelée après les appels à OnTradeTransaction() correspondants. En général, il n'y a pas de corrélation exacte entre le nombre d'appels à OnTrade() et à OnTradeTransaction(). Un appel à OnTrade() correspond à un ou plusieurs appels à OnTradeTransaction.

Chaque évènement Trade peut être le résultat d'une ou plusieurs demandes de trades. Les demandes de trades sont envoyées au serveur en utilisant OrderSend() ou OrderSendAsync(). Chaque demande peut aboutir à plusieurs évènements de trading. Vous ne pouvez pas vous fier à la phrase "Une demande - un évènement Trade", puisque le traitement des évènements peut être effectué en plusieurs étapes, et chaque opération peut changer l'état des ordres, des positions et de l'historique de trading.

EA exemple avec la fonction OnTradeTransaction()

//+------------------------------------------------------------------+
//|                                    OnTradeTransaction_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Exemple de listener des évènements TradeTransaction"
//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'expert                            |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   PrintFormat("DERNIER PING=%.f ms",
               TerminalInfoInteger(TERMINAL_PING_LAST)/1000.);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Fonction de tick de l'Expert                                     |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
 
  }
//+------------------------------------------------------------------+
//| Fonction TradeTransaction                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   static int counter=0;   // compteur d'appels à OnTradeTransaction()
   static uint lasttime=0; // heure du dernier appel à OnTradeTransaction()
//---
   uint time=GetTickCount();
//--- si la dernière transaction a été effectuée il y a plus d'1 seconde,
   if(time-lasttime>1000)
     {
      counter=0; // c'est donc une nouvelle opération de trade, et le compteur peut être réinitialisé
      if(IS_DEBUG_MODE)
         Print(" Nouvelle opération de trade");
     }
   lasttime=time;
   counter++;
   Print(counter,". ",__FUNCTION__);
//--- résultat de l'exécution de la demande de trade
   ulong            lastOrderID   =trans.order;
   ENUM_ORDER_TYPE  lastOrderType =trans.order_type;
   ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- le nom du symbole pour lequel une transaction a été effectuée
   string trans_symbol=trans.symbol;
//--- type de transaction
   ENUM_TRADE_TRANSACTION_TYPE  trans_type=trans.type;
   switch(trans.type)
     {
      case  TRADE_TRANSACTION_POSITION:   // modification de la position
        {
         ulong pos_ID=trans.position;
         PrintFormat("MqlTradeTransaction: Position  #%I64u %s modifiée: SL=%.5f TP=%.5f",
                     pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
        }
      break;
      case TRADE_TRANSACTION_REQUEST:     // envoi d'une demande de trade
         PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST");
         break;
      case TRADE_TRANSACTION_DEAL_ADD:    // ajout d'un trade
        {
         ulong          lastDealID   =trans.deal;
         ENUM_DEAL_TYPE lastDealType =trans.deal_type;
         double        lastDealVolume=trans.volume;
         //--- Identifiant du trade dans un système externe - un ticket assigné par une bourse
         string Exchange_ticket="";
         if(HistoryDealSelect(lastDealID))
            Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID);
         if(Exchange_ticket!="")
            Exchange_ticket=StringFormat("(Exchange deal=%s)",Exchange_ticket);
 
         PrintFormat("MqlTradeTransaction: %s deal #%I64u %s %s %.2f lot   %s",EnumToString(trans_type),
                     lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
        }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD// ajout d'un ordre dans l'historique
        {
         //--- Identifiant de l'ordre dans un système externe - un ticket assigné par une bourse
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_FILLED)
           {
            if(HistoryOrderSelect(lastOrderID))
               Exchange_ticket=HistoryOrderGetString(lastOrderID,ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("(Ticket boursier=%s)",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s ordre #%I64u %s %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
      default// autres transactions  
        {
         //--- Identifiant de l'ordre dans un système externe - un ticket assigné par une bourse
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_PLACED)
           {
            if(OrderSelect(lastOrderID))
               Exchange_ticket=OrderGetString(ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("(Ticket boursier=%s)",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s ordre #%I64u %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
     }
//--- ticket de l'ordre    
   ulong orderID_result=result.order;
   string retcode_result=GetRetcodeID(result.retcode);
   if(orderID_result!=0)
      PrintFormat("MqlTradeResult: ordre #%d retcode=%s ",orderID_result,retcode_result);
//---   
  }
//+------------------------------------------------------------------+
//| convertit les codes de réponses en chaînes de caractères         |
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
  {
   switch(retcode)
     {
      case 10004: return("TRADE_RETCODE_REQUOTE");             break;
      case 10006: return("TRADE_RETCODE_REJECT");              break;
      case 10007: return("TRADE_RETCODE_CANCEL");              break;
      case 10008: return("TRADE_RETCODE_PLACED");              break;
      case 10009: return("TRADE_RETCODE_DONE");                break;
      case 10010: return("TRADE_RETCODE_DONE_PARTIAL");        break;
      case 10011: return("TRADE_RETCODE_ERROR");               break;
      case 10012: return("TRADE_RETCODE_TIMEOUT");             break;
      case 10013: return("TRADE_RETCODE_INVALID");             break;
      case 10014: return("TRADE_RETCODE_INVALID_VOLUME");      break;
      case 10015: return("TRADE_RETCODE_INVALID_PRICE");       break;
      case 10016: return("TRADE_RETCODE_INVALID_STOPS");       break;
      case 10017: return("TRADE_RETCODE_TRADE_DISABLED");      break;
      case 10018: return("TRADE_RETCODE_MARKET_CLOSED");       break;
      case 10019: return("TRADE_RETCODE_NO_MONEY");            break;
      case 10020: return("TRADE_RETCODE_PRICE_CHANGED");       break;
      case 10021: return("TRADE_RETCODE_PRICE_OFF");           break;
      case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION");  break;
      case 10023: return("TRADE_RETCODE_ORDER_CHANGED");       break;
      case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS");   break;
      case 10025: return("TRADE_RETCODE_NO_CHANGES");          break;
      case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT");  break;
      case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT");  break;
      case 10028: return("TRADE_RETCODE_LOCKED");              break;
      case 10029: return("TRADE_RETCODE_FROZEN");              break;
      case 10030: return("TRADE_RETCODE_INVALID_FILL");        break;
      case 10031: return("TRADE_RETCODE_CONNECTION");          break;
      case 10032: return("TRADE_RETCODE_ONLY_REAL");           break;
      case 10033: return("TRADE_RETCODE_LIMIT_ORDERS");        break;
      case 10034: return("TRADE_RETCODE_LIMIT_VOLUME");        break;
      case 10035: return("TRADE_RETCODE_INVALID_ORDER");       break;
      case 10036: return("TRADE_RETCODE_POSITION_CLOSED");     break;
      default:
         return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode));
         break;
     }
//---
  }

Voir également

OrderSend, OrderSendAsync, OnTradeTransaction, structure de demande de trade, Structure de transaction de trade, Types de transaction de trade, Types d'opération de trade, Evènements du terminal client