DRAW_HISTOGRAM2

El estilo DRAW_HISTOGRAM2 dibuja un histograma de color especificado — segmentos verticales, usando valores de dos búfers indicadores. El grosor, color y el estilo de segmentos se puede establecer de la misma manera como para el estilo DRAW_LINE — 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.

El estilo DRAW_HISTOGRAM se puede utilizar tanto en una subventana separada del gráfico, como en la ventana principal. Los valores vacíos no se dibujan, todos los valores hay que establecer en los búfers indicadores de forma explícita. Los búfers no se inicializan con valores vacíos.

El número de búfers requeridos para construir DRAW_HISTOGRAM2 – 2.

Aquí tenemos un ejemplo del indicador que traza en cada barra un segmento vertical de color y grosor especificados entre los precios Open y Close. El color, grosor y el estilo de todas las columnas del histograma se cambian de forma aleatoria cada N tics. Cuando el indicador se inicia, en la función OnInit() se define al azar el número del día de la semana para el que el histograma no va a dibujarse — invisible_day. Para eso se establece el valor vacío PLOT_EMPTY_VALUE=0:

//--- estableceremos el valor vacío
   PlotIndexSetDouble(índice_ de_construcción_DRAW_SECTION,PLOT_EMPTY_VALUE,0);

Ejemplo del estilo DRAW_HISTOGRAM2

Fíjense que inicialmente para la construcción gráfica plot1 con el estilo DRAW_HISTOGRAM2 las propiedades se establecen mediante la directiva del compilador #property, y luego en la función OnCalculate() estas tres propiedades se establecen de forma aleatoria. 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_HISTOGRAM2.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_HISTOGRAM2"
#property description "Dibuja en cada barra un segmento entre Open y Close"
#property description "El color, grosor y el estilo se cambian de forma aleatoria"
#property description "dentro de cada N tics"
 
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot Histogram_2
#property indicator_label1  "Histogram_2"
#property indicator_type1   DRAW_HISTOGRAM2
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- input parameters
input int      N=5;              // número de tics para el cambio del histograma
//--- indicator buffers
double         Histogram_2Buffer1[];
double         Histogram_2Buffer2[];
//--- día de la semana para el que el indicador no se dibuja
int invisible_day;
//--- array para almacenar colores
color colors[]={clrRed,clrBlue,clrGreen};
//--- 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,Histogram_2Buffer1,INDICATOR_DATA);
   SetIndexBuffer(1,Histogram_2Buffer2,INDICATOR_DATA);
//--- estableceremos el valor vacío
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- obtenemos un número aleatorio de 0 a 5
   invisible_day=MathRand()%6;
//---
   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();
      //--- actualizamos el contador de tics pasándolo a cero
      ticks=0;
     }
 
//--- cálculos de los valores del indicador
   int start=0;
//--- para obtener el día de la semana por la hora de apertura de cada barra
   MqlDateTime dt;
//--- 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++)
     {
      TimeToStruct(time[i],dt);
      if(dt.day_of_week==invisible_day)
        {
         Histogram_2Buffer1[i]=0;
         Histogram_2Buffer2[i]=0;
        }
      else
        {
         Histogram_2Buffer1[i]=open[i];
         Histogram_2Buffer2[i]=close[i];
        }
     }
//--- volveremos el valor prev_calculated para la siguiente llamada de la función
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| cambia la apariencia de la línea en el indicador                 |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
  {
//--- cadena para formar la información sobre las propiedades de la línea
   string comm="";
//--- bloque del cambio del color de la línea
   int number=MathRand(); // obtenemos un número aleatorio
//--- el divisor del número es igual al tamaño del array colors[]
   int size=ArraySize(colors);
//--- obtenemos el índice para seleccionar nuevo color como el remanente de la división de números enteros
   int color_index=number%size;
//--- estableceremos el color como la propiedad PLOT_LINE_COLOR
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- apuntaremos el color de la línea
   comm=comm+"\r\n"+(string)colors[color_index];
 
//--- bloque de cambio del grosor de la línea
   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
//--- fijaremos el grosor de la línea
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width);
//--- apuntaremos el grosor de la línea
   comm=comm+"\r\nWidth="+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
   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 estilo de la línea
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,styles[style_index]);
//--- apuntaremos el estilo de la línea
   comm="\r\n"+EnumToString(styles[style_index])+""+comm;
//--- agregaremos la información sobre el día que se ignora en los cálculos
   comm="\r\nDía no dibujable - "+EnumToString((ENUM_DAY_OF_WEEK)invisible_day)+comm;
//--- mostraremos la información en el gráfico a través del comentario
   Comment(comm);
  }