Объект-график

Объект-график OBJ_CHART позволяет создать внутри графика миниатюры других графиков — для других инструментов и таймфреймов. Объекты-графики включаются в общий список графиков, который мы получали программно с помощью функций ChartFirst и ChartNext. Как было сказано в разделе Проверка состояния основного окна, специальное свойство графика CHART_IS_OBJECT позволяет узнать по идентификатору, является ли он полноценным окном или объектом-графиком. В последнем случае вызов ChartGetInteger(id, CHART_IS_OBJECT) вернет true.

У объекта-графика имеется набор характерных только для него свойств.

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

Описание

Тип

OBJPROP_CHART_ID

Идентификатор графика (r/o)

long

OBJPROP_PERIOD

Период графика

ENUM_TIMEFRAMES

OBJPROP_DATE_SCALE

Признак отображения шкалы времени

bool

OBJPROP_PRICE_SCALE

Признак отображения ценовой шкалы

bool

OBJPROP_CHART_SCALE

Масштаб (значение в диапазоне 0 – 5)

int

OBJPROP_SYMBOL

Символ

string

Идентификатор, получаемый через свойство OBJPROP_CHART_ID, позволяет управлять объектом, как обычным графиком с помощью функций из главы Работа с графиками. Вместе с тем, существуют и некоторые ограничения:

По умолчанию все свойства (за исключением OBJPROP_CHART_ID) равны соответствующим свойствам текущего окна.

Демонстрация объектов-графиков реализована в виде безбуферного индикатора ObjectChart.mq5. Он создает подокно с двумя объектами-графиками для того же символа, что и текущий график, но со смежными таймфреймами — выше и ниже текущего.

Объекты привязываются к правому верхнему углу подокна и имеют одинаковые предопределенные размеры:

#define SUBCHART_HEIGHT 150
#define SUBCHART_WIDTH  200

Разумеется, высота подокна должна совпадать с высотой объектов, пока мы не умеем адаптивно реагировать на события изменения размера.

#property indicator_separate_window
#property indicator_height SUBCHART_HEIGHT
#property indicator_buffers 0
#property indicator_plots   0

Настройка одного мини-графика производится в функции SetupSubChart, которая принимает номер объекта, его размеры и требуемый таймфрейм. Результатом SetupSubChart является идентификатор объекта-графика, который мы просто для справки выводим в журнал.

void OnInit()
{
   Print(SetupSubChart(0SUBCHART_WIDTHSUBCHART_HEIGHTPeriodUp(_Period)));
   Print(SetupSubChart(1SUBCHART_WIDTHSUBCHART_HEIGHTPeriodDown(_Period)));
}

Макросы PeriodUp и PeriodDown используют вспомогательную функцию PeriodRelative.

#define PeriodUp(PPeriodRelative(P, +1)
#define PeriodDown(PPeriodRelative(P, -1)
   
ENUM_TIMEFRAMES PeriodRelative(const ENUM_TIMEFRAMES tfconst int step)
{
   static const ENUM_TIMEFRAMES stdtfs[] =
   {
      PERIOD_M1,  // =1 (1)
      PERIOD_M2,  // =2 (2)
      ...
      PERIOD_W1,  // =32769 (8001)
      PERIOD_MN1// =49153 (C001)
   };
   const int x = ArrayBsearch(stdtfstf == PERIOD_CURRENT ? _Period : tf);
   const int needle = x + step;
   if(needle >= 0 && needle < ArraySize(stdtfs))
   {
      return stdtfs[needle];
   }
   return tf;
}

А вот и основная рабочая функция SetupSubChart.

long SetupSubChart(const int nconst int dxconst int dy,
   ENUM_TIMEFRAMES tf = PERIOD_CURRENTconst string symbol = NULL)
{
   // создаем объект
   const string name = Prefix + "Chart-"
      + (symbol == NULL ? _Symbol : symbol) + PeriodToString(tf);
   ObjectCreate(0nameOBJ_CHARTChartWindowFind(), 00);
   
   // привязываем к правому верхнему углу подокна
   ObjectSetInteger(0nameOBJPROP_CORNERCORNER_RIGHT_UPPER);
   // позиция и размер
   ObjectSetInteger(0nameOBJPROP_XSIZEdx);
   ObjectSetInteger(0nameOBJPROP_YSIZEdy);
   ObjectSetInteger(0nameOBJPROP_XDISTANCE, (n + 1) * dx);
   ObjectSetInteger(0nameOBJPROP_YDISTANCE0);
   
   // специфические настройки графика
   if(symbol != NULL)
   {
      ObjectSetString(0nameOBJPROP_SYMBOLsymbol);
   }
   
   if(tf != PERIOD_CURRENT)
   {
      ObjectSetInteger(0nameOBJPROP_PERIODtf);
   }
   // отключаем вывод линеек   
   ObjectSetInteger(0nameOBJPROP_DATE_SCALEfalse);
   ObjectSetInteger(0nameOBJPROP_PRICE_SCALEfalse);
   // добавляем индикатор MA в объект по его id просто для демо   
   const long id = ObjectGetInteger(0nameOBJPROP_CHART_ID);
   ChartIndicatorAdd(id0iMA(NULLtf100MODE_EMAPRICE_CLOSE));
   return id;
}

Напомним, что у объекта-графика точка привязки всегда зафиксирована в левом верхнем углу объекта, поэтому при привязке к правому углу окна требуется добавлять ширину объекта (это делается за счет +1 в выражении (n + 1) * dx для OBJPROP_XDISTANCE).

На следующем скриншоте показан результат работы индикатора на графике XAUUSD,H1.

Два объекта-графика в подокне индикатора

Два объекта-графика в подокне индикатора

Как мы видим, в мини-графиках отображаются таймфреймы M30 и H2.

Важно отметить, что вы можете добавлять в объекты-графики индикаторы и применять к ним tpl-шаблоны, в том числе и с экспертом. Однако создавать объекты внутри объектов-графиков нельзя.

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