OnTrade

Вызывается в экспертах при наступлении события Trade. Функция предназначеня для обработки изменений в списках ордеров, позиций и сделок.

void  OnTrade(void);

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

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

Примечание

OnTrade() вызывается только для экспертов, в индикаторах и скриптах она игнорируется, даже если добавить в них функцию с таким именем и типом.

При любом торговом действии (выставлении отложенного ордера, открытии/закрытии позиции, установке стопов, срабатывании отложенных ордеров и т.п.) соответствующим образом изменяется история ордеров и сделок и/или список позиций и текущих ордеров.

В момент обработки ордера торговый сервер посылает терминалу сообщение о наступлении торгового события Trade. Для получения из истории актуальных данных по ордерам и сделкам необходимо предварительно выполнить запрос торговой истории с помощью HistorySelect().

Торговые события генерируются сервером в следующих случаях:

  • изменение в действующих ордерах,
  • изменения в позициях,
  • изменения в сделках,
  • изменения в торговой истории.

 

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

 

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

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

//+------------------------------------------------------------------+
//|                                               OnTrade_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"
 
input    int days=7;            // глубина торговой истории в днях
//--- зададим на глобальном уровне границы торговой истории
datetime     start;             // дата начала торговой истории в кэше
datetime     end;               // дата конца торговой истории в кэше
//--- глобальные счетчики
int          orders;            // количество действующих ордеров
int          positions;         // количество открытых позиций
int          deals;             // количество сделок в кэше торговой истории
int          history_orders;    // количество ордеров в кэше торговой истории
bool         started=false;     // флаг актуальности счетчиков
 
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   end=TimeCurrent();
   start=end-days*PeriodSeconds(PERIOD_D1);
   PrintFormat("Границы загружаемой торговой истории: начало - %s, конец - %s",
               TimeToString(start),TimeToString(end));
   InitCounters();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//|  инициализация счетчиков позиций, ордеров и сделок               |
//+------------------------------------------------------------------+
void InitCounters()
  {
   ResetLastError();
//--- загрузим историю 
   bool selected=HistorySelect(start,end);
   if(!selected)
     {
      PrintFormat("%s. Не удалось загрузить в кэш историю с %s по %s. Код ошибки: %d",
                  __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
      return;
     }
//--- получим текущие значения
   orders=OrdersTotal();
   positions=PositionsTotal();
   deals=HistoryDealsTotal();
   history_orders=HistoryOrdersTotal();
   started=true;
   Print("Счетчики ордеров, позиций и сделок успешно инициализированы");
  }  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(started) SimpleTradeProcessor();
   else InitCounters();
  }
//+------------------------------------------------------------------+
//| вызывается при поступлении события Trade                         |
//+------------------------------------------------------------------+
void OnTrade()
  {
   if(started) SimpleTradeProcessor();
   else InitCounters();
  }
//+------------------------------------------------------------------+
//| пример обработки изменений в торговле и истории                  |
//+------------------------------------------------------------------+
void SimpleTradeProcessor()
  {
   end=TimeCurrent();
   ResetLastError();
//--- загрузим в кэш программы торговую историю из указанного интервала
   bool selected=HistorySelect(start,end);
   if(!selected)
     {
      PrintFormat("%s. Не удалось загрузить в кэш историю с %s по %s. Код ошибки: %d",
                  __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
      return;
     }
//--- получим текущие значения
   int curr_orders=OrdersTotal();
   int curr_positions=PositionsTotal();
   int curr_deals=HistoryDealsTotal();
   int curr_history_orders=HistoryOrdersTotal();
//--- проверим изменения в количестве действующих ордеров
   if(curr_orders!=orders)
     {
      //--- количество действующих ордеров изменилось
      PrintFormat("Изменилось количество ордеров. Было %d, стало %d",
                  orders,curr_orders);
      //--- обновим значение
      orders=curr_orders;
     }
//--- изменения в количестве открытых позиций
   if(curr_positions!=positions)
     {
      //--- количество открытых позиций изменилось
      PrintFormat("Изменилось количество позиций. Было %d, стало %d",
                  positions,curr_positions);
      //--- обновим значение
      positions=curr_positions;
     }
//--- изменения в количестве сделок в кэше торговой истории
   if(curr_deals!=deals)
     {
      //--- количество сделок в кэше торговой истории изменилось
      PrintFormat("Изменилось количество сделок. Было %d, стало %d",
                  deals,curr_deals);
      //--- обновим значение
      deals=curr_deals;
     }
//--- изменения в количестве исторических ордеров в кэше торговой истории
   if(curr_history_orders!=history_orders)
     {
      //--- количество исторических ордеров в кэше торговой истории изменилось
      PrintFormat("Изменилось количество ордеров в истории. Было %d, стало %d",
                  history_orders,curr_history_orders);
     //--- обновим значение
     history_orders=curr_history_orders;
     }
//--- проверка на необходимость изменения границ торговой истории для запроса в кэш
   CheckStartDateInTradeHistory();
  }
//+------------------------------------------------------------------+
//|  изменения начальной даты для запроса торговой истории           |
//+------------------------------------------------------------------+
void CheckStartDateInTradeHistory()
  {
//--- начальный интервал, если бы мы начали работу прямо сейчас
   datetime curr_start=TimeCurrent()-days*PeriodSeconds(PERIOD_D1);
//--- убедимся, что граница начала торговой истории ушла не больше
//--- чем на 1 день от задуманной даты
   if(curr_start-start>PeriodSeconds(PERIOD_D1))
     {
      //--- придется подкорректировать дату начала загружаемой в кэш истории
      start=curr_start;
      PrintFormat("Новая граница начала загружаемой торговой истории: начало => %s",
                  TimeToString(start));
      //--- теперь заново загрузим торговую историю для обновленного интервала
      HistorySelect(start,end);
      //--- подкорректируем счетчики сделок и ордеров в истории для следующего сравнения
      history_orders=HistoryOrdersTotal();
      deals=HistoryDealsTotal();
     }
  }
//+------------------------------------------------------------------+
/* Пример вывода: 
   Границы загружаемой торговой истории: начало - 2018.07.16 18:11, конец - 2018.07.23 18:11
   Счетчики ордеров, позиций и сделок успешно инициализированы
   Изменилось количество ордеров. Было 0, стало 1
   Изменилось количество ордеров. Было 1, стало 0
   Изменилось количество позиций. Было 0, стало 1
   Изменилось количество сделок. Было 0, стало 1
   Изменилось количество ордеров в истории. Было 0, стало 1
*/

Смотри также

OrderSend, OrderSendAsync, OnTradeTransaction, События клиентского терминала