Questions des débutants MQL5 MT5 MetaTrader 5 - page 713

 
dimnik:
Pouvez-vous me dire comment connaître le résultat de la ou des dernières transactions ?

Il y a deux façons de procéder :

utiliserOnTradeTransaction() directement dans le conseiller expert et attraper les transactions qui ont été enregistrées dans l'historique.

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      double   deal_profit       =0.0;
      double   deal_volume       =0.0;
      string   deal_symbol       ="";
      long     deal_magic        =0;
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_profit=HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
        }
      else
         return;
      if(deal_symbol==Symbol() && deal_magic==m_magic)
         if(deal_entry==DEAL_ENTRY_OUT)
           {
            // здесь ваши действия
           }
     }
  }

ou pour faire référence à l'historique des transactions, par exemple quelque chose comme ceci :

//+------------------------------------------------------------------+
//|                                               HistorySelect.mq5  |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property description "Реверс позиции и исследование \"DEAL_POSITION_ID\" истории сделок"
#property script_show_inputs
//---
input datetime start=D'2016.08.05 09:00:00';
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   if(AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
     {
      Print("This script cannot be run on a hedge; Этот скрипт нельзя запускать на хедж");
      return;
     }
   Print_IDs();
  }
//+------------------------------------------------------------------+
//| List all positions and deals                                     |
//+------------------------------------------------------------------+
void Print_IDs(void)
  {
//--- запрашиваем историю сделок и ордеров за указанный период серверного времени
   HistorySelect(start,TimeCurrent()+86400);
   uint     total    =HistoryDealsTotal();   // количество сделок в истории
   ulong    ticket   =0;                     // тикет сделки в истории
   long     type     =0;                     // тип сделки
   long     deal_id=0;   // идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка
   double   volume   =0.0;                   // объём сделки
   double   profit   =0.0;                   // финансовый результат сделки
   double   price    =0.0;                   // цена сделки
   string   symbol   =NULL;                  // имя символа, по которому произведена сделка
   long     entry    =0;                     // направление сделки – вход в рынок, выход из рынка или разворот
//--- for all deals
   for(uint i=0;i<total;i++)
     {
      //--- try to get deals ticket
      if((ticket=HistoryDealGetTicket(i))>0)
        {
         //--- get deals properties
         type     =HistoryDealGetInteger(ticket,DEAL_TYPE);
         deal_id  =HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
         volume   =HistoryDealGetDouble(ticket,DEAL_VOLUME);
         profit   =HistoryDealGetDouble(ticket,DEAL_PROFIT);
         price    =HistoryDealGetDouble(ticket,DEAL_PRICE);
         symbol   =HistoryDealGetString(ticket,DEAL_SYMBOL);
         entry    =HistoryDealGetInteger(ticket,DEAL_ENTRY);
         Print(EnumToString((ENUM_DEAL_ENTRY)entry),
               ", type ",EnumToString((ENUM_DEAL_TYPE)type),
               ", price ",DoubleToString(price,Digits()),
               ", Deal ",symbol," volume ",DoubleToString(volume,2),
               ", DEAL_POSITION_ID #",deal_id,
               ", profit ",DoubleToString(profit,2));
        }
     }
   Print("");
  }
//+------------------------------------------------------------------+


Selon la méthode choisie, vous devrez modifier un peu le code - pour obtenir des informations sur la dernière transaction.

Dossiers :
 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
     {
       if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
       if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
     }  
    
  }

Le gestionnaire d'événement garde la trace de toutes les transactions avec les magies de l'EA.

Mais pour une raison quelconque, le premier échange obtient toujours un mauvais magicien (zéro), alors que les échanges suivants sont corrects.

Comment puis-je le corriger ? Ou peut-être que je devrais le faire d'une autre manière ?

 
dimnik:
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
     {
       if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
       if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
     }  
    
  }

Le gestionnaire d'événement garde la trace de toutes les transactions avec les magies de l'EA.

Mais pour une raison quelconque, le premier échange obtient toujours un mauvais magicien (zéro), alors que les échanges suivants sont corrects.

Comment puis-je le corriger ? Ou peut-être que je devrais le faire d'une autre manière ?

Vous devez vous éloigner du traitement des commandes - c'est un vieux système dépassé. Alors tout s'arrangera. "TRADE_TRANSACTION_DEAL_ADD" - ajout de la transaction à l'historique. Cela se fait à la suite de l'exécution d'un ordre ou de transactions sur le solde du compte. De quoi d'autre avez-vous besoin ? L'accord a été exécuté et enregistré dans l'histoire.
 
dimnik:

Le gestionnaire d'événement garde la trace de toutes les transactions avec les magies de l'EA.

Mais pour une raison quelconque, pour le premier trade le magicien (reçu par chistoriorder) est toujours faux (zéro), pour les trades suivants - tout est normal.


pour imprimer les paramètres de cette transaction.

quel est le problème de connaître son ticket/type/symbole/profit ?

 
o_O:


alors imprimez les paramètres de cet accord.

quel est le problème pour trouver son ticket/type/symbole/profit ?

Sorties :

Deal 2, Magic 0, Volume 0.000000

En général, sur toutes les transactions, il affiche un chiffre correct, mais aucun chiffre magique ni volume.


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
 
dimnik:

Sorties :

Deal 2, Magic 0, Volume 0.000000

En général, sur toutes les transactions, il donne le bon numéro, mais pas de mags ni de volumes.


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());

Ajoutez ce code :

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
   long     deal_type         =0;
   long     deal_positions_id =0;
   long     deal_ticket       =0;
   double   deal_volume       =0;
   long     deal_entry        =0;
   long     deal_magic        =0;
   string   deal_symbol       ="";
   string   deal_comment      ="";
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
      deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
      deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
      deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);
      Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
            "D_POSITION_ID: ",deal_positions_id,", ",
            "D_TICKET: ",deal_ticket,", ",
            "D_VOLUME: ",DoubleToString(deal_volume,2),", ",
            "D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
            "_MAGIC: ",deal_magic,", ",
            "D_SYMBOL: ",deal_symbol,", ",
            "D_COMMENT: ",deal_comment);
     }
   else
      return;
  }

et vous verrez quels types de transactions se produisent et vous verrez également qu'avec "TRADE_TRANSACTION_DEAL_ADD", la magie et le volume sont tous deux visibles.


 
Vladimir Karputov:

Ajoutez ce code :

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
   long     deal_type         =0;
   long     deal_positions_id =0;
   long     deal_ticket       =0;
   double   deal_volume       =0;
   long     deal_entry        =0;
   long     deal_magic        =0;
   string   deal_symbol       ="";
   string   deal_comment      ="";
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
      deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
      deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
      deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);
      Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
            "D_POSITION_ID: ",deal_positions_id,", ",
            "D_TICKET: ",deal_ticket,", ",
            "D_VOLUME: ",DoubleToString(deal_volume,2),", ",
            "D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
            "_MAGIC: ",deal_magic,", ",
            "D_SYMBOL: ",deal_symbol,", ",
            "D_COMMENT: ",deal_comment);
     }
   else
      return;
  }

et vous verrez quels types de transactions ont lieu, et vous verrez également qu'avec "TRADE_TRANSACTION_DEAL_ADD", le magik et le volume sont tous deux visibles.


Merci, ça marche comme ça.
 
dimnik:

Sorties :

Deal 2, Magic 0, Volume 0.000000

En général, tous les métiers donnent le bon chiffre, mais aucun chiffre magique ni volume.


       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());

J'ai remarqué depuis longtemps que lorsque j'utilise la classe CDealInfo, je dois charger l'historique des transactions de manière indépendante, puis tout fonctionne bien.

   if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      HistorySelect(0,TimeCurrent());
       deal.Ticket(trans.deal);
       printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
     }
 
dimnik:
Merci, ça marche.

Pour éviter d'imprimer tous les types de transaction, posez la condition suivante dans OnTradeTransaction:

//--- получим тип транзакции в виде значения перечисления  
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   if(type!=TRADE_TRANSACTION_DEAL_ADD)
      return;

   long     deal_type         =0;

c'est-à-dire que si le type de transaction n'est pas "TRADE_TRANSACTION_DEAL_ADD" - alors exit.

Si nous devons suivre le placement (pas le déclenchement, juste le placement) d'un ordre en attente, OnTradeTransaction prendra cette forme :

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   Print(EnumToString(type));
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_ORDER_ADD)
     {
      long     order_type        =0;
      double   order_price       =0.0;
      double   order_volume      =0.0;
      string   order_symbol      ="";
      long     order_magic       =0;
      if(OrderSelect(trans.order)) // select pending orders
        {
         order_type=OrderGetInteger(ORDER_TYPE);
         order_price=OrderGetDouble(ORDER_PRICE_OPEN);
         order_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
         order_symbol=OrderGetString(ORDER_SYMBOL);
         order_magic=OrderGetInteger(ORDER_MAGIC);
        }
      else
         return;
      if(order_symbol==m_symbol.Name() && order_magic==m_magic)
        {
         if(order_type==ORDER_TYPE_BUY_LIMIT)
           {
            //
           }
         if(order_type==ORDER_TYPE_SELL_LIMIT)
           {
            //
           }
        }
     }
  }
 

Avec l'utilisation de OnTradeTransaction, le temps d'optimisation a étrangement changé. Un système sur 15M, très simple, historique annuel, une course se produit en 0,3 - 0,4 secondes.

Après le démarrage de l'optimisation, les 200-300 premières courses vont à moins d'une seconde, les suivantes ralentissent jusqu'à 15-20 secondes (50 fois !) ;

Pas de surchauffe du CPU et pas de troll, plus de la moitié de la mémoire est libre (à partir de 16 Go).

Avant l'utilisation du gestionnaire OnTradeTransaction, il n'y avait rien de tel - même des EA plus complexes sur de petites échéances étaient optimisés avec approximativement la même vitesse à chaque exécution.

Est-ce que HistoryDealSelect affecte autant la vitesse ? Comment éliminer les décalages ?

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if( trans.type != TRADE_TRANSACTION_DEAL_ADD) return;
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
   long     deal_type         =0;
   double   deal_volume       =0;
   long     deal_magic        =0;
   if(HistoryDealSelect(trans.deal))
     {
      deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
      deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
      deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
     }
   else
      return;
   if (deal_type == DEAL_TYPE_BUY && deal_magic == MagicNumber) current_position += deal_volume;
   if (deal_type == DEAL_TYPE_SELL && deal_magic == MagicNumber) current_position -= deal_volume;
      
  }