Discussion de l'article "Le MQL5 Cookbook : Traitement de l'événement de TradeTransaction"

 

Un nouvel article Le MQL5 Cookbook : Traitement de l'événement de TradeTransaction a été publié :

Cet article considère les capacités du langage MQL5 du point de vue de la programmation par évènement. Le plus grand avantage de cette approche est que le programme peut recevoir des informations sur la mise en œuvre progressive d'une opération de trade. L'article contient également un exemple de réception et de traitement d'informations sur les opérations de trade en cours à l'aide du gestionnaire d'événements TradeTransaction. À mon avis, une telle approche peut être utilisée pour copier des transactions d'un terminal à un autre.

Puisqu'il n'y a aucune information sur les types de transactions responsables de certaines opérations de trade, nous allons le découvrir par essais et par erreurs.

Avant cela, nous devrons créer un modèle de l'Expert qui contiendra le gestionnaire d'événements TradeTransaction. J'ai nommé ma version du modèle TradeProcessor.mq5. J'ai ajouté une fonctionnalité qui permet d'afficher des informations sur les valeurs des champs de structure dans le journal. Ces valeurs sont les paramètres de l'événement - gestionnaire. L'analyse de ces enregistrements prendra du temps, mais en fin de compte, elle paiera en présentant une image complète des événements.

Nous devons lancer l'Expert en mode débogage sur l'un des graphiques du terminal MetaTrader 5.

Ouvrez une position manuellement et jetez un coup d’œil sur le code. Le premier appel du gestionnaire sera comme ceci (Fig. 1).

Fig. 1. Le champ du type est égal à TRADE_TRANSACTION_REQUEST

Fig.1. Le champ du type est égal à TRADE_TRANSACTION_REQUEST

Auteur : Denis Kirichenko

 

D'après mon expérience, je peux dire que le véritable besoin d'utiliser TradeTransaction se fait sentir lors de la programmation en mode asynchrone. Il est dommage que l'article ne dise pas un mot sur ce mode.

s.s. Je pensais également que "What MQL recipes". - était un titre de marque des articles d'Anatoly. Mais il s'avère maintenant que ce n'est pas le cas(

 

C-4, merci pour votre avis.

C-4:

D'après mon expérience, je peux dire que le véritable besoin d'utiliser TradeTransaction se fait sentir lors de la programmation en mode asynchrone. Il est dommage que l'article ne dise pas un mot sur ce mode...

Il y a différents besoins et exigences qui peuvent justifier l'utilisation du gestionnaire TradeTransaction. C'est un sujet intéressant, j'espère que des collègues expérimentés feront également des commentaires sur cette question...

s.s. Je pensais également que "MQL recipes". - était le nom de marque des articles d'Anatoly. Il s'avère maintenant que ce n'est pas le cas(

Oui, je reconnais qu'Anatoly est l'inventeur de cette série d'articles. Je l'ai aimée, alors j'ai modestement rejoint le cycle :-))))

J'espère qu'Anatoly n'y voit pas d'inconvénient....

 
Je n'ai pas encore eu le temps de traiter la question de l'exécution partielle des ordres(ORDER_STATE_PARTIAL) dans cet article. Question pour vous : combien de fois le gestionnaire TradeTransaction sera-t-il appelé ?
 
denkir:
Je n'ai pas encore eu le temps de traiter la question de l'exécution partielle des ordres(ORDER_STATE_PARTIAL) dans cet article. Question pour vous : combien de fois le gestionnaire TradeTransaction sera-t-il appelé ?

Je n'en sais rien. Logiquement, le gestionnaire devrait être déclenché autant de fois que lors d'une exécution complète. En effet, l'exécution d'un ordre n'est pas un événement discret, et MT ne sait pas si l'ordre sera exécuté partiellement ou complètement.

s.s. Malheureusement, la livraison des événements n'est pas garantie et les événements eux-mêmes ne fonctionnent qu'en temps réel, ce qui limite leur application. Mais ils sont extrêmement utiles pour les systèmes basés sur le suivi d'état, tels que les systèmes asynchrones ou les copieurs d'échanges. Grâce aux événements, il est possible de construire un algorithme sans boucle et sans freins supplémentaires liés à l'attente d'un événement OnTimer.

 
denkir:

...

J'espère qu'Anatoly n'y voit pas d'inconvénient...

Non, bien sûr qu'il n'y voit pas d'inconvénient. ) D'autant plus que...

C-4:

...

s.s. Je pensais aussi que "MQL recipes". - était un nom de marque des articles d'Anatoly. Il s'avère maintenant que ce n'est pas le cas(

...Le label "Recettes MQL5" a été suggéré par l'équipe éditoriale de MQ, il peut donc être utilisé par n'importe qui. L'essentiel est d'avoir des articles plus nombreux et différents.

 
Le manuel de référence indique clairement que la cohérence n'est PAS garantie ! Si l'on examine les données historiques, la cohérence est tout à fait différente.
 
Merci pour cet article. Il est très utile.
 
Comment faire fonctionner le système ?
 
Excellent texte ! J'ai beaucoup appris, félicitations
 
VikMorroHun #:
Merci pour cet article. Il est très utile.

Bonjour,

Ma situation semble être assez simple : Je place un ordre en attente (Sell_Stop) et je veux être capable de réagir dans le cas où a) l'ordre en attente est rempli et enfin b) la position ouverte a été fermée par le stop loss ou l'objectif de profit.

Est-ce que je comprends bien que :

  1. lorsque l'ordre en attente a été exécuté, je ne peux obtenir le nombre magique qu'en le demandant à partir de la liste des positions bien que le paramètre "request" de OnTradeTransaction() possède le champ "magic" comme :
             if(!PositionSelectByTicket(trans.position)) {Print(__LINE__," PositionSelectByTicket FAILED ",err());}
             else {      
                OpnPos[sz].mag  = PositionGetInteger(POSITION_MAGIC);
             }   
    

  2. les différents types de transaction de telle sorte que je ne peux pas savoir si la position de vente a été ouverte ou fermée :
    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'une seconde, 
       if(time-lasttime>1000) 
         { 
          counter=0; // il s'agit alors d'une nouvelle opération commerciale, et le compteur peut être remis à zéro 
          if(IS_DEBUG_MODE) 
             Print(__LINE__," "," New trade operation dTime",time-lasttime); 
         } 
       Print(__LINE__," ",counter," ",DoubleToString((double(lasttime=time)/1000.0,2)
                ," Tr.Type: ",EnumToString(trans.type)," DL.Type: ",EnumToString(trans.deal_type)
                ," RQ.Type: ",EnumToString(request.type)," RQ.Fill: ",EnumToString(request.type_filling)
             ); 
    Ce Print produit dans le cas de l'ouverture d'une position à 01:00:40 et de la fermeture de cette position à 10:04:40 :
    01:00:40   322 0 81952.76 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_SELL RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81970.73 Tr.Type: TRADE_TRANSACTION_DEAL_ADD DL.Type: DEAL_TYPE_BUY  RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81955.30 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81980.91 Tr.Type: TRADE_TRANSACTION_ORDER_DELETE DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // close sell position
    
    01:00:40   322 0 81965.14 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY RQ.Fill: ORDER_FILLING_FOK // open sell position
    10:04:40   322 0 81982.69 Tr.Type: TRADE_TRANSACTION_HISTORY_ADD DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_BUY DL.Type: ORDER_FILLING_FOK // close sell position
    
    01:00:59   322 0 81968.50 Tr.Type: TRADE_TRANSACTION_REQUEST     DL.Type: DEAL_TYPE_BUY RQ.Type: ORDER_TYPE_SELL RQ.Fill: ORDER_FILLING_FOK // open sell position
    
    Les appels ont l'air à peu près identiques - comment cela se fait-il ? A 1:00 une vente a été ouverte - pourquoi y a-t-il 12 ..TYPE_BUY et seulement 2 TYPE_SELL ??
    Pourquoi et quelle est la signification de request.type = ORDER_TYPE_BUY dans le cas où un stop de vente est déclenché et devient une vente (position) ?? D'où vient le _BUY ?
Connaissez-vous une façon élégante de déterminer qu'une position a été fermée par un stop loss ou un objectif de profit avec les moyens (paramètres) de OnTradeTransaction() sans savoir si c'était une position de vente ou d'achat qui a été fermée ?