Основные понятия календаря

При работе с календарем мы будем оперировать несколькими понятиями, для формального описания которых в MQL5 определены специальные типы структур.

Прежде всего, события связаны с конкретными странами, и каждая страна описана с помощью структуры MqlCalendarCountry.

struct MqlCalendarCountry

   ulong  id;              // идентификатор страны по стандарту ISO 3166-1 
   string name;            // текстовое имя страны (в текущей кодировке терминала) 
   string code;            // двухбуквенное обозначение страны по ISO 3166-1 alpha-2 
   string currency;        // международный код валюты страны 
   string currency_symbol// символ/знак валюты страны 
   string url_name;        // имя страны, используемое в URL на сайте mql5.com 
};

О том, как получить перечень доступных в календаре стран и их атрибутов в виде массива структур MqlCalendarCountry, мы узнаем в следующем разделе.

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

Каждый вид событий задается структурой MqlCalendarEvent, в которой поле country_id однозначно связывает событие со страной. Типы используемых перечислений мы рассмотрим чуть ниже.

struct MqlCalendarEvent

   ulong                          id;         // идентификатор события 
   ENUM_CALENDAR_EVENT_TYPE       type;       // тип события 
   ENUM_CALENDAR_EVENT_SECTOR     sector;     // сектор, к которому относится событие 
   ENUM_CALENDAR_EVENT_FREQUENCY  frequency;  // частота (периодичность) события 
   ENUM_CALENDAR_EVENT_TIMEMODE   time_mode;  // режим времени события 
   ulong                          country_id// идентификатор страны 
   ENUM_CALENDAR_EVENT_UNIT       unit;       // единица измерения показателя 
   ENUM_CALENDAR_EVENT_IMPORTANCE importance// важность события 
   ENUM_CALENDAR_EVENT_MULTIPLIER multiplier// множитель показателя 
   uint                           digits;     // количество знаков после запятой 
   string                         source_url// URL источника публикации события 
   string                         event_code// код события
   string                         name;       // текстовое имя события на языке терминала 
};

Важно понимать, что структура MqlCalendarEvent описывает именно вид события (например, публикацию индекса потребительских цен, Consumer Price Index (CPI)), но не конкретное событие, которое может происходить раз в квартал, раз в месяц или по другому расписанию. Здесь содержатся общие характеристики события — его важность, периодичность, отношение к сектору экономики, единицы измерения, название, источник информации. А фактические и прогнозные показатели будут предоставляться в записях календаря о каждом конкретном событии данного вида: эти записи хранятся как структуры MqlCalendarValue, о которых речь пойдет ниже по тексту. Функции для запроса поддерживаемых видов событий будут представлены в последующих разделах.

Тип события в поле type указывается как одно из значений перечисления ENUM_CALENDAR_EVENT_TYPE.

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

Описание

CALENDAR_TYPE_EVENT

Событие (митинг, речь и так далее)

CALENDAR_TYPE_INDICATOR

Экономический индикатор

CALENDAR_TYPE_HOLIDAY

Праздник (выходной день)

Сектор экономики, к которому относится событие, выбирается из перечисления ENUM_CALENDAR_EVENT_SECTOR.

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

Описание

CALENDAR_SECTOR_NONE

Сектор не задан

CALENDAR_SECTOR_MARKET

Рынок, биржа

CALENDAR_SECTOR_GDP

Валовый внутренний продукт (GDP)

CALENDAR_SECTOR_JOBS

Рынок труда

CALENDAR_SECTOR_PRICES

Цены

CALENDAR_SECTOR_MONEY

Деньги

CALENDAR_SECTOR_TRADE

Торговля

CALENDAR_SECTOR_GOVERNMENT

Правительство

CALENDAR_SECTOR_BUSINESS

Бизнес

CALENDAR_SECTOR_CONSUMER

Потребление

CALENDAR_SECTOR_HOUSING

Жилье

CALENDAR_SECTOR_TAXES

Налоги

CALENDAR_SECTOR_HOLIDAYS

Праздники

Периодичность события указывается в поле frequency с использованием перечисления ENUM_CALENDAR_EVENT_FREQUENCY.

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

Описание

CALENDAR_FREQUENCY_NONE

Частота публикации не задана

CALENDAR_FREQUENCY_WEEK

Раз в неделю

CALENDAR_FREQUENCY_MONTH

Раз в месяц

CALENDAR_FREQUENCY_QUARTER

Раз в квартал

CALENDAR_FREQUENCY_YEAR

Раз в год

CALENDAR_FREQUENCY_DAY

Раз в день

Продолжительность события (time_mode) может быть описана одним из элементов перечисления ENUM_CALENDAR_EVENT_TIMEMODE.

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

Описание

CALENDAR_TIMEMODE_DATETIME

Известно точное время наступления события

CALENDAR_TIMEMODE_DATE

Событие занимает весь день

CALENDAR_TIMEMODE_NOTIME

Время не публикуется

CALENDAR_TIMEMODE_TENTATIVE

Предварительно известен только день, но не точное время события (время уточняется по факту)

Важность события в поле importance указывается с помощью перечисления ENUM_CALENDAR_EVENT_IMPORTANCE.

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

Описание

CALENDAR_IMPORTANCE_NONE

Не задана

CALENDAR_IMPORTANCE_LOW

Низкая

CALENDAR_IMPORTANCE_MODERATE

Средняя

CALENDAR_IMPORTANCE_HIGH

Высокая

Единицы измерения, в которых даются значения события, определены в поле unit как элемент перечисления ENUM_CALENDAR_EVENT_UNIT.

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

Описание

CALENDAR_UNIT_NONE

Единица измерения не задана

CALENDAR_UNIT_PERCENT

Проценты

CALENDAR_UNIT_CURRENCY

Национальная валюта

CALENDAR_UNIT_HOUR

Количество часов

CALENDAR_UNIT_JOB

Количество рабочих мест

CALENDAR_UNIT_RIG

Буровые установки

CALENDAR_UNIT_USD

Доллары США

CALENDAR_UNIT_PEOPLE

Число людей

CALENDAR_UNIT_MORTGAGE

Количество ипотечных кредитов

CALENDAR_UNIT_VOTE

Число голосов

CALENDAR_UNIT_BARREL

Количество в баррелях

CALENDAR_UNIT_CUBICFEET

Объем в кубических футах

CALENDAR_UNIT_POSITION

Чистый объем спекулятивных позиций в контрактах

CALENDAR_UNIT_BUILDING

Количество строений

В некоторых случаях значения экономического показателя требуют множителя (multiplier), согласно одному из элементов перечисления ENUM_CALENDAR_EVENT_MULTIPLIER.

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

Описание

CALENDAR_MULTIPLIER_NONE

Множитель не задан

CALENDAR_MULTIPLIER_THOUSANDS

Тысячи

CALENDAR_MULTIPLIER_MILLIONS

Миллионы

CALENDAR_MULTIPLIER_BILLIONS

Миллиарды

CALENDAR_MULTIPLIER_TRILLIONS

Триллионы

Итак, мы разобрались со всеми специальными типами данных, используемыми для описания видов событий в структуре MqlCalendarEvent.

Отдельная запись календаря оформлена как структура MqlCalendarValue. Её подробное описание приведено ниже, а пока нам важно обратить внимание на такой нюанс. В MqlCalendarValue есть поле event_id, которое указывает на идентификатор разновидности события, то есть содержит один из существующих id в структурах MqlCalendarEvent.

Как мы видели выше, структура MqlCalendarEvent в свою очередь имеет связь с MqlCalendarCountry через поле country_id. Таким образом, внеся один раз информацию о конкретной стране или виде события в базу календаря, можно регистрировать для них произвольное количество однотипных событий. Разумеется, наполнением базы занимается поставщик информации, а не разработчики.

Подведем промежуточный итог: система хранит раздельно три внутренних таблицы:

  • таблицу структур MqlCalendarCountry для описания стран;
  • таблицу структур MqlCalendarEvent с описаниями видов событий;
  • таблицу структур MqlCalendarValue с показателями конкретных событий различных видов.

За счет ссылок на идентификаторы видов событий из записей о конкретных событиях исключается дублирование информации. Например, ежемесячные публикации значений CPI лишь ссылаются на одну и ту же структуру MqlCalendarEvent с общими характеристиками этого вида событий. Если бы не разные таблицы, потребовалось бы в каждой записи календаря о CPI повторять одни и те же свойства. Данный подход к установлению отношений между таблицами с данными с помощью полей-идентификаторов называется реляционным, и мы еще вернемся к нему в главе про SQLite. Все это проиллюстрировано на следующей схеме.

Схема связей между структурами по полям с идентификаторами

Схема связей между структурами по полям с идентификаторами

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

Записи календаря (конкретные события) — это структуры MqlCalendarValue. Они также идентифицируется по собственному уникальному номеру в поле id (в каждой из трех таблиц свое поле id).

struct MqlCalendarValue 

   ulong      id;                 // ID записи 
   ulong      event_id;           // ID вида события 
   datetime   time;               // время и дата события 
   datetime   period;             // отчетный период события 
   int        revision;           // ревизия публикуемого индикатора по отношению к отчетному периоду 
   long       actual_value;       // актуальное значение в миллионных долях или LONG_MIN 
   long       prev_value;         // предыдущее значение в миллионных долях или LONG_MIN 
   long       revised_prev_value// пересмотренное предыдущее значение в миллионных долях или LONG_MIN 
   long       forecast_value;     // прогнозное значение в миллионных долях или LONG_MIN 
   ENUM_CALENDAR_EVENT_IMPACT impact_type;  // потенциальное влияние на курс валюты
    
   // функции для проверки значений 
   bool HasActualValue(voidconst;     // true, если поле actual_value заполнено 
   bool HasPreviousValue(voidconst;   // true, если поле prev_value заполнено 
   bool HasRevisedValue(voidconst;    // true, если поле revised_prev_value заполнено 
   bool HasForecastValue(voidconst;   // true, если поле forecast_value заполнено
    
   // функции для получение значений 
   double GetActualValue(voidconst;   // actual_value или nan, если значение не задано 
   double GetPreviousValue(voidconst// prev_value или nan, если значение не задано 
   double GetRevisedValue(voidconst;  // revised_prev_value или nan, если значение не задано 
   double GetForecastValue(voidconst// forecast_value или nan, если значение не задано 
};

Для каждого события, помимо времени его публикации (time), предусмотрено хранение 4-х значений:

  • актуального показателя (actual_value), который становится известен сразу после публикации новости;
  • предыдущего показателя (prev_value), ставшего известным в прошлый выход той же новости;
  • пересмотренного значения предыдущего показателя, revised_prev_value (если оно было изменено с момента прошлой публикации);
  • прогнозного значения (forecast_value);

Очевидно, что могут быть заполнены не все поля. Так, актуальный показатель отсутствует (еще не известен) у будущих событий, а пересмотр прошлых значений также происходит не всегда. Кроме того, все 4 поля имеют смысл только для количественных показателей, в то время как календарь отражает также выступления регуляторов, встречи и праздники.

Пустое поле (отсутствие значения) обозначается константой LONG_MIN (-9223372036854775808). Если значение в поле задано (не равно LONG_MIN), то оно соответствует увеличенной в миллион раз реальной величине показателя, то есть для получения показателя в привычном (вещественном) виде необходимо разделить значение поля на 1000000.

Для удобства программиста в структуре определены 4 Has-метода для проверки заполненности поля, а также 4 Get-метода, возвращающих уже преобразованное в вещественное число значение соответствующего поля, причем в случае, когда оно не заполнено, метода вернет NaN (Not A Number).

Иногда для получения абсолютных величин (если они требуются для алгоритма) важно дополнительно анализировать свойство multiplier в структуре MqlCalendarEvent, так как некоторые показатели указываются в кратных единицах согласно перечислению ENUM_CALENDAR_EVENT_MULTIPLIER. Кроме того, в MqlCalendarEvent есть поле digits, задающее количество значащих цифр в получаемых значениях для последующего корректного форматирования (например, в вызове NormalizeDouble).

Отчетный период (за который посчитан публикуемый показатель) задается в поле period его первым днем. Например, если показатель считается ежемесячно, то дата '2022.05.01 00:00:00' означает месяц май. Длительность периода (например, месяц, квартал, год) определена в поле frequency связанной структуры MqlCalendarEvent: типом этого поля является специальное перечисление ENUM_CALENDAR_EVENT_FREQUENCY, описанное выше, вместе с другими перечислениями.

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

Потенциальное влияние события на курс национальной валюты указывается с помощью перечисления ENUM_CALENDAR_EVENT_IMPACT.

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

Описание

CALENDAR_IMPACT_NA

Влияния не указано

CALENDAR_IMPACT_POSITIVE

Положительное влияние

CALENDAR_IMPACT_NEGATIVE

Отрицательное влияние

Еще одним важным понятием календаря является факт его изменения. Специальной структуры для изменения, к сожалению, не предусмотрено. Единственное свойство, которым обладает изменение, — это его уникальный идентификатор — целое число, присваиваемое системой при каждом изменении внутренней базы календаря.

Как известно, календарь постоянно модифицируется поставщиками информации — в него добавляются новые грядущие события, корректируются уже опубликованные показатели и прогнозы. Поэтому очень важно отслеживать любые правки, появление которых и дают обнаружить периодически увеличивающиеся номера изменений.

Время правки с конкретным идентификатором и её суть в MQL5 недоступны. При необходимости MQL-программы должны сами реализовать периодические запросы состояния календаря и анализ записей.

Получить информацию о странах, видах событий и конкретных записях календаря, а также их изменениях позволяет набор функций MQL5, которые мы рассмотрим в следующих разделах.

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