Comment travailler correctement dans MT5 avec OrderSend ? - page 11

 
prostotrader:

Pas deux, un seul :)

if(transaction.type == TRADE_TRANSACTION_REQUEST && request.action == TRADE_ACTION_DEAL)

TRADE_TRANSACTION_REQUEST est nécessaire lorsque vous utilisez OrderSendAsymc pour recevoir un ticket de commande.

Alors qu'est-ce qui ne va pas ici ? Comment savoir si j'utilise spécifiquement OrderSendAsync() ?
Et je ne peux pas l'utiliser pour vérifier, par exemple, le cachet du conseiller expert qui m'a envoyé une demande de transaction ? Ou, par exemple, pour vérifier le ticket de la position à partir de laquelle la dernière transaction a été exécutée ?

Enfin, je peux utiliser cet événement pour vérifier le prix auquel la transaction a été effectuée (bien que je convienne que la vérification du prix dans cet événement n'a de sens que si l'on utilise la négociation asynchrone).

Donc, si j'utilise l'envoi asynchrone des commandes, le code est-il correct ?

 
Oleg Shenker:

Alors qu'est-ce qui ne va pas ? Comment savez-vous que j'utilise peut-être OrderSendAsync() ?
Et je ne peux pas l'utiliser pour vérifier, par exemple, le cachet du conseiller expert qui a envoyé une demande de transaction ? Ou, par exemple, pour vérifier le ticket de la position à partir de laquelle la dernière transaction a été exécutée ?

Enfin, je peux utiliser cet événement pour vérifier le prix auquel la transaction a été effectuée (bien que je convienne que la vérification du prix dans cet événement n'a de sens que si l'on utilise la négociation asynchrone).

Donc si j'utilise l'envoi asynchrone des commandes, le code est correct ?

Le sujet s'appelle

"Comment travailler correctement avec OrderSend".

Cette fonction (telle qu'elle a été conçue par les développeurs) devrait être totalement synchrone, c'est-à-dire que si vous envoyez une commande et si vous obtenez un ticket,

tout est OK pour la commande. Mais maintenant cette fonction ne fonctionne pas tout à fait correctement, donc après avoir reçu un ticket d'une commande, vous

obtenir une confirmation dans OnTradeTransaction que tout est OK.

C'est-à-dire que les données de cet ordre sont entièrement synchronisées dans le terminal.

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
           switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Данные по ордеру синхронизированы
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }
 
prostotrader:

Le sujet s'appelle

"Comment travailler correctement avec OrderSend".

Cette fonction (telle qu'elle a été conçue par les développeurs) devrait être totalement synchrone, c'est-à-dire que si vous envoyez une commande et si vous obtenez un ticket,

tout est OK pour la commande. Mais maintenant cette fonction ne fonctionne pas tout à fait correctement, donc après avoir reçu un ticket d'une commande, vous

obtenir une confirmation dans OnTradeTransaction que tout est OK.

C'est-à-dire que les données de cet ordre sont entièrement synchronisées dans le terminal.

//+------------------------------------------------------------------+
// Expert TradeTransaction function                                  |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_ORDER_UPDATE:
           switch(trans.order_state)
           {
            case ORDER_STATE_PLACED:
               if(order_ticket==trans.order)
                 {
                  Print(__FUNCTION__," Order plased done. Ticket = ",trans.order);
                  if(order_ticket>0)
                    {
                     if(OrderSelect(order_ticket))
                       {
                        //Данные по ордеру синхронизированы
                       }
                     else
                       {
                        Print(__FUNCTION__," Order not select! Ticket = ",trans.order);
                       }
                    }
                  else
                    {
                     Print(__FUNCTION__," Wrong order ticket = ",trans.order);
                    }
                 }
               break;
           }
         break;
     }
  }


Super ! Je le sais. Seulement, j'utilise l'envoi asynchrone des commandes. J'ai un problème différent, l'événement REQUEST (qui signifie finaliser les totaux de la transaction) pour la même transaction est arrivé deux fois.
 
Oleg Shenker:
Super ! Je sais comment ça marche. Seulement, j'utilise l'envoi asynchrone des commandes. J'ai un problème différent, l'événement REQUEST (dans le sens de la finalisation des totaux de la transaction) pour la même transaction est arrivé deux fois.

Vous ne comprenez pas tout à fait comment les messages OnTradeTransaction doivent être traités lors du placement d'un OrderSEndAsync.

Enregistrez cette EA et voyez comment elle fonctionne

Dossiers :
TestOrders.mq5  25 kb
 
prostotrader:

Vous ne comprenez pas bien comment les messages de OnTradeTransaction doivent être traités lors de la définition des ordres OrderSEndAsync.

Enregistrer le conseiller expert et voir comment il fonctionne

C'est ce que je vous demande, comment les TradeTransactions devraient être gérées correctement.

 
Oleg Shenker:

C'est ce que je vous demande, comment les TradeTransactions devraient être gérées correctement.

L'ordre pour OrderSendAsync est le suivant :

Lorsque vous envoyez une commande avec la commande OrderSendAsync, si la commande est envoyée avec succès, vous recevrez order_id

bool SendOrderAsyncMode()
  {
   double price=SymbolInfoDouble(Symbol(),SYMBOL_SESSION_PRICE_LIMIT_MAX);
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   order_ticket=0;
   order_id=0;
   request.action = TRADE_ACTION_PENDING;
   request.magic  = 9876543210;
   request.symbol = Symbol();
   request.volume = 1;
   request.price  = price;
   request.type=ORDER_TYPE_SELL_LIMIT;
   request.comment="Async mode";
   request.type_filling=ORDER_FILLING_RETURN;
   request.type_time=ORDER_TIME_DAY;
   if(OrderSendAsync(request,result))
     {
      if((result.retcode==TRADE_RETCODE_PLACED) || (result.retcode==TRADE_RETCODE_DONE))
        {
         if(result.request_id>0)
           {
            order_id=result.request_id;
            Print(__FUNCTION__," Order sent in async mode");
            return(true);
           }
         else
           {
            Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
           }
        }
      else
        {
         Print(__FUNCTION__," Error order sent in async mode! Retcode = ",result.retcode);
        }
     }
   else
     {
      Print(__FUNCTION__," Order not sent in async mode.");
     }
   return(false);
  }

Ensuite, nous obtenons toutes les autres données dans OnTradeTransactions.

1. Recevoir le ticket de commande

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_REQUEST:
         if((order_id>0) && (order_id==result.request_id))
           {
            order_id=0;
            order_ticket=result.order;
            Print(__FUNCTION__," Order get ticket done. Ticket = ",result.order);
           }
         break;
     }
}

2. Si vous utilisez des ordres au marché ou des ordres à cours limité (non en attente), c'est-à-dire ceux qui sont exécutés immédiatement.

ou rejeté, il est nécessaire de surveiller TRADE_TRANSACTION_HISTORY_ADD, puisque dans tous les cas 3.

Ces commandes sont ajoutées à l'historique.

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   switch(trans.type)
     {
      case TRADE_TRANSACTION_HISTORY_ADD:
         if(order_ticket==trans.order)
           {
             //Берем данные из истории
           }
         break;
    }
  }


Si vous utilisez des ordres en attente (qui peuvent être exécutés en plusieurs fois), vous devez alors surveiller

Il existe trois événements : TRADE_TRANSACTION_ORDER_UPDATE, TRADE_TRANSACTION_HISTORY_ADD, TRADE_TRANSACTION_DEAL_ADD.

TRADE_TRANSACTION_ORDER_UPDATE - sert à obtenir l'information que l'ordre a été fixé (modifié).

TRADE_TRANSACTION_DEAL_ADD - obtenir l'information qu'une transaction a été exécutée

TRADE_TRANSACTION_HISTORY_ADD - l'ordre n'est pas présent dans le système commercial ; nous pouvons visualiser les données sur l'ordre.

C'est toute la "sagesse"

Ajouté

L'interaction entreOrderSendAsync etOnTradeTransactionfonctionne sans problème.

et sur le forex (réel)

 
prostotrader:

Ajouté

OrderSendAsync etOnTradeTransactionfonctionnent bien, je l'ai vérifié sur FOREX (démo)

Les deux sur le FOREX (réel)

Merci ! Maintenant je sais comment utiliser la fonction OnTradeTransaction() ou il y a d'autres secrets ?

Comment puis-je le faire sans problème si l'événement TradeTransaction() peut se perdre ?

 
Oleg Shenker:

Merci ! Je sais maintenant comment utiliser OnTradeTransaction() ou y a-t-il d'autres secrets ?

Comment peut-il n'y avoir aucun avertissement si l'événement TradeTransaction() peut se perdre ?

Il n'y a plus de secrets.

Elle peut se perdre (mais c'est arrivé 3-4 fois en 4-5 mois et dans des moments de forte activité du marché),

donc l'assurance ne serait pas une mauvaise chose.

 

Et voici un exemple concret de contrôle d'une commande

Journal du terminal :

2017.01.05 11:46:01.673 Trades  'xxxxx': buy limit 1.00 PLT-6.17 at 952.3
2017.01.05 11:46:02.895 Trades  'xxxxx': accepted buy limit 1.00 PLT-6.17 at 952.3
2017.01.05 11:46:02.896 Trades  'xxxxx': buy limit 1.00 PLT-6.17 at 952.3 placed for execution in 1223.187 ms

Journal du conseiller expert :

2017.01.05 11:46:02.829 trader (PLT-3.17,H1)      CheckOrders: Задержка ответа сервера. Ожидание продолжается...


La commande a été envoyée le2017.01.05 11:46:01.673

Pas de réponse du serveur pendant plus d'une seconde, la commande a été vérifiée.

En mode normal, la réponse arrive en 7-10 msec.

 

Répondant à la question"Comment travailler correctement dans MT5 avec OrderSend?

Il y a une réponse simple.

Jusqu'à ce que les développeurs corrigent le problème, alors

ulong pre_ticket; //Предварительный тикет
ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
  {
    if(result.retcode==TRADE_RETCODE_DONE)
    {
      pre_ticket=result.order;
    }  
  }
//----------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
{
   switch(trans.type)
   {
     case TRADE_TRANSACTION_ORDER_UPDATE:
       if((pre_ticket>0) && (trans.order==pre_ticket))
       {
         switch(trans.order_state)
         {
           case ORDER_STATE_PLACED:
             order_ticket = pre_ticket;
           break;
         }
       }
     break;
   }
}

Et quand ils le sont, alors

ulong order_ticket; //Тикет ордера
//---
if(OrderSend(request,result))
  {
    if(result.retcode==TRADE_RETCODE_DONE)
    {
      order_ticket=result.order;
    }  
  }