DRAW_COLOR_BARS

El estilo DRAW_COLOR_BARS dibuja las barras basándose en los valores de cuatro búfers indicadores que contienen los precios Open, High, Low y Close. Este estilo es una versión más avanzada del estilo DRAW_BARS y permite establecer para cada barra su propio color desde un conjunto de colores predefinido previamente. Se utiliza para crear sus propios indicadores personalizados en forma de barras, también en otra subventana del gráfico y para otros instrumentos financieros.

El color de las barras 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 dibuja sólo para las barras que tienen establecidos los valores no vacíos de todos los cuatro búfers indicadores. Para indicar qué valor se debe considerar "vacío", establezca este valor en la propiedad PLOT_EMPTY_VALUE:

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

Rellene siempre los búfers indicadores con valores de forma explícita, para las barras que se ignoran indique en el búfer un valor vacío.

El número de búfers requeridos para construir DRAW_COLOR_BARS – 5:

  • cuatro búfers para almacenar los valores Open, High, Low y Close;
  • un búfer para almacenar el índice de color con el que se dibuja la barra (tiene sentido establecerlo sólo para las barras a dibujar).

Todos los búfers que se utilizan para la construcción deben ir en serie uno detrás del otro en orden establecido: Open, High, Low, Close y el búfer de color. Ninguno de los búfers de precios puede contener sólo los valores vacíos, porque en este caso no se dibuja nada.

Aquí tenemos un ejemplo del indicador que dibuja en una ventana separada las barras para el instrumento financiero especificado. El color de las barras se cambia 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).

Ejemplo del estilo DRAW_COLOR_BARS

Fíjense, inicialmente para la construcción gráfica plot1 con el estilo DRAW_COLOR_BARS se establecen 8 colores mediante la directiva del compilador #property, y luego en la función OnCalculate() el color se elige aleatoriamente de 14 colores que se guardan en el array colors[].

//+------------------------------------------------------------------+
//|                                              DRAW_COLOR_BARS.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_BARS"
#property description "Dibuja en la ventana separada las barras de diferentes colores para el símbolo seleccionado"
#property description "El color y el grosor de las barras, igual que el estilo, se cambian de forma aleatoria "
#property description "cada N tics"
 
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots   1
//--- plot ColorBars
#property indicator_label1  "ColorBars"
#property indicator_type1   DRAW_COLOR_BARS
//--- estableceremos 8 colores para colorear las barras (se guardan en un array especial)
#property indicator_color1  clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- parámetros input
input int      N=5;              // número de tics para el cambio de apariencia
input int      bars=500;         // número de barras a mostrar
input bool     messages=false;   // mostrar mensajes en el log "Asesores Expertos"
//--- búfers indicadores
double         ColorBarsBuffer1[];
double         ColorBarsBuffer2[];
double         ColorBarsBuffer3[];
double         ColorBarsBuffer4[];
double         ColorBarsColors[];
//--- nombre del símbolo
string symbol;
int    bars_colors;
//--- el array para almacenar colores tiene 14 elementos
color colors[]=
  {
   clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
   clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrMagenta,clrCyan,clrMediumPurple
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ColorBarsBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,ColorBarsBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,ColorBarsBuffer3,INDICATOR_DATA);
   SetIndexBuffer(3,ColorBarsBuffer4,INDICATOR_DATA);
   SetIndexBuffer(4,ColorBarsColors,INDICATOR_COLOR_INDEX);
//---- número de colores para colorear las barras
   bars_colors=8;   //  ver comentario para la propiedad #property indicator_color1
//---
   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 barra
   ticks++;
//--- si tenemos acumulado un número suficiente de tics
   if(ticks>=N)
     {
      //--- escogeremos nuevo símbolo en la ventana "Observación del mercado"
      symbol=GetRandomSymbolName();
      //--- cambiamos las propiedades de la línea
      ChangeLineAppearance();
      //--- cambiamos los colores con los que se dibujan las barras
      ChangeColors(colors,bars_colors);
      int tries=0;
      //--- haremos 5 intentos de llenar el búfer con los precios desde symbol
      while(!CopyFromSymbolToBuffers(symbol,rates_total,bars_colors) && tries<5)
        {
         //--- contador de llamadas a la función CopyFromSymbolToBuffers()
         tries++;
        }
      //--- actualizamos el contador de tics pasándolo a cero
      ticks=0;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|  Llenamos los búfers indicadores con los precios                 |
//+------------------------------------------------------------------+
bool CopyFromSymbolToBuffers(string name,int total,int bar_colors)
  {
//--- vamos a copiar los precios Open, High, Low y Close al array rates[]
   MqlRates rates[];
//--- contador de intentos
   int attempts=0;
//--- cantidad que se ha copiado ya
   int copied=0;
//--- hacemos 25 intentos de obtener la serie temporal para el símbolo necesario
   while(attempts<25 && (copied=CopyRates(name,_Period,0,bars,rates))<0)
     {
      Sleep(100);
      attempts++;
      if(messagesPrintFormat("%s CopyRates(%s) attempts=%d",__FUNCTION__,name,attempts);
     }
//--- si no se ha podido copiar la cantidad suficiente de barras
   if(copied!=bars)
     {
      //--- formaremos la cadena del mensaje
      string comm=StringFormat("Para el símbolo %s se ha logrado obtener sólo %d barras de %d solicitadas",
                               name,
                               copied,
                               bars
                               );
      //--- mostraremos el mensaje en un comentario en la ventana principal del gráfico
      Comment(comm);
      //--- mostramos el mensaje
      if(messagesPrint(comm);
      return(false);
     }
   else
     {
      //--- estableceremos la visualización del símbolo 
      PlotIndexSetString(0,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Close");
      IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_COLOR_BARS("+name+")");
     }
//--- inicializaremos los búfers con valores vacíos
   ArrayInitialize(ColorBarsBuffer1,0.0);
   ArrayInitialize(ColorBarsBuffer2,0.0);
   ArrayInitialize(ColorBarsBuffer3,0.0);
   ArrayInitialize(ColorBarsBuffer4,0.0);
 
//--- copiamos los precios a los búfers
   for(int i=0;i<copied;i++)
     {
      //--- calcularemos el índice correspondiente para los búfers
      int buffer_index=total-copied+i;
      //--- escribimos los precios en los búfers
      ColorBarsBuffer1[buffer_index]=rates[i].open;
      ColorBarsBuffer2[buffer_index]=rates[i].high;
      ColorBarsBuffer3[buffer_index]=rates[i].low;
      ColorBarsBuffer4[buffer_index]=rates[i].close;
      //---
      ColorBarsColors[buffer_index]=i%bar_colors;
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| devuelve aleatoriamente el símbolo desde Market Watch            |
//+------------------------------------------------------------------+
string GetRandomSymbolName()
  {
//--- número de símbolos mostrados en la ventana "Observación del mercado"
   int symbols=SymbolsTotal(true);
//--- posición del símbolo en la lista - un número aleatorio de 0 a symbols
   int number=MathRand()%symbols;
//--- devolvemos el nombre del símbolo sobre la posición indicada
   return SymbolName(number,true);
  }
//+------------------------------------------------------------------+
//|  cambia el color de segmentos del zigzag
//+------------------------------------------------------------------+
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("BarColorIndex[%d]=%s \r\n",plot_color_ind,ColorToString(cols[i],true));
      ChartSetString(0,CHART_COMMENT,comm);
     }
//---
  }
//+------------------------------------------------------------------+
//| cambia la apariencia de las barras                               |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
  {
//--- cadena para formar la información sobre las propiedades de las barras
   string comm="";
 
//--- bloque del cambio del grosor de las barras
   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+"\r\nWidth="+IntegerToString(width);
 
//--- apuntamos el nombre del símbolo
   comm="\r\n"+symbol+comm;
 
//--- mostraremos la información en el gráfico a través del comentario
   Comment(comm);
  }