Видимость объектов в разрезе таймфреймов

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

В MQL5 имеется аналогичное программное свойство — OBJPROP_TIMEFRAMES — оно управляет видимостью объекта на таймфрейма. Значением данного свойства может быть любая комбинация специальных целочисленных флагов: каждый флаг (константа) содержит бит, соответствующий одному таймфрейму (см. таблицу). Для установки/получения свойства OBJPROP_TIMEFRAMES следует использовать функции ObjectSetInteger/ObjectGetInteger.

Константа

Значение

Видимость на таймфреймах

OBJ_NO_PERIODS

0

Объект невидим на всех таймфреймах

OBJ_PERIOD_M1

0x00000001

M1

OBJ_PERIOD_M2

0x00000002

M2

OBJ_PERIOD_M3

0x00000004

M3

OBJ_PERIOD_M4

0x00000008

M4

OBJ_PERIOD_M5

0x00000010

M5

OBJ_PERIOD_M6

0x00000020

M6

OBJ_PERIOD_M10

0x00000040

M10

OBJ_PERIOD_M12

0x00000080

M12

OBJ_PERIOD_M15

0x00000100

M15

OBJ_PERIOD_M20

0x00000200

M20

OBJ_PERIOD_M30

0x00000400

M30

OBJ_PERIOD_H1

0x00000800

H1

OBJ_PERIOD_H2

0x00001000

H2

OBJ_PERIOD_H3

0x00002000

H3

OBJ_PERIOD_H4

0x00004000

H4

OBJ_PERIOD_H6

0x00008000

H6

OBJ_PERIOD_H8

0x00010000

H8

OBJ_PERIOD_H12

0x00020000

H12

OBJ_PERIOD_D1

0x00040000

D1

OBJ_PERIOD_W1

0x00080000

W1

OBJ_PERIOD_MN1

0x00100000

MN1

OBJ_ALL_PERIODS

0x001fffff

Все таймфреймы

Флаги можно комбинировать с помощью оператора побитового ИЛИ ("|"), например, суперпозиция флагов OBJ_PERIOD_M15 | OBJ_PERIOD_H4 означает, что объект будет видимым на 15-минутном и 4-часовом таймфреймах.

Обратите внимание, что каждый флаг можно получить сдвигом 1 влево на количество бит, равное номеру константы в таблице. Это облегчает динамическую генерацию флагов, когда алгоритм оперирует множеством таймфреймов, а не одним конкретным.

Мы воспользуемся такой возможностью в тестовом скрипте ObjectTimeframes.mq5. Его задача — создать на графике множество больших текстовых надписей с названиями таймфреймов, причем каждое название должно выводиться только на соответствующем таймфрейме. Например, крупная надпись "D1" будет видна только на дневном графике, а при переключении на H4 — увидим надпись "H4".

Для получения краткого названия таймфрейма, без префикса "PERIOD_", реализована простая вспомогательная функция.

string GetPeriodName(const int tf)
{
   const static int PERIOD_ = StringLen("PERIOD_");
   return StringSubstr(EnumToString((ENUM_TIMEFRAMES)tf), PERIOD_);
}

Получение списка всех таймфреймов из перечисления ENUM_TIMEFRAMES поручим функции EnumToArray, которую мы представили в разделе о конвертации Перечислений.

#include "ObjectPrefix.mqh"
#include <MQL5Book/EnumToArray.mqh>
 
void OnStart()
{
   ENUM_TIMEFRAMES tf = 0;
   int values[];
   const int n = EnumToArray(tfvalues0USHORT_MAX);
   ...

Все надписи будут выводиться в центре окна на момент запуска скрипта. Изменение размера окна после завершения работы скрипта приведет к тому, что созданные надписи перестанут быть отцентрированными. Это следствие того, что MQL5 поддерживает привязку только к углам окна, но не к центру. Если хочется автоматически поддерживать позицию объектов, следует реализовать аналогичный алгоритм в индикаторе и реагировать на события изменения размера окна. В качестве альтернативы мы могли бы выводить надписи в каком-либо углу, например, правом нижнем.

   const int centerX = (int)ChartGetInteger(0CHART_WIDTH_IN_PIXELS) / 2;
   const int centerY = (int)ChartGetInteger(0CHART_HEIGHT_IN_PIXELS) / 2;
   ...

В цикле по таймфреймам создаем для каждого из них объект OBJ_LABEL, размещаем его в середине окна, с привязкой по центру объекта.

   for(int i = 1i < n; ++i)
   {
      // create and setup text label for each timeframe
      const string name = ObjNamePrefix + (string)i;
      ObjectCreate(0nameOBJ_LABEL000);
      ObjectSetInteger(0nameOBJPROP_XDISTANCEcenterX);
      ObjectSetInteger(0nameOBJPROP_YDISTANCEcenterY);
      ObjectSetInteger(0nameOBJPROP_ANCHORANCHOR_CENTER);
      ...

Далее устанавливаем текст (название таймфрейма), большой размер шрифта, серый цвет и свойство отображения на заднем плане.

      ObjectSetString(0nameOBJPROP_TEXTGetPeriodName(values[i]));
      ObjectSetInteger(0nameOBJPROP_FONTSIZEfmin(centerYcenterX));
      ObjectSetInteger(0nameOBJPROP_COLORclrLightGray);
      ObjectSetInteger(0nameOBJPROP_BACKtrue);
      ...

Наконец, генерируем правильный флаг видимости для i-го таймфрейма и записываем его в свойство OBJPROP_TIMEFRAMES.

      const int flag = 1 << (i - 1);
      ObjectSetInteger(0nameOBJPROP_TIMEFRAMESflag);
   }

Посмотрите, что получилось на одном и то же графике при переключении таймфреймов.

Надписи с названиями таймфреймов

Надписи с названиями таймфреймов

Если открыть диалог Список объектов и включить в списке Все объекты, легко убедиться в наличии сгенерированных надписей для всех таймфреймов и проверить их флаги видимости.

Для удаления объектов можно запустить скрипт ObjectCleanup1.mq5.