Traitement des transactions (OnTradeTransaction)

 

Bonsoir.

Les gars, s'il vous plaît, aidez-moi à comprendre. Le problème n'est probablement pas nouveau, mais je n'ai pas trouvé de solution unique (ni en pratique ni sur les forums).

J'exécute deux robots différents dans le terminal sur deux instruments différents. Les magies sont différentes partout. Le robot place des limites en attente et la procédure OnTradeTransaction me permet de détecter une transaction et de placer des ordres stop en attente en utilisant cette transaction.

Voici le code de la transaction commerciale

case TRADE_TRANSACTION_DEAL_ADD:
        {
         drop_info2("TRADE_TRANSACTION_DEAL_ADD\r\n"+TransactionDescription(trans));
         if((trans.deal_type==DEAL_TYPE_BUY || trans.deal_type==DEAL_TYPE_SELL) && trans.order!=0)
           {
            if(getIsDealOfExpert(trans.deal)) //функция проверки принадлежности сделки к роботу
              {
               drop_info2("Сделка наша");
               analyzeFilledOrder(trans.order,trans.volume); //процедура по выставлению отложенных стоп ордеров
              }
           }
        }
      break;

Voici le code de la fonction qui vérifie si l'affaire appartient à un robot

bool getIsDealOfExpert(ulong dealTicket)
     {
      if(HistoryDealSelect(dealTicket) && HistoryDealGetInteger(dealTicket,DEAL_MAGIC)==magic_number && HistoryDealGetString(dealTicket,DEAL_SYMBOL)==symbol)
         return true;
      else
         return false;
     }

Voici le code de la procédure pour les ordres stop en attente

void analyzeFilledOrder(ulong orderTicket,double volume)
  {
   bool isFindOrder=false;
   string fullComment;
   ENUM_ORDER_TYPE orderType;
   if(getIsOrderOfExpert(orderTicket,true)) //Если ордер из сделки уже в истории
     {
      fullComment=HistoryOrderGetString(orderTicket,ORDER_COMMENT);
      orderType=ENUM_ORDER_TYPE(HistoryOrderGetInteger(orderTicket,ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли в истории
     }
   if(!isFindOrder && getIsOrderOfExpert(orderTicket,false)) //Если не нашли ордер в истории и ордер есть не в истории
     {
      fullComment=OrderGetString(ORDER_COMMENT); 
      orderType=ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли не в истории
     }
   if(isFindOrder) //если хоть где-то нашли, то выставляем отложенные стоп ордера
     {
     //выставляем стоп ордера

Voici le code de la fonction de recherche d'un ordre dans l'historique et hors de l'historique

bool getIsOrderOfExpert(ulong OrderTicket,bool isHistory)
     {
      bool is_expert=false;
      //если ордер находится в истории
      if(isHistory)
        {
         if(HistoryOrderSelect(OrderTicket) && HistoryOrderGetInteger(OrderTicket,ORDER_MAGIC)==magic_number && HistoryOrderGetString(OrderTicket,ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      else
        {
         if(OrderSelect(OrderTicket) && OrderGetInteger(ORDER_MAGIC)==magic_number && OrderGetString(ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      return is_expert;
     }

J'éditerais les informations sur les transactions entrantes dans les fichiers journaux dans l'ordre où elles sont reçues dans le terminal. J'ai maintenant un problème auquel j'ai été confronté lorsque je négociais sur un compte de démonstration :

Parfois, les transactions se présentent dans l'ordre suivant : TRADE_TRANSACTION_ORDER_DELETE, puis TRADE_TRANSACTION_DEAL_ADD, puis TRADE_TRANSACTION_HISTORY_ADD. Dans ce cas, les ordres stop ne sont souvent pas placés après l'exécution d'une transaction. Je suppose que cela se produit parce que la commande a déjà été supprimée mais n'a pas encore été ajoutée à l'historique. Cela signifie que nous ne pouvons pas trouver l'ordre de l'opération ni dans l'historique ni dans le terminal. Bien que cela soit douteux, le fait est qu'aucun ordre stop n'est placé car le robot ne le trouve pas après avoir recherché l'ordre dans toutes les dimensions(isFindOrder=false). L'ordre des transactions peut être correct, mais l'ordre est toujours introuvable. Dans tous les cas, le robot détecte correctement la transaction, mais ne parvient pas à placer des ordres.Cependant, il arrive aussi qu'il fonctionne correctement et que des ordres soient placés.

J'ai essayé différentes approches, mais rien ne fonctionne. J'envisage maintenant d'ajouter un intervalle d'une seconde au début de la procédure de passation des commandes en attente. Je ne sais pas vraiment où aller.

Veuillez partager vos expériences et vos idées.

 
Илья Ребенок:

Bonsoir.

Les gars, s'il vous plaît, aidez-moi. Le problème n'est probablement pas nouveau, mais je n'ai pas trouvé de solution unique (ni en pratique ni sur les forums).

J'exécute deux robots différents dans le terminal sur deux instruments différents. Les magies sont différentes partout. Le robot place des limites en attente et la procédure OnTradeTransaction me permet de détecter une transaction et de placer des ordres stop en attente en utilisant cette transaction.

Voici le code de la transaction commerciale

Voici le code de la fonction qui vérifie si l'affaire appartient à un robot

Voici le code de la procédure pour les ordres stop en suspens

Voici le code de la fonction de recherche d'un ordre dans l'historique et hors de l'historique

J'éditerais les informations sur les transactions entrantes dans le journal dans l'ordre où elles sont reçues dans le terminal. J'ai maintenant un problème auquel j'ai été confronté lorsque je négociais sur un compte de démonstration :

Parfois, les transactions se présentent dans l'ordre suivant : TRADE_TRANSACTION_ORDER_DELETE, puis TRADE_TRANSACTION_DEAL_ADD, puis TRADE_TRANSACTION_HISTORY_ADD. Dans ce cas, les ordres stop ne sont souvent pas placés après l'exécution d'une transaction. Je suppose que cela se produit parce que la commande a déjà été supprimée mais n'a pas encore été ajoutée à l'historique. Cela signifie que nous ne pouvons pas trouver l'ordre de l'opération ni dans l'historique ni dans le terminal. Bien que cela soit douteux, le fait est qu'aucun ordre stop n'est placé car le robot ne le trouve pas après avoir recherché l'ordre dans toutes les dimensions(isFindOrder=false). L'ordre de transaction est peut-être correct, mais l'ordre est toujours introuvable.

J'ai essayé différentes approches, rien n'y fait. Je pense maintenant ajouter un sleep de 1 seconde au début d'une procédure pour placer des ordres en attente, peut-être que le temps n'est pas suffisant. Je ne sais même pas où creuser.

Veuillez partager vos expériences et vos idées.

Je n'ai pas encore commencé à regarder tout le code. Je ne pense pas du tout que cette approche soit correcte.

Au moment de la transaction de type TRADE_TRANSACTION_DEAL_ADD nous devons choisir la position trans.et vérifier sa magie.

if(PositionSelectByTicket(trans.position) && PositionGetInteger(POSITION_MAGIC) == mag)

Vous pouvez également vérifier que trans.symbol == _Symbol et prendre une décision en fonction des résultats de ces vérifications.

 
Alexey Viktorov:

Je n'ai pas regardé dans tout le code. À mon avis, cette approche n'est pas du tout correcte.

Au moment de la transaction de type TRADE_TRANSACTION_DEAL_ADD, il faut choisir trans.position et vérifier sa magie.

Vous pouvez également vérifier que trans.symbol == _Symbol et prendre une décision en fonction des résultats de ces vérifications.

J'ai oublié d'ajouter que le mode est le filet. La position est la même pour tous les robots. C'est-à-dire qu'un robot a acheté une position, le second l'a achetée, les événements TRADE_TRANSACTION_DEAL_ADD sont arrivés dans l'ordre inverse et par conséquent le premier robot ne l'a pas vu.

Et j'ai logiquement besoin d'obtenir le commentaire d'ordre de la transaction, la position n'est pas d'une grande aide ici.
 
Илья Ребенок:

Partagez vos expériences et vos idées, s'il vous plaît.

Une situation

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie

Bugs, bugs, questions

fxsaber, 2018.06.20 23:18

J'ai décidé de vérifier combien de temps durent ces situations de commandes fantômes, lorsqu'une commande est dans le système mais pas dans le terminal.

// Советник отслеживает длительность ситуаций, когда ордер отсутствует среди текущих и исторических

#define  TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define  TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

bool OrderIsExist( const ulong &OrderTicket )
{
  return(OrderTicket ? OrderSelect(OrderTicket) || HistoryOrderSelect(OrderTicket) : true);
}

void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest&, const MqlTradeResult& )
{
  static bool PrevIsExist = true;
  static ulong StartTime = 0;
  static ulong MaxInterval = 0;
  
  const ulong NowTime = GetMicrosecondCount();
  const bool IsExist = OrderIsExist(Trans.order);
    
  if (!IsExist)
  {
    Print(TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
  
    if (PrevIsExist) 
      StartTime = NowTime;
  }
  else if (!PrevIsExist)
  {
    const ulong Interval = NowTime - StartTime;
    
    Print(TOSTRING(Interval) + TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
    
    if (Interval > MaxInterval)
    {
      MaxInterval = Interval;
      
      Comment(TOSTRING(MaxInterval) + TOSTRING(Trans.order)); // mcs.
    }
  }
          
  PrevIsExist = IsExist;
}


Résultat

2018.06.21 00:10:31.047 Trans.type = TRADE_TRANSACTION_ORDER_DELETE (2)
2018.06.21 00:10:31.047 Trans.order = 2210967406
2018.06.21 00:10:31.047 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 HistoryOrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 
2018.06.21 00:10:31.080 Interval = 32643
2018.06.21 00:10:31.080 Trans.type = TRADE_TRANSACTION_HISTORY_ADD (3)
2018.06.21 00:10:31.080 Trans.order = 2210967406
2018.06.21 00:10:31.080 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.080 HistoryOrderSelect(Trans.order) = true


32 millisecondes un ordre est là mais pas dans le Terminal ! Imaginez les conséquences si la logique de trading était exécutée dans cet intervalle ...


Il est intéressant de constater que les ordres fantômes ne sont le plus souvent présents que pour les types de transactionTRADE_TRANSACTION_ORDER_DELETE et TRADE_TRANSACTION_DEAL_ADD (beaucoup plus rares).


Très mauvaise nuance de plate-forme.


ZZY vitesse douteuse des transactions commerciales sur 5, malheureusement.


Deuxièmement

ouvrir une position et le total des ordres a augmenté de un.

  • Elle a été exécutée et le total des commandes a diminué de un, mais le total des positions n'a pas augmenté de un. En d'autres termes, il existe une position, mais le terminal ne la connaît pas.
  • Par exemple, il n'y a pas de positions ou d'ordres - PositionsTotal = 0, OrdersTotal = 0.

    Vous placez un ordre au marché. PositionsTotal = 0, CommandesTotal = 1.

    L'ordre au marché est exécuté - OrdersTotal = 0. Mais PositionsTotal = 0!

     
    Илья Ребенок:

    J'ai oublié d'ajouter que le mode est le filet. La position est la même pour tous les robots.

    Ça n'a pas d'importance. La position a toujours un ticket, mais elle peut aussi être sélectionnée par symbole. Vous devrez peut-être ajouter une vérification du volume des transactions ou autre chose. Par exemple, sélectionnez les ordres et les transactions d'une position et secouez-les pour trouver la bonne. Mais un marché est un marché... Et personne ne garantit la cohérence des transactions. Il n'y a pas si longtemps, il y a même eu une mise en garde contre une éventuelle perte de transactions.


    Compte tenu de l'addendum dans votre post, c'est tout faux. Dans ce cas, vous devez l'examiner de plus près.

     
    Илья Ребенок:

    J'ai essayé différentes approches, mais rien ne fonctionne.

    Rédigez une action simple qui doit être mise en œuvre.

     
    fxsaber:

    Une situation


    Deuxièmement

    Merci, je vais le lire, mais à première vue, cela confirme mon hypothèse.

    Alexey Viktorov:

    Ça n'a pas d'importance. La position a toujours un ticket, mais vous pouvez également sélectionner par symbole. Vous devrez peut-être ajouter un contrôle sur le volume des transactions ou autre. Par exemple, sélectionnez les ordres et les transactions d'une position et secouez-les pour trouver la bonne. Mais un marché est un marché... Et personne ne garantit la cohérence des transactions. Il n'y a pas si longtemps, un avertissement a été lancé concernant une éventuelle perte de transactions.


    Compte tenu de l'addendum dans votre message, tout ne colle pas. Dans ce cas, vous devez l'examiner de plus près.

    J'ai vu un message sur la perte de transactions, mais les modérateurs ont dit que c'était une relique du passé et ont oublié de le retirer de la documentation.

    fxsaber:

    Rédigez une action simple à mettre en œuvre.

    Je ne comprends pas bien l'écriture d'une action simple) Veuillez expliquer.

     
    Илья Ребенок:


    J'ai vu un message sur la perte de transactions, mais les modérateurs ont dit que c'était une relique du passé et ont oublié de le retirer de la documentation.

    Ils l'ont fait, mais il n'y a pas si longtemps.

     
    Илья Ребенок:

    Je ne comprends pas bien l'écriture d'une action simple) Expliquez-moi s'il vous plaît.

    Quel est l'objectif commercial ?

     
    fxsaber:

    Quel est votre objectif commercial ?

    Nous plaçons des ordres à cours limité, et lorsqu'ils se déclenchent, nous plaçons un ordre stop et un ordre de prise de bénéfices. Lorsqu'un ordre stop se déclenche, nous supprimons le take profit et vice versa. Le ticket limite initial, sur la base duquel nous fixons l'ordre stop et le take profit, est écrit dans le commentaire de l'ordre stop et du take profit. C'est pourquoi il est important d'obtenir des commentaires sur les ordres afin que, lorsqu'un ordre stop se déclenche, vous puissiez trouver le take profit avec le même commentaire et le supprimer.

    Puisque notre robot nous permet de recharger des positions, nous devons également placer un ordre stop et un take profit et laisser un commentaire avec l'entrée d'un ticket de rechargement.

    Une seconde de sommeil peut-elle être une bonne idée ? Pour avoir du temps pour toutes les transactionsTRADE_TRANSACTION_ORDER_DELETE etTRADE_TRANSACTION_HISTORY_ADD

    Общие принципы - Торговые операции - MetaTrader 5
    Общие принципы - Торговые операции - MetaTrader 5
    • www.metatrader5.com
    Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит...
     

    Илья Ребенок:

    Le robot permet une mise à l'échelle, donc lorsque nous achetons plus, nous plaçons également un ordre stop et un take profit, et enregistrons la mise à l'échelle dans le ticket.

    Peut-on avoir >=2 prises et arrêts en même temps ?

    Raison: