Поэлементное раскрашивание диаграмм

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

В следующей таблице приведены элементы ENUM_DRAW_TYPE с поддержкой цвета и количество буферов, требуемых для их отрисовки, включая 1 буфер с индексами цветов.

Тип визуализации

Описание

Количество
буферов

DRAW_COLOR_LINE

Разноцветная линия

1+1

DRAW_COLOR_SECTION

Разноцветные отрезки

1+1

DRAW_COLOR_ARROW

Разноцветные стрелки

1+1

DRAW_COLOR_HISTOGRAM

Разноцветная гистограмма от нулевой линии

1+1

DRAW_COLOR_HISTOGRAM2

Разноцветная гистограмма между попарными значениями двух индикаторных буферов

2+1

DRAW_COLOR_ZIGZAG

Разноцветный ZigZag

2+1

DRAW_COLOR_BARS

Разноцветные бары

4+1

DRAW_COLOR_CANDLES

Разноцветные свечи

4+1

В ходе привязки буферов к диаграммам следует учитывать, что дополнительный "цветовой" буфер должен быть указан в первом параметре SetIndexBuffer под номером, идущим непосредственно после буферов с данными. Например, для раскрашиваемой линии, где используется 1 буфер с данными и "цветовой" буфер, данные идут под номером 0, а их цвета под номером 1:

double ColorLineData[];
double ColorLineColors[];
   
void OnInit()
{
   SetIndexBuffer(0ColorLineDataINDICATOR_DATA);
   SetIndexBuffer(1ColorLineColorsINDICATOR_COLOR_INDEX);
   PlotIndexSetInteger(0PLOT_DRAW_TYPEDRAW_COLOR_LINE);
   ...
}

Начальный набор цветов в палитре для диаграммы N можно задать директивой #property indicator_colorN. В ней через запятую указываются необходимые цвета как именованные константы или литералы цвета. Например, следующая запись в индикаторе выберет 6 стандартных цветов для раскраски 0-ой диаграммы (в директивах нумерация начинается с 1):

#property indicator_color1   clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan

Далее в программе следует указывать не сам цвет, которым будет отображаться графическое построение, а только его индекс. Нумерация в палитре ведется как в обычном массиве — начиная с 0. Так, если для i-го бара нужно задать зеленый цвет, то достаточно установить в цветовом буфере индекс зеленого цвета из палитры, то есть 2 в данном случае.

   ColorLineColors[i] = 2// ссылка на элемент с цветом clrGreen

Набор цветов для раскрашивания не является раз и навсегда заданным, его можно менять динамически с помощью функции PlotIndexSetInteger(index, PLOT_LINE_COLOR, color).

Например, чтобы в вышеприведенной палитре заменить цвет clrGreen на clrGray следует выполнить вызов:

   PlotIndexSetInteger(0PLOT_LINE_COLORclrGray);

Применим цветовую раскраску в нашем индикаторе WPR. Новый файл — IndColorWPR.mq5. Изменения касаются следующих сфер.

Количество буферов увеличено на 1. Вместо одного цвета указано три.

#property indicator_buffers    2
#property indicator_plots      1
#property indicator_type1      DRAW_COLOR_LINE
#property indicator_color1     clrDodgerBlue,clrGreen,clrRed

Добавлен новый массив под буфер цветов и его регистрация в OnInit.

double WPRColors[];
 
void OnInit()
{
   ...
   SetIndexBuffer(1WPRColorsINDICATOR_COLOR_INDEX);
   ...

Если не задать тип буфера INDICATOR_COLOR_INDEX (т.е. с вызовом SetIndexBuffer(1, WPRColors) он трактовался бы по умолчанию как INDICATOR_DATA), он станет видимым в Окне данных.

В функции OnCalculate внутри рабочего цикла добавим раскраску на основе анализа значения i-го бара. По умолчанию берется цвет с 0-м индексом, то есть прежний clrDodgerBlue. Если показания индикатора уходят в верхнюю зону, они подсвечиваются цветом номер 2 (clrRed), а если в нижнюю зону — цветом номер 1 (clrGreen).

int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
{
   ...
   for(int i = fmax(prev_calculated - 1WPRPeriod - 1);
      i < rates_total && !IsStopped(); i++)
   {
      ...
      WPRColors[i] = 0;
      if(WPRBuffer[i] > -20WPRColors[i] = 2;
      else if(WPRBuffer[i] < -80WPRColors[i] = 1;
   }
   return rates_total;
}

Вот как это выглядит на экране.

Индикатор WPR с цветными зонами перекупленности и перепроданности

Индикатор WPR с цветными зонами перекупленности и перепроданности

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

Цвет отрезка линейной диаграммы DRAW_COLOR_LINE между двумя соседними барами определяется цветом правого (более свежего) бара.

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

      WPRColors[i] = 0;
      if(WPRBuffer[i] > -20 && WPRBuffer[i - 1] > -20WPRColors[i] = 2;
      else if(WPRBuffer[i] < -80 && WPRBuffer[i - 1] < -80WPRColors[i] = 1;

Также напомним, что мы добавили в исходный код установку заголовка и точности представления величин (2 знака). Сравнение нового изображения с прежним позволит заметить эти визуальные отличия. В частности, заголовок теперь имеет вид "%R(14)", а шакала значений по вертикали — намного компактнее.

Последний аспект, который мы изменим в индикаторе IndColorWPR.mq5 — это пропуск отрисовки на начальных барах.