DRAW_COLOR_SECTION

El estilo DRAW_COLOR_SECTION es la versión de colores del estilo DRAW_SECTION, pero a diferencia del último, permite colorear cada segmento con su propio color. El estilo DRAW_COLOR_SECTION, igual que todos los estilos de color en cuyo nombre figura COLOR, cuenta con un especial búfer indicador adicional que guarda el índice (número) del color desde un especial array de colores. De esta manera, se puede definir el color de cada segmento indicando un índice de color para la barra en la que cae el fin del segmento.

El grosor, color y el estilo de segmentos se puede establecer de la misma manera como para el estilo DRAW_SECTIONcon las directivas del compilador, o bien dinámicamente, utilizando la función PlotIndexSetInteger(). El cambio dinámico de las propiedades de la construcción gráfica permite "vivificar" los indicadores, para que cambien su apariencia en función de la situación actual.

Los segmentos se trazan desde un valor no vacío hasta otro valor no vacío del búfer indicador, ignorando los valores vacíos. Para indicar qué valor se debe considerar "vacío", establezca este valor en la propiedad PLOT_EMPTY_VALUE. Por ejemplo, si un indicador debe dibujarse con segmentos sobre los valores no nulos, entonces hay que establecer el valor nulo como vacío:

//--- el valor 0 (valor vacío) no va a participar en el proceso de trazado
   PlotIndexSetDouble(índice_ de_construcción_DRAW_COLOR_SECTION,PLOT_EMPTY_VALUE,0);

Rellene siempre todos los elementos del búfer indicador con valores de forma explícita, estableciendo el valor vacío para los elementos que no van a dibujarse.

El número de búfers requeridos para construir DRAW_COLOR_SECTION – 2:

  • un búfer para almacenar los valores del indicador a base de los cuales se traza la línea;
  • un búfer para almacenar el índice de color con el que se colorea el segmento (tiene sentido establecer sólo para los valores no vacíos).

Se puede definir los colores con la directiva del compilador #property indicator_color1, separados por coma. El número de colores no puede superar 64.

Aquí tenemos un ejemplo del indicador que dibuja segmentos de diferentes colores de 5 barras de longitud a base de los precios High. El color, grosor y el estilo de segmentos se cambian de forma aleatoria cada N tics.

Ejemplo del estilo DRAW_COLOR_SECTION

Fíjense, inicialmente para la construcción gráfica plot1 con el estilo DRAW_COLOR_SECTION se establecen 8 colores mediante la directiva del compilador #property. Luego en la función OnCalculate() los colores se establecen de forma aleatoria desde el array de colores colors[].

El parámetro N está pasado a los parámetros externos del indicador para que exista la posibilidad de establecerlo manualmente (pestaña "Parámetros" en la ventana de propiedades del indicador).

//+------------------------------------------------------------------+
//|                                           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 "Indicador para demostrar DRAW_COLOR_SECTION"
#property description "Dibuja con segmentos de colores de la longitud que corresponde al número de barras establecido"
#property description "El color, grosor y el estilo del segmento se cambia de forma aleatoria"
#property description "dentro de cada N tics"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot ColorSection
#property indicator_label1  "ColorSection"
#property indicator_type1   DRAW_COLOR_SECTION
//--- estableceremos 8 colores para colorear los segmentos (se guardan en un array especial)
#property indicator_color1  clrRed,clrGold,clrMediumBlue,clrLime,clrMagenta,clrBrown,clrTan,clrMediumVioletRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- parámetros input
input int      N=5;                      // número de tics a cambiar 
input int      bars_in_section=5;        // longitud de segmentos en barras
//--- una variable auxiliar para calcular los extremos de segmentos
int            divider;
int            color_sections;
//--- búfer para dibujar
double         ColorSectionBuffer[];
//--- búfer para almacenar el color del trazado de la línea en cada barra
double         ColorSectionColors[];
//--- el array para almacenar colores tiene 14 elementos
color colors[]=
  {
   clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
   clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrWhiteSmoke,clrCyan,clrMediumPurple
  };
//--- array para almacenar estilos de trazado de la línea
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);
//--- el valor 0 (valor vacío) no va a participar en el proceso de trazado
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---- número de colores para colorear los segmentos
   color_sections=8;   //  ver comentario para la propiedad #property indicator_color1
//--- comprobaremos el parámetro del indicador
   if(bars_in_section<=0)
     {
      PrintFormat("Segmento tiene una longitud inválida=%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;
//--- contamos los tics para el cambio del estilo, color y grosor de la línea
   ticks++;
//--- si tenemos acumulado un número crítico de tics,
   if(ticks>=N)
     {
      //--- cambiamos las propiedades de la línea
      ChangeLineAppearance();
      //--- cambiamos colores con los que se dibujan segmentos
      ChangeColors(colors,color_sections);
      //--- actualizamos el contador de tics pasándolo a cero
      ticks=0;
     }
 
//--- número de la barra a partir del cual empezaremos a calcular los valores del indicador
   int start=0;
//--- si el indicador ha sido calculado antes, estableceremos start para la barra anterior
   if(prev_calculated>0) start=prev_calculated-1;
//--- aquí están todos los cálculos de los valores del indicador
   for(int i=start;i<rates_total;i++)
     {
      //--- si el número de la barra se divide sin remanente por la longitud_del_segmento, entonces es el fin del segmento
      if(i%bars_in_section==0)
        {
         //--- estableceremos el extremo del segmento en el precio High de esta barra
         ColorSectionBuffer[i]=high[i];
         //--- remanente de la división del número de la barra por longitud_del_segmento*número_de_colores
         int rest=i%divider;
         //obtendremos el número del color =  de 0 a número_de_colores-1
         int color_indext=rest/bars_in_section;
         ColorSectionColors[i]=color_indext;
        }
      //--- si la remanente de la división es igual a bars, 
      else
        {
         //--- si no encaja nada, omitimos esta barra - ponemos el valor 0
         ColorSectionBuffer[i]=0;
        }
     }
//--- volveremos el valor prev_calculated para la siguiente llamada de la función
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|  cambia el color de segmentos de la línea                        |
//+------------------------------------------------------------------+
void  ChangeColors(color  &cols[],int plot_colors)
  {
//--- número de colores
   int size=ArraySize(cols);
//--- 
   string comm=ChartGetString(0,CHART_COMMENT)+"\r\n\r\n";
 
//--- definimos de forma aleatoria un color nuevo para cada índice de colores
   for(int plot_color_ind=0;plot_color_ind<plot_colors;plot_color_ind++)
     {
      //--- obtendremos un número aleatorio
      int number=MathRand();
      //--- obtendremos un índice en el array col[] como el remanente de la división de números enteros
      int i=number%size;
      //--- estableceremos el color para cada índice como la propiedad PLOT_LINE_COLOR
      PlotIndexSetInteger(0,                    //  número del estilo gráfico
                          PLOT_LINE_COLOR,      //  identificador de la propiedad
                          plot_color_ind,       //  índice del color donde escribiremos el color
                          cols[i]);             //  nuevo color
      //--- apuntaremos los colores
      comm=comm+StringFormat("SectionColorIndex[%d]=%s \r\n",plot_color_ind,ColorToString(cols[i],true));
      ChartSetString(0,CHART_COMMENT,comm);
     }
//---
  }
//+------------------------------------------------------------------+
//| cambia la apariencia de la línea trazada en el indicador         |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
  {
//--- cadena para formar la información sobre las propiedades de la línea
   string comm="";
//--- bloque de cambio del grosor de la línea
   int number=MathRand();
//--- obtenemos el grosor como el remanente de la división de números enteros
   int width=number%5; // el grosor puede ser de 0 a 4
//--- estableceremos el color como la propiedad PLOT_LINE_WIDTH
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width);
//--- apuntaremos el grosor de la línea
   comm=comm+" Width="+IntegerToString(width);
 
//--- bloque de cambio del estilo de la línea
   number=MathRand();
//--- el divisor del número es igual al tamaño del array styles
   int size=ArraySize(styles);
//--- obtenemos el índice para seleccionar nuevo estilo como el remanente de la división de números enteros
   int style_index=number%size;
//--- estableceremos el color como la propiedad PLOT_LINE_COLOR
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,styles[style_index]);
//--- apuntaremos el estilo de la línea
   comm=EnumToString(styles[style_index])+", "+comm;
//--- mostraremos la información en el gráfico a través del comentario
   Comment(comm);
  }