Символы и таймфреймы

Временные ряды с котировками идентифицируются двумя параметрами: именем символа (финансового инструмента) и таймфреймом (периодом).

Пользователь видит перечень символов в окне Обзора рынка и может редактировать его на основе общего списка, предоставляемого брокером (диалог Символы). Для MQL-программ существует набор функций, с помощью которых можно делать то же самое: "пролистать" все символы, узнать их свойства и добавить или удалить в/из Обзор рынка. Этим функциям будет посвящена отдельная глава.

Однако для запроса таймсерий достаточно лишь знать имя символа — это строка, содержащая обозначение существующего финансового инструмента. Его, например, может задавать пользователь во входной переменной. Кроме того, символ текущего графика можно узнать из встроенной переменной _Symbol (или функции Symbol), но для нашего удобства все функции таймсерий поддерживают соглашение, что значение NULL также соответствует символу текущего графика.

Теперь обратимся к таймфреймам. В системе определен 21 стандартный таймфрейм: каждый задается элементом в специальном перечислении ENUM_TIMEFRAMES.

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

Значение (Hex)

Описание

PERIOD_CURRENT

0

Текущий период графика

PERIOD_M1

1 (0x1)

1 минута

PERIOD_M2

2 (0x2)

2 минуты

PERIOD_M3

3 (0x3)

3 минуты

PERIOD_M4

4 (0x4)

4 минуты

PERIOD_M5

5 (0x5)

5 минут

PERIOD_M6

6 (0x6)

6 минут

PERIOD_M10

10 (0xA)

10 минут

PERIOD_M12

12 (0xC)

12 минут

PERIOD_M15

15 (0xF)

15 минут

PERIOD_M20

20 (0x14)

20 минут

PERIOD_M30

30 (0x1E)

30 минут

PERIOD_H1

16385 (0x4001)

1 час

PERIOD_H2

16386 (0x4002)

2 часа

PERIOD_H3

16387 (0x4003)

3 часа

PERIOD_H4

16388 (0x4004)

4 часа

PERIOD_H6

16390 (0x4006)

6 часов

PERIOD_H8

16392 (0x4008)

8 часов

PERIOD_H12

16396 (0x400C)

12 часов

PERIOD_D1

16408 (0x4018)

1 день

PERIOD_W1

32769 (0x8001)

1 неделя

PERIOD_MN1

49153 (0xC001)

1 месяц

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

Значение для минутных таймфреймов совпадают с количеством минут в них (например, 30 обозначает M30). Для часовых таймфреймов взведен бит 0x4000, а в нижнем байте содержится количество часов (например, 0x4003 для H3). Дневной период D1 кодируется как 24 часа — 0x4018 (0x18 равно 24). Наконец, недельный и месячный таймфреймы имеют свои собственные отличительные биты 0x8000 и 0xC000, соответственно, как индикаторы единиц измерения, а количество (в младшем байте) в обоих случаях равно 1.

Для удобной конвертации элементов перечисления в строки и обратно к книге прилагается заголовочный файл Periods.mqh (мы его уже использовали в примере работы с файлами и будем использовать в будущих примерах). Одна из входящих в него функций StringToPeriod использует в своем алгоритме вышеописанные особенности внутреннего битового представления элементов перечисления.

#define PERIOD_PREFIX_LENGTH 7 // StringLen("PERIOD_")
   
// получаем сокращенное имя периода без префикса "PERIOD_"
string PeriodToString(const ENUM_TIMEFRAMES tf = PERIOD_CURRENT)
{
   const static int prefix = StringLen("PERIOD_");
   return StringSubstr(EnumToString(tf == PERIOD_CURRENT ? _Period : tf),
      PERIOD_PREFIX_LENGTH);
}
   
// получаем значение периода по полному (PERIOD_H4) или краткому (H4) имени   
ENUM_TIMEFRAMES StringToPeriod(string name)
{
   if(StringLen(name) < 2return 0;
   // преобразуем полное имя "PERIOD_TN" к краткому "TN", если надо
   if(StringLen(name) > PERIOD_PREFIX_LENGTH)
   {
     name = StringSubstr(namePERIOD_PREFIX_LENGTH);
   }
   // преобразуем цифровое окончание "N" в число, пропускаем "T"  
   const int count = (int)StringToInteger(StringSubstr(name1));
   // сбрасываем возможную ошибку WRONG_STRING_PARAMETER(5040)
   // например, если на входе строка "MN1", то N1 - не число для StringToInteger
   ResetLastError();
   switch(name[0])
   {
      case 'M':
         if(!countreturn PERIOD_MN1;
         return (ENUM_TIMEFRAMES)count;
      case 'H':
         return (ENUM_TIMEFRAMES)(0x4000 + count);
      case 'D':
         return PERIOD_D1;
      case 'W':
         return PERIOD_W1;
   }
   return 0;
}

 

Обратите внимание, что переменные _Symbol и _Period содержат актуальные данные только в MQL-программах, выполняющихся на графиках: скриптах, экспертах, индикаторах. В сервисах эти переменные пусты, и потому для доступа к таймсериям следует явным образом задавать имя символа и период, либо получать их каким-то образом извне.

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

int PeriodSeconds(ENUM_TIMEFRAMES period = PERIOD_CURRENT)

Параметр period задает интересующий период как элемент из перечисления ENUM_TIMEFRAMES. Если параметр не указан, то возвращается количество секунд текущего периода графика, на котором запущена программа.

Примеры использования функции мы рассмотрим в индикаторе IndDeltaVolume.mq5 в разделе Ожидание данных и управление видимостью, а также в индикаторе UseM1MA.mq5 в разделе Использование встроенных индикаторов.

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

Кроме того важно отметить, что в MetaTrader 5 продолжительность баров внутри конкретной таймсерии или на графике всегда одинакова. Поэтому для построения графиков, в которых бары формируются не по времени, а по мере накопления иных параметров, в частности, объемов (эквиобъемные графики) или движения цены в одном направлении фиксированными шагами (ренко), также предполагается разрабатывать собственные решения на базе индикаторов (например, с типом отрисовки DRAW_CANDLES или DRAW_BARS) или опять-таки пользовательских символов.