Работа с историей ордеров и сделок. В чем смысл?

 

В справке смотрим пример по historydealgetinteger:

void OnTrade() 
  { 
//--- получим тикет последней сделки из истории торговли за неделю 
   ulong last_deal=GetLastDealTicket(); 
   if(HistoryDealSelect(last_deal)) 
     { 
      //--- время совершения сделки в миллисекундах от 01.01.1970 
      long deal_time_msc=HistoryDealGetInteger(last_deal,DEAL_TIME_MSC); 
      PrintFormat("Deal #%d DEAL_TIME_MSC=%i64 => %s", 
                  last_deal,deal_time_msc,TimeToString(deal_time_msc/1000)); 
     } 

В переменой last_deal имеем тикет последней сделки.

Затем выделяем сделку: HistoryDealSelect(last_deal).

Когда получаем значение какого-нибудь свойства сделки, в функцию HistoryDealGetInteger() передается тикет. Что интересно, когда работаем с позициями или ордерами (не с историей), тикет не надо указывать, сначала позиция или ордер выделяется, потом выполняется получения свойств, указывается только идентификатор свойства. А при работе с историей все функции имеют параметр для тикета. В чем смысл, если сделку или ордер все равно надо выделять?

 
Dmitry Fedoseev:

В справке смотрим пример по historydealgetinteger:

В переменой last_deal имеем тикет последней сделки.

Затем выделяем сделку: HistoryDealSelect(last_deal).

Когда получаем значение какого-нибудь свойства сделки, в функцию HistoryDealGetInteger() передается тикет. Что интересно, когда работаем с позициями или ордерами (не с историей), тикет не надо указывать, сначала позиция или ордер выделяется, потом выполняется получения свойств, указывается только идентификатор свойства. А при работе с историей все функции имеют параметр для тикета. В чем смысл, если сделку или ордер все равно надо выделять?

Отвечу на этот интересный и по-прежнему актуальный вопрос, хоть и прошло уже много лет.

Параметр с тикетом нужен потому, что функции HistoryDealGetXYZ являются универсальными для доступа к истории, в которой может быть выбрана не конкретная сделка, а несколько сделок - в частности, по позиции (HistorySelectByPosition(pid)), в заданном диапазоне дат (HistorySelect(from, to)) или даже вся целиком (HistorySelect(0, LONG_MAX)). При этом можно читать свойства разных сделок по их тикетам, не прибегая к HistoryDealSelect().

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

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