OnTradeTransaction

Вызывается в экспертах при наступлении события TradeTransaction. Функция предназначена для обработки результатов выполнения торгового запроса.

void  OnTradeTransaction()
   const MqlTradeTransaction&    trans,     // структура торговой транзакции
   const MqlTradeRequest&        request,   // структура запроса
   const MqlTradeResult&         result     // структура ответа
   );

Параметры

trans

[in]  Переменная типа MqlTradeTransaction с описанием транзакции, проведенной на торговом счете.

request

[in]  Переменная типа MqlTradeRequest с описанием торгового запроса, породившего транзакцию. Содержит значения только для транзакции типа TRADE_TRANSACTION_REQUEST.

result

[in]  Переменная типа MqlTradeResult с результатом выполнения торгового запроса, породившего транзакцию. Содержит значения только для транзакции типа TRADE_TRANSACTION_REQUEST.

Возвращаемое значение

Нет возвращаемого значения

Примечание

OnTradeTransaction() вызывается для обработки события TradeTransaction, которое торговый сервер посылает терминалу в следующих случаях:

  • отправка торгового запроса из MQL5-программы при помощи функций OrderSend()/OrderSendAsync() и его последующее исполнение;
  • отправка торгового запроса вручную через графический интефейс и его последующее исполнение;
  • срабатывания отложенных ордеров и стоп-ордеров на сервере;
  • выполнения операций на стороне торгового сервера.

 

Информация о типе транзакции содержится в поле type переменной trans. Типы торговых транзакций описываются в перечислении ENUM_TRADE_TRANSACTION_TYPE:

  • TRADE_TRANSACTION_ORDER_ADD – добавление нового действующего ордера
  • TRADE_TRANSACTION_ORDER_UPDATE – изменение действующего ордера
  • TRADE_TRANSACTION_ORDER_DELETE – удаление ордера из списка действующих
  • TRADE_TRANSACTION_DEAL_ADD – добавление сделки в историю
  • TRADE_TRANSACTION_DEAL_UPDATE – изменение сделки в истории
  • TRADE_TRANSACTION_DEAL_DELETE – удаление сделки из истории
  • TRADE_TRANSACTION_HISTORY_ADD – добавление ордера в историю в результате исполнения или отмены
  • TRADE_TRANSACTION_HISTORY_UPDATE – изменение ордера, находящегося в истории ордеров
  • TRADE_TRANSACTION_HISTORY_DELETE – удаление ордера из истории ордеров
  • TRADE_TRANSACTION_POSITION – изменение позиции, не связанное с исполнением сделки
  • TRADE_TRANSACTION_REQUEST – уведомление о том, что торговый запрос обработан сервером и результат его обработки получен.

При обрабокте транзакций типа TRADE_TRANSACTION_REQUEST для получения дополнительной информации необходимо анализировать второй и третий параметры функции OnTradeTransaction() – request и result.

Отправка торгового запроса на покупку приводит к цепи торговых транзакций, которые совершаются на торговом счете: 1) запрос  принимается на обработку, 2) далее для счета создается соответствующий ордер на покупку, 3) затем происходит исполнение ордера, 4) удаление исполненного ордера из списка действующих, 5) добавление в историю ордеров, 6) далее добавляется соответствующая сделка в историю и 7) создается новая позиция. Все эти действия являются торговыми транзакциями. Приход каждой такой транзакции в терминал является событием TradeTransaction. При этом очередность поступления этих транзакций в терминал не гарантирована, поэтому нельзя свой торговый алгоритм строить на ожидании поступления одних торговых транзакций после прихода других.

Во время обработки торговых транзакций экспертом при помощи обработчика OnTradeTransaction(), терминал продолжает обрабатывать вновь поступающие торговые транзакции. Таким образом, состояние торгового счета может измениться уже в процессе работы OnTradeTransaction(). Например, пока MQL5-программа обрабатывает событие добавления нового ордера, он может быть исполнен, удален из списка открытых и перемещен в историю. В дальнейшем программа будет уведомлена о всех этих событиях.

Длина очереди транзакций составляет 1024 элемента. Если OnTradeTransaction() будет обрабатывать очередную транзакцию слишком долго, старые транзакции в очереди могут быть вытеснены более новыми.

Обработчик OnTrade() вызывается после соответствующих вызовов OnTradeTransaction(). В общем случае нет точного соотношения по количеству вызовов OnTrade() и OnTradeTransaction(). Один вызов OnTrade() соответствует одному или нескольким вызовам OnTradeTransaction.

Каждое событие Trade может быть результатом одного или нескольких торговых запросов. Торговые запросы отправляются на сервер с помощью OrderSend() или OrderSendAsync(). Каждый запрос может порождать несколько торговых событий. Нельзя полагаться на правило "Один запрос - Одно событие Trade", так как обработка запросов может происходить в несколько этапов и каждая операция может изменять состояние ордеров, позиций и торговой истории.

Пример эксперта c обработчиком OnTradeTransaction()

//+------------------------------------------------------------------+
//|                                    OnTradeTransaction_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Пример слушателя событий TradeTransaction"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   PrintFormat("LAST PING=%.f ms",
               TerminalInfoInteger(TERMINAL_PING_LAST)/1000.);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
 
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   static int counter=0;   // счетчик вызовов OnTradeTransaction()
   static uint lasttime=0; // время последнего вызова OnTradeTransaction()
//---
   uint time=GetTickCount();
//--- если последняя транзакция была больше 1 секунды назад
   if(time-lasttime>1000)
     {
      counter=0; // значит, это новая торговая операция и можно сбросить счетчик
      if(IS_DEBUG_MODE)
         Print(" Новая торговая операция");
     }
   lasttime=time;
   counter++;
   Print(counter,". ",__FUNCTION__);
//--- результат выполнения торгового запроса
   ulong            lastOrderID   =trans.order;
   ENUM_ORDER_TYPE  lastOrderType =trans.order_type;
   ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- имя символа, по которому произошла транзакция
   string trans_symbol=trans.symbol;
//--- тип транзакции
   ENUM_TRADE_TRANSACTION_TYPE  trans_type=trans.type;
   switch(trans.type)
     {
      case  TRADE_TRANSACTION_POSITION:   // изменение позиции
        {
         ulong pos_ID=trans.position;
         PrintFormat("MqlTradeTransaction: Position  #%I64u %s modified: SL=%.5f TP=%.5f",
                     pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
        }
      break;
      case TRADE_TRANSACTION_REQUEST:     // отправка торгового запроса
         PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST");
         break;
      case TRADE_TRANSACTION_DEAL_ADD:    // добавление сделки
        {
         ulong          lastDealID   =trans.deal;
         ENUM_DEAL_TYPE lastDealType =trans.deal_type;
         double        lastDealVolume=trans.volume;
         //--- идентификатор сделки во внешней системе - тикет, присваиваемый биржей
         string Exchange_ticket="";
         if(HistoryDealSelect(lastDealID))
            Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID);
         if(Exchange_ticket!="")
            Exchange_ticket=StringFormat("(Exchange deal=%s)",Exchange_ticket);
 
         PrintFormat("MqlTradeTransaction: %s deal #%I64u %s %s %.2f lot   %s",EnumToString(trans_type),
                     lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket);
        }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD// добавление ордера в историю
        {
         //--- идентификатор ордера во внешней системе - тикет, присваиваемый биржей
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_FILLED)
           {
            if(HistoryOrderSelect(lastOrderID))
               Exchange_ticket=HistoryOrderGetString(lastOrderID,ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("(Exchange ticket=%s)",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%I64u %s %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
      default// прочие транзакции  
        {
         //--- идентификатор ордера во внешней системе - тикет, присваиваемый Московской биржей
         string Exchange_ticket="";
         if(lastOrderState==ORDER_STATE_PLACED)
           {
            if(OrderSelect(lastOrderID))
               Exchange_ticket=OrderGetString(ORDER_EXTERNAL_ID);
            if(Exchange_ticket!="")
               Exchange_ticket=StringFormat("Exchange ticket=%s",Exchange_ticket);
           }
         PrintFormat("MqlTradeTransaction: %s order #%I64u %s %s   %s",EnumToString(trans_type),
                     lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket);
        }
      break;
     }
//--- тикет ордера    
   ulong orderID_result=result.order;
   string retcode_result=GetRetcodeID(result.retcode);
   if(orderID_result!=0)
      PrintFormat("MqlTradeResult: order #%d retcode=%s ",orderID_result,retcode_result);
//---   
  }
//+------------------------------------------------------------------+
//| переводит числовые коды ответов в строковые мнемокоды            |
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
  {
   switch(retcode)
     {
      case 10004: return("TRADE_RETCODE_REQUOTE");             break;
      case 10006: return("TRADE_RETCODE_REJECT");              break;
      case 10007: return("TRADE_RETCODE_CANCEL");              break;
      case 10008: return("TRADE_RETCODE_PLACED");              break;
      case 10009: return("TRADE_RETCODE_DONE");                break;
      case 10010: return("TRADE_RETCODE_DONE_PARTIAL");        break;
      case 10011: return("TRADE_RETCODE_ERROR");               break;
      case 10012: return("TRADE_RETCODE_TIMEOUT");             break;
      case 10013: return("TRADE_RETCODE_INVALID");             break;
      case 10014: return("TRADE_RETCODE_INVALID_VOLUME");      break;
      case 10015: return("TRADE_RETCODE_INVALID_PRICE");       break;
      case 10016: return("TRADE_RETCODE_INVALID_STOPS");       break;
      case 10017: return("TRADE_RETCODE_TRADE_DISABLED");      break;
      case 10018: return("TRADE_RETCODE_MARKET_CLOSED");       break;
      case 10019: return("TRADE_RETCODE_NO_MONEY");            break;
      case 10020: return("TRADE_RETCODE_PRICE_CHANGED");       break;
      case 10021: return("TRADE_RETCODE_PRICE_OFF");           break;
      case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION");  break;
      case 10023: return("TRADE_RETCODE_ORDER_CHANGED");       break;
      case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS");   break;
      case 10025: return("TRADE_RETCODE_NO_CHANGES");          break;
      case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT");  break;
      case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT");  break;
      case 10028: return("TRADE_RETCODE_LOCKED");              break;
      case 10029: return("TRADE_RETCODE_FROZEN");              break;
      case 10030: return("TRADE_RETCODE_INVALID_FILL");        break;
      case 10031: return("TRADE_RETCODE_CONNECTION");          break;
      case 10032: return("TRADE_RETCODE_ONLY_REAL");           break;
      case 10033: return("TRADE_RETCODE_LIMIT_ORDERS");        break;
      case 10034: return("TRADE_RETCODE_LIMIT_VOLUME");        break;
      case 10035: return("TRADE_RETCODE_INVALID_ORDER");       break;
      case 10036: return("TRADE_RETCODE_POSITION_CLOSED");     break;
      default:
         return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode));
         break;
     }
//---
  }

Смотри также

OrderSend, OrderSendAsync, OnTradeTransaction, Структура торгового запроса, Структура торговой транзакции, Типы торговых транзакций, Типы торговых операций, События клиентского терминала