DRAW_COLOR_HISTOGRAM

El estilo DRAW_COLOR_HISTOGRAM dibuja un histograma de columnas de diferentes colores desde cero hasta el valor especificado. Los valores se cogen desde el búfer indicador. Cada columna puede tener su propio color elegido de un conjunto previamente definido.

El grosor, color y el estilo del histograma se puede establecer de la misma manera como para el estilo DRAW_HISTOGRAM — con 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 cambiar la apariencia del histograma en función de la situación actual.

Ya que en cada barra se dibuja una columna desde el nivel cero, es mejor utilizar DRAW_COLOR_HISTOGRAM para mostrar en otra subventana del gráfico. Las más de las veces este tipo de construcción gráfica se utiliza para crear los indicadores del tipo oscilatorio, por ejemplo: Awesome Oscillator o Market Facilitation Index. Para los valores vacíos que no se muestran, será suficiente indicarlos valores nulos.

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

  • un búfer para almacenar el valor no nulo del segmento vertical en cada barra, el segundo extremos del segmento siempre se encuentra en la línea cero del indicador;
  • 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 con coma. El número de colores no puede superar 64.

Aquí tenemos un ejemplo del indicador que dibuja una sinusoide de color especificado basándose en la función MathSin(). El color, grosor y el estilo de todas las columnas se cambian de forma aleatoria cada N tics. El parámetro bars determina el período de la sinusoide, eso quiere decir que dentro de una cantidad de barras especificada la sinusoide va a repetir su ciclo.

Ejemplo del estilo DRAW_COLOR_HISTOGRAM

Fíjense, inicialmente para la construcción gráfica plot1 con el estilo DRAW_COLOR_HISTOGRAM se establecen 5 colores mediante la directiva del compilador #property indicator_color1, y luego en la función OnCalculate() estos colores se eligen aleatoriamente de 14 colores que se guardan en el array 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_HISTOGRAM.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_HISTOGRAM"
#property description "Dibuja la sinusoide como un histograma en otra ventana"
#property description "El color y el grosor de las columnas se cambian de forma aleatoria"
#property description "dentro de cada N tics"
#property description "El parámetro bars establece el número de barras para la repetición de la sinusoide"
 
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   1
//--- parámetros input
input int      bars=30;          // período de la sinusoide en barras
input int      N=5;              // número de tics para el cambio del histograma
//--- plot Color_Histogram
#property indicator_label1  "Color_Histogram"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
//--- estableceremos 8 colores para colorear los segmentos (se guardan en un array especial)
#property indicator_color1  clrRed,clrGreen,clrBlue,clrYellow,clrMagenta,clrCyan,clrMediumSeaGreen,clrGold
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- búfer de valores
double         Color_HistogramBuffer[];
//--- búfer para los índices de colores
double         Color_HistogramColors[];
//--- factor para obtener el ángulo 2Pi en radiánes al multiplicar por el parámetro bars
double         multiplier;
int            color_sections;
//--- 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,Color_HistogramBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,Color_HistogramColors,INDICATOR_COLOR_INDEX);
//---- número de colores para colorear la sinusoide
   color_sections=8;   //  ver comentario para la propiedad #property indicator_color1   
//--- calcularemos el multiplicador
   if(bars>1)multiplier=2.*M_PI/bars;
   else
     {
      PrintFormat("Establezca el valor bars=%d mayor que 1",bars);
      //--- finalización anticipada del trabajo del indicador
      return(INIT_PARAMETERS_INCORRECT);
     }   
//---
   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 los colores con los que se dibuja el histograma
      ChangeColors(colors,color_sections);      
      //--- actualizamos el contador de tics pasándolo a cero
      ticks=0;
     }
 
//--- cálculos de los valores del indicador
   int start=0;
//--- si el cálculo ya ha sido realizado en el arranque anterior de OnCalculate
   if(prev_calculated>0) start=prev_calculated-1; // fijaremos el inicio del cálculo a partir de penúltima barra
//--- llenamos el búfer indicador con valores
   for(int i=start;i<rates_total;i++)
     {
      //--- valor
      Color_HistogramBuffer[i]=sin(i*multiplier);
      //--- color
      int color_index=i%(bars*color_sections);
      color_index/=bars;
      Color_HistogramColors[i]=color_index;
     }
//--- 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("HistogramColorIndex[%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);
  }