Правила истечения сроков отложенных ордеров

При работе с отложенными ордерами (включая уровни Stop Loss и Take Profit) MQL-программе следует проверять пару свойств, задающих правила их истечения. Оба свойства доступны как элементы перечисления ENUM_SYMBOL_INFO_INTEGER для вызова функции SymbolInfoInteger.

Идентификатор

Описание

SYMBOL_EXPIRATION_MODE

Флаги разрешенных режимов истечения ордера (битовая маска)

SYMBOL_ORDER_GTC_MODE

Срок действия определен одним из элементов перечисления ENUM_SYMBOL_ORDER_GTC_MODE

Свойство SYMBOL_ORDER_GTC_MODE принимается во внимание, только если SYMBOL_EXPIRATION_MODE содержит SYMBOL_EXPIRATION_GTC (см. далее). GTC является аббревиатурой "Good Till Canceled".

Для каждого финансового инструмента в свойстве SYMBOL_EXPIRATION_MODE может быть указано несколько режимов срока действия (истечения) отложенных ордеров. Каждому режиму сопоставлен флаг (бит).

Идентификатор (Значение)

Описание

SYMBOL_EXPIRATION_GTC (1)

Ордер действителен согласно свойству ENUM_SYMBOL_ORDER_GTC_MODE

SYMBOL_EXPIRATION_DAY (2)

Ордер действителен до конца текущего дня

SYMBOL_EXPIRATION_SPECIFIED (4)

Дата и время истечения указывается в ордере

SYMBOL_EXPIRATION_SPECIFIED_DAY (8)

Дата истечения указывается в ордере

Флаги могут комбинироваться операцией логического ИЛИ ('|'), например, SYMBOL_EXPIRATION_GTC | SYMBOL_EXPIRATION_SPECIFIED, что эквивалентно 1 | 4, то есть числу 5. Для проверки разрешения конкретного режима для инструмента выполните операцию логического И ('&') над полученным результатом функции и битом желаемого режима: ненулевое значение означает доступность режима.

В случае SYMBOL_EXPIRATION_SPECIFIED_DAY ордер действует до 23:59:59 указанного дня. Если это время не попадает на торговую сессию, истечение наступит в ближайшее следующее торговое время.

Перечисление ENUM_SYMBOL_ORDER_GTC_MODE содержит следующие элементы.

Идентификатор

Описание

SYMBOL_ORDERS_GTC

Отложенные ордера и уровни Stop Loss/Take Profit действительны неограниченное время вплоть до явной отмены

SYMBOL_ORDERS_DAILY

Ордера действуют только внутри одного торгового дня: по его завершении удаляются все отложенные ордера, а также уровни Stop Loss и Take Profit

SYMBOL_ORDERS_DAILY_EXCLUDING_STOPS

При смене торгового дня удаляются только отложенные ордера, уровни Stop Loss и Take Profit сохраняются

В зависимости от установленных битов в свойстве SYMBOL_EXPIRATION_MODE, при подготовке ордера к отправке MQL-программа может выбрать один из режимов, соответствующих этим битам. Технически это делается путем заполнения поля type_time в специальной структуре MqlTradeRequest перед вызовом функции OrderSend. Значение поля должно быть элементом перечисления ENUM_ORDER_TYPE_TIME (см. Сроки действия отложенных ордеров): как мы увидим в дальнейшем, оно перекликается с вышеприведенным набором флагов, то есть каждый флаг задает соответствующий режим в ордере — ORDER_TIME_GTC, ORDER_TIME_DAY, ORDER_TIME_SPECIFIED, ORDER_TIME_SPECIFIED_DAY. Само время или день истечения должен быть указан в другом поле той же структуры.

Скрипт SymbolFilterExpiration.mq5 позволяет узнать статистику применения каждого из флагов в имеющихся символах (в обзоре рынка или вцелом, в зависимости от входного параметра UseMarketWatch). Второй параметр ShowPerSymbolDetails, будучи взведенным в true, вызовет вывод в журнал всех флагов для каждого символа — будьте внимательны: если при этом режим UseMarketWatch равен false, сгенерируется очень большое число записей в журнале.

#property script_show_inputs
   
#include <MQL5Book/SymbolFilter.mqh>
   
input bool UseMarketWatch = false;
input bool ShowPerSymbolDetails = false;

В функции OnStart помимо объекта фильтра и приемных массивов для названий символов и значений свойств описываем карты MapArray для подсчета статистики - раздельно для каждого из свойств SYMBOL_EXPIRATION_MODE и SYMBOL_ORDER_GTC_MODE.

void OnStart()
{
   SymbolFilter f;                // объект фильтра
   string symbols[];              // приемный массив для названий символов
   long flags[][2];               // приемный массив для значений свойств
   
   MapArray<SYMBOL_EXPIRATION,intstats;        // счетчики режимов
   MapArray<ENUM_SYMBOL_ORDER_GTC_MODE,intgtc// счетчики GTC
   
   ENUM_SYMBOL_INFO_INTEGER ints[] =
   {
      SYMBOL_EXPIRATION_MODE,
      SYMBOL_ORDER_GTC_MODE
   };
   ...

Далее применяем фильтр и посчитываем статистику.

   f.select(UseMarketWatchintssymbolsflags);
   const int n = ArraySize(symbols);
   
   for(int i = 0i < n; ++i)
   {
      if(ShowPerSymbolDetails)
      {
         Print(symbols[i] + ":");
         for(int j = 0j < ArraySize(ints); ++j)
         {
            // свойства в виде описаний и чисел
            PrintFormat("  %s (%d)",
               SymbolMonitor::stringify(flags[i][j], ints[j]),
               flags[i][j]);
         }
      }
      
      const SYMBOL_EXPIRATION mode = (SYMBOL_EXPIRATION)flags[i][0];
      for(int j = 0j < 4; ++j)
      {
         const SYMBOL_EXPIRATION bit = (SYMBOL_EXPIRATION)(1 << j);
         if((mode & bit) != 0)
         {
            stats.inc(bit);
         }
         
         if(bit == SYMBOL_EXPIRATION_GTC)
         {
            gtc.inc((ENUM_SYMBOL_ORDER_GTC_MODE)flags[i][1]);
         }
      }
   }
   ...

Наконец, выводим полученные числа в журнал.

   PrintFormat("===== Expiration modes for %s symbols =====",
      (UseMarketWatch ? "Market Watch" : "all available"));
   PrintFormat("Total symbols: %d"n);
   
   Print("Stats per expiration mode:");
   stats.print();
   Print("Legend: key=expiration mode, value=count");
   for(int i = 0i < stats.getSize(); ++i)
   {
      PrintFormat("%d -> %s"stats.getKey(i), EnumToString(stats.getKey(i)));
   }
   Print("Stats per GTC mode:");
   gtc.print();
   Print("Legend: key=GTC mode, value=count");
   for(int i = 0i < gtc.getSize(); ++i)
   {
      PrintFormat("%d -> %s"gtc.getKey(i), EnumToString(gtc.getKey(i)));
   }
}

Запустим скрипт два раза. Первый раз — с настройками по умолчанию — можем получить примерно следующую картину.

===== Expiration modes for all available symbols =====
Total symbols: 52357
Stats per expiration mode:
    [key] [value]
[0]     1   52357
[1]     2   52357
[2]     4   52357
[3]     8   52303
Legend: key=expiration mode, value=count
1 -> _SYMBOL_EXPIRATION_GTC
2 -> _SYMBOL_EXPIRATION_DAY
4 -> _SYMBOL_EXPIRATION_SPECIFIED
8 -> _SYMBOL_EXPIRATION_SPECIFIED_DAY
Stats per GTC mode:
    [key] [value]
[0]     0   52357
Legend: key=GTC mode, value=count
0 -> SYMBOL_ORDERS_GTC

Здесь видно, что практически все флаги разрешены для большинства символов, а для режима SYMBOL_EXPIRATION_GTC используется единственный вариант SYMBOL_ORDERS_GTC.

Второй раз запустим скрипт, установив UseMarketWatch и ShowPerSymbolDetails в true (предполагается, что в Обзор рынка выбрано ограниченное число символов).

GBPUSD:
  [ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED ] (7)
  SYMBOL_ORDERS_GTC (0)
USDCHF:
  [ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED ] (7)
  SYMBOL_ORDERS_GTC (0)
USDJPY:
  [ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED ] (7)
  SYMBOL_ORDERS_GTC (0)
...
XAUUSD:
  [ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED
  _SYMBOL_EXPIRATION_SPECIFIED_DAY ] (15)
  SYMBOL_ORDERS_GTC (0)
SP500m:
  [ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED
  _SYMBOL_EXPIRATION_SPECIFIED_DAY ] (15)
  SYMBOL_ORDERS_GTC (0)
UK100:
  [ _SYMBOL_EXPIRATION_GTC _SYMBOL_EXPIRATION_DAY _SYMBOL_EXPIRATION_SPECIFIED
  _SYMBOL_EXPIRATION_SPECIFIED_DAY ] (15)
  SYMBOL_ORDERS_GTC (0)
===== Expiration modes for Market Watch symbols =====
Total symbols: 15
Stats per expiration mode:
    [key] [value]
[0]     1      15
[1]     2      15
[2]     4      15
[3]     8       6
Legend: key=expiration mode, value=count
1 -> _SYMBOL_EXPIRATION_GTC
2 -> _SYMBOL_EXPIRATION_DAY
4 -> _SYMBOL_EXPIRATION_SPECIFIED
8 -> _SYMBOL_EXPIRATION_SPECIFIED_DAY
Stats per GTC mode:
    [key] [value]
[0]     0      15
Legend: key=GTC mode, value=count
0 -> SYMBOL_ORDERS_GTC

Из 15-ти выбранных символов только у 6-ти установлен флаг SYMBOL_EXPIRATION_SPECIFIED_DAY. Подробности о флагах по каждому символу можно найти выше.