Questions from Beginners MQL5 MT5 MetaTrader 5 - page 713

 
dimnik:
Can you tell me how to know the result of the last one or more trades?

There are two ways:

useOnTradeTransaction() directly in the Expert Advisor and catch trades that have been recorded in the history.

//+------------------------------------------------------------------+
//| 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)
           {
            // здесь ваши действия
           }
     }
  }

or to refer to the trading history, e.g. something like this:

//+------------------------------------------------------------------+
//|                                               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("");
  }
//+------------------------------------------------------------------+


Depending on which method you choose, you will need to edit the code a bit - to get information about the last trade.

Files:
 
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());
     }  
    
  }

The event handler keeps track of all trades with EA's magiks.

But for some reason, the first trade always gets a wrong magician (zero), while the following trades are fine.

How do I correct it? Or maybe I should do it in another way?

 
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());
     }  
    
  }

The event handler keeps track of all trades with EA's magiks.

But for some reason, the first trade always gets a wrong magician (zero), while the following trades are fine.

How do I correct it? Or maybe I should do it in another way?

You need to move away from order handling - this is an outdated old system. Then everything will work out. "TRADE_TRANSACTION_DEAL_ADD" - adding the transaction to the history. This is done as a result of order execution or account balance transactions. What else do you need? The deal was executed and recorded in the history.
 
dimnik:

The event handler keeps track of all trades with EA's magiks.

But for some reason, for the first trade the magician (received through chistoriorder) is always wrong (zero), for the following trades - everything is normal.


so print the parameters of this transaction.

what is the problem with knowing its ticket/type/symbol/profit?

 
o_O:


so print the parameters of this deal.

what is the problem to find out its ticket/type/symbol/profit?

Outputs:

Deal 2, Magic 0, Volume 0.000000

In general on all deals it shows a correct number, but zero magic and volume.


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

Outputs:

Deal 2, Magic 0, Volume 0.000000

In general on all deals gives out correct number, but zero mags and volumes.


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

Add this 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;
  }

and you will see what types of transactions occur and you will also see that with "TRADE_TRANSACTION_DEAL_ADD" both magic and volume are visible.


 
Vladimir Karputov:

Add this 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;
  }

and you will see what types of transactions take place, and you will also see that with "TRADE_TRANSACTION_DEAL_ADD" both magik and volume are visible.


Thanks, it works that way.
 
dimnik:

Outputs:

Deal 2, Magic 0, Volume 0.000000

In general, all the trades give the correct number, but zero magic numbers and volumes.


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

I have long noticed that when using CDealInfo class, I need to load the history of deals independently, then everything works fine

   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:
Thank you, it works.

To avoid printing all transaction types, make the following condition in OnTradeTransaction:

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

   long     deal_type         =0;

i.e. if transaction type is not "TRADE_TRANSACTION_DEAL_ADD" - then exit.

If we need to follow the placing (not triggering, just placing) of a pending order, OnTradeTransaction will take this form:

//+------------------------------------------------------------------+
//| 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)
           {
            //
           }
        }
     }
  }
 

With the use of OnTradeTransaction, the optimisation time has strangely changed. A system on 15M, very simple, annual history, one run occurs in 0.3 - 0.4 seconds.

After optimization start the first 200-300 runs go at less than a second, the next ones slow down up to 15-20 seconds (50 times!);

No processor overheating or trotting, more than half of memory is free (from 16GB).

Before using the OnTradeTransaction handler there was nothing like that - even more complex EAs on small timeframes were optimized with approximately the same speed each run.

Does HistoryDealSelect affect the speed so much? How can we eliminate the lags?

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;
      
  }
Reason: