DRAW_SECTION

El estilo DRAW_SECTION dibuja los segmentos de color especificado a base de los valores del búfer indicador. El grosor, color y el estilo de la línea 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 "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_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_SECTION – 1.

Aquí tenemos un ejemplo del indicador que traza segmentos entre los precios High y Low. El color, grosor y el estilo de todos los segmentos se cambian de forma aleatoria cada N tics.

Ejemplo del estilo DRAW_SECTION

Fíjense que inicialmente para la construcción gráfica plot1 con el estilo DRAW_SECTION 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_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_SECTION"
#property description "Dibujamos con segmentos rectos dentro de cada bars barras"
#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 1
#property indicator_plots   1
//--- plot Section
#property indicator_label1  "Section"
#property indicator_type1   DRAW_SECTION
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- parámetro input
input int      bars=5;           // longitud del segmento en barras
input int      N=5;              // número de tics para el cambio del estilo de segmentos
//--- búfer indicador para la construcción
double         SectionBuffer[];
//--- una variable auxiliar para calcular los extremos de segmentos
int            divider;
//--- 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()
  {
//--- vinculación del array con el búfer indicador
   SetIndexBuffer(0,SectionBuffer,INDICATOR_DATA);
//--- el valor 0 (valor vacío) no va a participar en el proceso de trazado
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- comprobaremos el parámetro del indicador
   if(bars<=0)
     {
      PrintFormat("Valor del parámetro bar=%d inválido",bars);
      return(INIT_PARAMETERS_INCORRECT);
     }
   else divider=2*bars;
//---+
   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;
     }
 
//--- 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++)
     {
      //--- obtendremos el remanente de la división del número de la barra por 2*bars
      int rest=i%divider;
      //--- si el número de la barra se divide por 2*bars sin remanente
      if(rest==0)
        {
         //--- estableceremos el extremo del segmento en el precio High de esta barra
         SectionBuffer[i]=high[i];
        }
      //--- si la remanente de la división es igual a bars, 
      else
        {
         //--- estableceremos el extremo del segmento en el precio High de esta barra
         if(rest==bars) SectionBuffer[i]=low[i];
         //--- si no encaja nada, omitimos esta barra - ponemos el valor 0
         else SectionBuffer[i]=0;
        }
     }
//--- volveremos el valor prev_calculated para la siguiente llamada de la función
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| cambia la apariencia del segmento 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
   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;
//--- mostraremos la información en el gráfico a través del comentario
   Comment(comm);
  }