DRAW_FILLING

El estilo DRAW_FILLING dibuja un área de color entre los valores de dos búferes de indicadores. Prácticamente, este estilo traza dos líneas y colorea el espacio entre ellas en uno de dos colores predefinidos. Sirve para crear indicadores que dibujan canales. Ninguno de los dos búferes puede contener sólo valores vacíos. Si es así, no se dibuja nada.

Se puede definir dos colores para el relleno:

  • el primer color se utiliza para las áreas donde los valores en el primer búfer indicador son más altos que los valores en el segundo búfer indicador;
  • el segundo color se utiliza para las áreas donde los valores en el segundo búfer indicador son más altos que los valores en el primer búfer indicador.

El color de relleno se puede definir con las directivas del compilador, o dinámicamente a través de 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.

El indicador se calcula para todas las barras para las que los valores de ambos búferes de indicadores no son iguales a cero y no son iguales al valor vacío. Para indicar qué valor habrá que considerar como "vacío", especifíquelo en la propiedad PLOT_EMPTY_VALUE:

   #define INDICATOR_EMPTY_VALUE -1.0
   ...
//--- el valor INDICATOR_EMPTY_VALUE (valor vacío) no va a participar en el cálculo
   PlotIndexSetDouble(índice_de_construcción_DRAW_FILLING,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);

El dibujo sobre las barras que no participan en el cálculo del indicador va a depender de los valores situados en los búferes de indicadores:

  • Las barras para las que los valores de ambos búferes de indicadores son iguales a 0 no participan en el dibujo del indicador. Es decir el área con los valores iguales a cero no va a colorearse.

DRAW_FILLING_without_drawing

  • Las barras para las que los valores de los búferes de indicadores son iguales a "valor vacío" participan en el dibujo del indicador. El área con valores vacíos va a colorearse de tal manera que las zonas con valores significativos se unan.

DRAW_FILLING_with_drawing

Es importante mencionar que si el "valor vacío" es igual a cero, las barras que no participan en el cálculo del indicador también van a colorearse.

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

Aquí tenemos un ejemplo del indicador que dibuja en una ventana separada un canal entre dos medias móviles con diferentes períodos de promedio. El cambio de color durante el cruce de las medias muestra visualmente el cambio de la tendencia alcista y bajista. Los colores se cambian aleatoriamente cada N tics. El parámetro N está sacado 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_FILLING

Fíjense en que inicialmente para la construcción gráfica plot1 con el estilo DRAW_FILLING dos colores se establecen mediante la directiva del compilador #property, y luego en la función OnCalculate() nuevos colores se establecen de forma aleatoria.

//+------------------------------------------------------------------+
//|                                                 DRAW_FILLING.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_FILLING"
#property description "Dibuja en la ventana separada un canal entre dos medias móviles"
#property description "El color del relleno del canal se cambia de forma aleatoria"
#property description "dentro de cada N tics"
 
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot Intersection
#property indicator_label1  "Intersection"
#property indicator_type1   DRAW_FILLING
#property indicator_color1  clrRed,clrBlue
#property indicator_width1  1
//--- parámetros input
input int      Fast=13;          // período de la media móvil rápida
input int      Slow=21;          // período de la media móvil lenta
input int      shift=1;          // desplazamiento de las medias móviles hacia el futuro (positivo)
input int      N=5;              // número de tics a cambiar 
//--- búfers indicadores
double         IntersectionBuffer1[];
double         IntersectionBuffer2[];
int fast_handle;
int slow_handle;
//--- array para almacenar colores
color colors[]={clrRed,clrBlue,clrGreen,clrAquamarine,clrBlanchedAlmond,clrBrown,clrCoral,clrDarkSlateGray};
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,IntersectionBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,IntersectionBuffer2,INDICATOR_DATA);
//---
   PlotIndexSetInteger(0,PLOT_SHIFT,shift);
//---
   fast_handle=iMA(_Symbol,_Period,Fast,0,MODE_SMA,PRICE_CLOSE);
   slow_handle=iMA(_Symbol,_Period,Slow,0,MODE_SMA,PRICE_CLOSE);
//---
   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 suficiente de tics
   if(ticks>=N)
     {
      //--- cambiamos las propiedades de la línea
      ChangeLineAppearance();
      //--- actualizamos el contador de tics pasándolo a cero
      ticks=0;
     }
 
//--- hacemos el primer cálculo del indicador, o los datos han cambiado y se requiere el recálculo total
   if(prev_calculated==0)
     {
      //--- copiamos todos los valores de los indicadores a los búfers correspondientes
      int copied1=CopyBuffer(fast_handle,0,0,rates_total,IntersectionBuffer1);
      int copied2=CopyBuffer(slow_handle,0,0,rates_total,IntersectionBuffer2);
     }
   else // llenamos sólo aquellos datos que se han actualizado
     {
      //--- obtendremos la diferencia en barras entre el arranque actual y el anterior OnCalculate()
      int to_copy=rates_total-prev_calculated;
      //--- si no hay diferencia, igualmente copiaremos un valor - en la barra cero
      if(to_copy==0) to_copy=1;
      //--- copiamos to_copy valores al mismísimo final de los búfers indicadores
      int copied1=CopyBuffer(fast_handle,0,0,to_copy,IntersectionBuffer1);
      int copied2=CopyBuffer(slow_handle,0,0,to_copy,IntersectionBuffer2);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Cambia los colores del relleno del canal                         |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
  {
//--- cadena para formar la información sobre las propiedades de la línea
   string comm="";
//--- bloque de 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_index1=number%size;
//--- establecemos el primer color como la propiedad PLOT_LINE_COLOR
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,colors[color_index1]);
//--- apuntaremos el primer color
   comm=comm+"\r\nColor1 "+(string)colors[color_index1];
 
//--- obtenemos el índice para seleccionar nuevo color como el remanente de la división de números enteros
   number=MathRand(); // obtenemos un número aleatorio
   int color_index2=number%size;
//--- establecemos el segundo color como la propiedad PLOT_LINE_COLOR
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,colors[color_index2]);
//--- apuntaremos el segundo color
   comm=comm+"\r\nColor2 "+(string)colors[color_index2];
//--- mostraremos la información en el gráfico a través del comentario
   Comment(comm);
  }