DRAW_COLOR_SECTION

Стиль DRAW_COLOR_SECTION является цветным вариантом стиля DRAW_SECTION, но в отличие от последнего, позволяет рисовать каждую секцию собственным цветом. Стиль DRAW_COLOR_SECTION, как и все цветные стили, имеющие в название COLOR, содержит дополнительный специальный индикаторный буфер для хранения индекса (номера) цвета из специального заданного массива цветов. Таким образом, цвет каждой секции можно задать, если указать индекса цвета для бара, на который приходится конец секции.

Толщину, цвет и стиль отрезков можно задавать так же, как и для стиля DRAW_SECTIONдирективами компилятора или динамически с помощью функции PlotIndexSetInteger(). Динамическое изменение свойств графического построения позволяет "оживить" индикаторы, чтобы они меняли свой вид в зависимости от  текущей ситуации.

Секции рисуются от одного непустого значения до другого непустого значения индикаторного буфера, пустые значения пропускаются. Чтобы указать, какое значение следует считать "пустым", установите это значение в свойстве PLOT_EMPTY_VALUE. Например, если индикатор должен рисоваться отрезками по ненулевым значениям, то нужно задать нулевое значение в качестве пустого:

//--- значение 0 (пустое значение) не будет участвовать в отрисовке
   PlotIndexSetDouble(индекс_построения_DRAW_COLOR_SECTION,PLOT_EMPTY_VALUE,0);

Всегда явно заполняйте значениями все элементы индикаторного буфера, неотрисовываемым элементам задавайте пустое значение.

Количество требуемых буферов для построения DRAW_COLOR_SECTION — 2:

  • один буфер для хранения значений индикатора, по которым рисуется линия;
  • один буфер для хранения индекса цвета, которым рисуется секция (имеет смысл задавать только для непустых значений).

Цвета можно задавать директивой компилятора #property indicator_color1 через запятую. Количество цветов не может превышать 64.

Пример индикатора, рисующего разноцветные секции длиной 5 баров по ценам High. Цвет, толщина и стиль секций меняются случайным образом каждые N тиков.

Пример стиля DRAW_COLOR_SECTION

Обратите внимание, первоначально для графического построения plot1 со стилем DRAW_COLOR_SECTION свойства задается 8 цветов с помощью директивы компилятора #property. Затем в функции OnCalculate() цвета задаются случайным образом из массива цветов colors[].

Параметр N вынесен во внешние параметры индикатора для возможности ручной установки (закладка "Параметры" в окне свойств индикатора).

//+------------------------------------------------------------------+
//|                                           DRAW_COLOR_SECTION.mq5 |
//|                         Copyright 2000-2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#property description "Индикатор для демонстрации DRAW_COLOR_SECTION"
#property description "Рисует цветными отрезками длиной в заданное число баров"
#property description "Цвет, толщина и стиль секций меняется случайным образом"
#property description "через каждые N тиков"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot ColorSection
#property indicator_label1  "ColorSection"
#property indicator_type1   DRAW_COLOR_SECTION
//--- зададим 8 цветов для раскраски секций (они хранятся в специальном массиве)
#property indicator_color1  clrRed,clrGold,clrMediumBlue,clrLime,clrMagenta,clrBrown,clrTan,clrMediumVioletRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input параметры
input int      N=5;                      // кол-во тиков для изменения 
input int      bars_in_section=5;        // длина секций в барах
//--- вспомогательная переменная для вычисления концов секций
int            divider;
int            color_sections;
//--- буфер для отрисовки
double         ColorSectionBuffer[];
//--- буфер для хранения цвета отрисовки линии на каждом баре
double         ColorSectionColors[];
//--- массив для хранения цветов содержит 14 элементов
color colors[]=
  {
   clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
   clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrWhiteSmoke,clrCyan,clrMediumPurple
  };
//--- массив для хранения стилей отрисовки линии
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ColorSectionBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ColorSectionColors,INDICATOR_COLOR_INDEX);
//--- значение 0 (пустое значение) не будет участвовать в отрисовке
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---- количество цветов для раскраски секций
   color_sections=8;   //  см. комментарий к свойству #property indicator_color1
//--- проверим параметр индикатора
   if(bars_in_section<=0)
     {
      PrintFormat("Недопустимое значение длины секции=%d",bars_in_section);
      return(INIT_PARAMETERS_INCORRECT);
     }
   else divider=color_sections*bars_in_section;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   static int ticks=0;
//--- считаем тики для изменения стиля, цвета и толщины линии
   ticks++;
//--- если накопилось критическое число тиков
   if(ticks>=N)
     {
      //--- меняем свойства линии
      ChangeLineAppearance();
      //--- меняем цвета, которыми рисуются секции
      ChangeColors(colors,color_sections);
      //--- сбрасываем счетчик тиков в ноль
      ticks=0;
     }
 
//--- номер бара, с которого начнем расчет значений индикатора
   int start=0;
//--- если индикатор уже рассчитывали раньше, то установим start на предыдущий бар
   if(prev_calculated>0) start=prev_calculated-1;
//--- здесь все расчеты значений индикатора
   for(int i=start;i<rates_total;i++)
     {
      //--- если номер бара делится без остатка на длину_секции, значит это конец секции
      if(i%bars_in_section==0)
        {
         //--- конец отрезка установим на цену High этого бара
         ColorSectionBuffer[i]=high[i];
         //--- остаток от деления номера бара на длина_секции*количество_цветов
         int rest=i%divider;
         //получим номер цвета =  от 0 до количество_цветов-1
         int color_indext=rest/bars_in_section;
         ColorSectionColors[i]=color_indext;
        }
      //--- если остаток от деления равен bars, 
      else
        {
         //--- если ничего не подошло, то этот бар пропускаем - ставим значение 0
         ColorSectionBuffer[i]=0;
        }
     }
//--- вернем значение prev_calculated для следующего вызова функции
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Изменяет цвет участков линии                                     |
//+------------------------------------------------------------------+
void  ChangeColors(color  &cols[],int plot_colors)
  {
//--- количество цветов 
   int size=ArraySize(cols);
//--- 
   string comm=ChartGetString(0,CHART_COMMENT)+"\r\n\r\n";
 
//--- для каждого цветового индекса зададим новый цвет случайным образом
   for(int plot_color_ind=0;plot_color_ind<plot_colors;plot_color_ind++)
     {
      //--- получим случайное число
      int number=MathRand();
      //--- получим индекс в массиве col[] как остаток от целочисленного деления
      int i=number%size;
      //--- установим цвет для каждого индекса как свойство PLOT_LINE_COLOR
      PlotIndexSetInteger(0,                    //  номер графического стиля
                          PLOT_LINE_COLOR,      //  идентификатор свойства
                          plot_color_ind,       //  индекс цвета, куда запишем цвет
                          cols[i]);             //  новый цвет
      //--- запишем цвета
      comm=comm+StringFormat("SectionColorIndex[%d]=%s \r\n",plot_color_ind,ColorToString(cols[i],true));
      ChartSetString(0,CHART_COMMENT,comm);
     }
//---
  }
//+------------------------------------------------------------------+
//| Изменяет внешний вид отображаемой линии в индикаторе             |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
  {
//--- строка для формирования информации о свойствах линии
   string comm="";
//--- блок изменения толщины линии
   int number=MathRand();
//--- получим толщину как остаток от целочисленного деления
   int width=number%5; // толщина задается от о до 4
//--- установим цвет как свойство PLOT_LINE_WIDTH
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width);
//--- запишем толщину линии
   comm=comm+" Width="+IntegerToString(width);
 
//--- блок изменения стиля линии
   number=MathRand();
//--- делитель числа равен размеру массива styles
   int size=ArraySize(styles);
//--- получим индекс для выбора нового стиля как остаток от целочисленного деления
   int style_index=number%size;
//--- установим цвет как свойство PLOT_LINE_COLOR
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,styles[style_index]);
//--- запишем стиль линии
   comm=EnumToString(styles[style_index])+", "+comm;
//--- выведем информацию на график через комментарий
   Comment(comm);
  }