Creación de indicadores multicolor en MQL5

Дмитрий Александрович | 19 diciembre, 2013

Introducción

Gracias a los esfuerzos de los desarrolladores de MetaTrader 5, ha surgido el lenguaje MQL5. Hay muchas novedades, pero voy a describir y abordar aquí la posibilidad de crear indicadores multicolores. En MQL4 se puede especificar el color de una línea, que es el mismo para todo la línea, y para crear un indicador multicolor hay que superponer los buffers parcialmente, que no es muy cómodo.

Los desarrolladores del lenguaje MQL5 han proporcionado una nueva característica que permite indicar el color para cada segmento de la curva del indicador (para las líneas) y los colores de cada objeto (para barras, velas, histogramas, arrays). Para entender este artículo, es preferible echar un vistazo a esta documentación de MQL5.

En este artículo, trataré de abordar los siguientes temas:

Vamos a tener en cuenta dos estilos de dibujo - DRAW_COLOR_LINE y DRAW_COLOR_CANDLES, se diferencian del resto de estilos de dibujo por el número de buffers.

¿Por qué los indicadores de color?

Mediante los indicadores de color, serás capaz de:

Simplemente dar rienda suelta a tu imaginación y haz que tu trading sea más cómodo.

Los conceptos básicos de MQL5

Comencemos con los principios del indicador.

En general, el indicador obtiene los datos de entrada (precios, datos de otros indicadores), realiza algunos cálculos y rellena varios buffers con los datos. El terminal de cliente representa los datos de los buffers, proporcionados por el indicador, en función del tipo de dibujo.

El estilo de dibujo se define por el desarrollador. Los buffers del indicador son arrays declarados a nivel global de tipo double. Se pueden combinar varios buffers en las representaciones gráficas, si se necesita más de un buffer para el estilo. Si no has creado nunca indicadores personalizados, deberías leer los artículos (se describen muy bien los conceptos básicos): "MQL5: Crea tu propio indicador" y "Indicadores personalizados para principiantes en MQL5".

Aquí está el código imprescindible del indicador de color, voy a describir sus componentes:

//+------------------------------------------------------------------+
//|                                         test_color_indicator.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_separate_window             // Se representa el indicador en una ventana separada
#property indicator_buffers 2                   //Número de buffers de indicadores
#property indicator_plots 1                     //Número de representaciones gráficas del indicador
#property indicator_type1 DRAW_COLOR_HISTOGRAM  //Estilo del dibujo - Histograma de color
#property indicator_width1 3                    //Grosor de la línea de representación gráfica (opcional)
#property indicator_color1 Red,Green,BlueViolet //Indicar 3 colores para la representación gráfica

//Declaración de los buffers
double buffer_line[]/*Buffer de datos*/, buffer_color_line[]/*Buffer del índice de color*/;

//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizado            |
//+------------------------------------------------------------------+
int OnInit()
  {
//Asignar el array de datos con el buffer del indicador
   SetIndexBuffer(0,buffer_line,INDICATOR_DATA);

//Asignar el array de índices de color con el buffer del indicador
   SetIndexBuffer(1,buffer_color_line,INDICATOR_COLOR_INDEX);

//Indicar el número de índices de color, usados en la representación gráfica
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

//Indicar los colores de cada índice
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Índice cero -> Azul
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //Primer índice  -> Naranja
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de iteración del indicador personalizado                 |
//+------------------------------------------------------------------+
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[])
  {
   //Para cada barra rellenamos el buffer de datos y el de índice de colores con los valores
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //Vamos a añadir una sencilla condición de dibujo -> Si el precio de apertura es superior al precio de cierre, entonces:
      if(open[i]>close[i])
        {   buffer_color_line[i]=0;   }       //Asignar el color con índice=cero (0)
      else
        {  buffer_color_line[i]=1;   }       //Asignar el color con índice=uno (1)
      
      //Indicar los datos para la representación, en nuestro caso es el precio de apertura
      buffer_line[i]=open[i];
     }

   return(rates_total-1); //Devolver el número de barras calculadas, 
                         //restar 1 para volver a calcular la última barra
  }
//+------------------------------------------------------------------+

Vamos a examinar los detalles de escritura de los indicadores de color:

#property indicator_buffers 2 //Número de buffers del indicador
#property indicator_plots 1   //Número de representaciones gráficas

En la primera línea indicamos el número de buffers del indicador, en nuestro caso tenemos dos buffers:

  1. El buffer para los datos del indicador, en nuestro caso, para los precios de apertura;
  2. El buffer para los índices de color.

En la segunda línea, indicamos el número de gráficos. Es muy importante distinguir entre los gráficos y los buffers del indicador. El gráfico es una línea (vela, barra, array, etc.) del indicador. Un buffer de indicador es un array con datos, necesarios para la representación gráfica, un array con índices de colores o un array para los cálculos internos del indicador (este tipo no se dibuja en la ventana del indicador).

El número de representaciones gráficas puede ser igual o inferior al número de buffers, y depende del estilo del dibujo y el número de buffers para el cálculo. La tabla con los estilos de dibujo y los números de buffers necesarios para cada estilo está disponible en el capítulo Estilos de dibujo de la documentación de MQL5.

Lo "más interesante" empieza aquí:

#property indicator_type1 DRAW_COLOR_HISTOGRAM  //Estilo de dibujo - histograma de color
#property indicator_width1 3                    //Grosor de la línea del dibujo (opcional)
#property indicator_color1 Red,Green,BlueViolet //Indicar 3 colores para una representación gráfica

En la primera línea, indicamos el estilo del dibujo, en nuestro caso se trata de un histograma desde la línea cero. Este estilo de dibujo requiere un buffer de datos y un buffer de índice de color. Todos los estilos de dibujo con la palabra "COLOR" requieren un buffer para los índices de color.

En la segunda línea, indicamos un grosor de línea de tres píxeles, el grosor por defecto de una línea es 1 píxel.

En la tercera línea, indicamos los colores para los índices de los gráficos, en este caso, indicamos tres colores "Red", "Green" y "BlueViolet". Los índices de color empiezan desde cero: 0-"Red", 1-"Green", 2-"BlueViolet". Los colores son necesarios para los ajustes de color de los gráficos. Se pueden indicar los colores de distintas maneras, "#property indicator_color1" es una de ellas. Este es un método "estático", se utiliza en la etapa de compilación del programa. A continuación se describe el segundo método.

double buffer_line[]/*Buffer de datos*/, buffer_color_line[]/*Buffer de índices de color*/;

Declaramos aquí dos arrays que se usarán como buffers, el primero servirá para el buffer de datos y el segundo para los índices de color, ambos declarados como arrays del tipo double.

Vamos a ver la función de inicialización del indicador:

SetIndexBuffer(0,buffer_line,INDICATOR_DATA);

Aquí asignamos un array al buffer del indicador, el tipo de buffer especificado "INDICATOR_DATA" significa que este buffer se usará para almacenar los valores del indicador (es decir, es el buffer de datos del indicador). Ten en cuenta que el primer parámetro es igual a cero (0) - es el índice del buffer.

SetIndexBuffer(1,buffer_color_line,INDICATOR_COLOR_INDEX);

Aquí asignamos un array al buffer del indicador y especificamos el tipo de buffer "INDICATOR_COLOR_INDEX", lo que significa que se trata del buffer que se usará para almacenar los índices de color de cada barra del indicador. Ten en cuenta que el primer parámetro es igual a uno (1) - es el índice del buffer.

El orden de los buffer es particular: primero, los buffers de datos del indicador, luego los buffers de índices de color.

Y finalmente, la segunda manera de indicar los colores de los gráficos (para especificar los índices de color):

//Indicar el número de índices de color, utilizados en los gráficos
PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

Indicamos aquí el número de índices de color. El primer parámetro de la función es igual a "0", es el índice gráfico. Ten en cuenta que en este caso debemos indicar el número de índices de color (en el primer método, lo calcula el compilador)

PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Índice cero -> Azul
PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //Primer índice -> Naranja

Indicamos aquí los colores de cada índice. El primer parámetro de la función es el índice de los gráficos, el tercer parámetro es el índice de color, empezando desde cero. La segunda manera de establecer los índices de color se caracteriza por lo siguiente: se puede especificar el número de colores y de sus índices de forma dinámica, por ejemplo, mediante la función. Si recurres a ambos métodos, recuerda que el método dinámico invalida el método estático (el primer método).

Considera A continuación la función OnCalculate, calculamos los valores del buffer para los gráficos del indicador. Escogemos la regla más sencilla para seleccionar el color del histograma, si el precio de apertura es superior al precio de cierre, asignamos el elemento actual del buffer con el índice de color (en el array "buffer_color_line") igual a cero (0). El índice de color igual a cero (0) mencionado antes, corresponde al color "Azul".

Si el precio de apertura es inferior al precio de cierre, asignamos el índice de color igual a 1, que corresponde al color Naranja. He aquí este sencillo ejemplo:

Indicador de prueba

Como se puede ver, es fácil, sólo necesitamos ser un poco creativos.

Los métodos para configurar el color

Vamos a ver los detalles de la configuración del color.

Según la documentación de MQL5, se puede especificar el color mediante distintos métodos:

Vamos a describirlos todos.

Literal

color color_var = C'10,20,255';
color color_var = C'0x0A,0x14,0xFF';

Los colores se definen según el modelo RGB (Red, Green, Blue - Rojo, Verde, Azul), se puede representar cualquier color como la suma de estos tres colores. Por consiguiente, le primer número corresponde a la componente de color Rojo. El segundo corresponde al Verde, el tercero corresponde a la componente azul. Los números (en el sistema decimal) pueden tomar valores de 0 a 255. En el sistema hexadecimal, toman valores de 00 a FF.

La primera y segunda línea son iguales: asignamos el color Azul a la variable color_var. La diferencia está en la la representación del número en un sistema numérico o en otro, el decimal en la primera línea y el hexadecimal en la segunda. Puedes elegir el sistema más cómodo para ti, no hay ninguna diferencia. Los números más bajos corresponden a los colores más oscuros, el color blanco es: "C'255,255,255'" o "C'0xFF,0xFF,0xFF'", el color negro es: "C'0,0,0'" o "C'0x00,0x00,0x00'".

Numérico

color color_var = 0xFFFFFF;  // blanco
color color_var = 0x0000FF;  // rojo
color color_var = 16777215   // blanco
color color_var = 0x008000   // verde
color color_var = 32768      // verde

Se representan los colores en los sistemas decimal y hexadecimal. Por ejemplo, el valor "0x0000FF" es igual a "C'0xFF,0x00,0x00'", como podemos ver, el primer par de los números y el último se intercambian.

Para obtener el número 16777215 en sistema numérico decimal, tenemos que convertir el número FFFFFF del sistema numérico hexadecimal al sistema decimal.

Nombres de los colores

color color_var = Red;    //rojo
color color_var = Blue;   //azul
color color_var = Orange; //naranja

Este es el método más sencillo, pero sólo se pueden indicar los colores del conjunto web-colors.

Vamos a resumir cómo podemos especificar los colores.

Los tres métodos son iguales, por ejemplo:

color color1 = C'255,0,0';
color color2 = C'0xFF,0x00,0x00';
color color3 = 0x0000FF;
color color4 = 255;
color color5 = Red;

Alert((color1==color2)
       && (color1==color2)
       && (color1==color4)
       && (color1==color5)); //salida true

Un caso práctico

Hemos aprendido los conceptos básicos, vamos a ver ahora cómo dar color a las velas del gráfico con distintos colores, en función de los valores de otro indicador, por ejemplo, en función de RSI. Para crear velas de color en el gráfico, tenemos que escribir un indicador que para representar las velas de color en el gráfico.

Aquí está el código del indicador, si los valores de RSI son inferiores al 50%, representa velas de color Azul, de lo contrario serán de color Naranja.

Para no confundir al lector, no se comprueba la validación de datos ni el procesamiento de errores. Pero hay que tener en cuenta estos detalles a la hora de escribir el código de funcionamiento del indicador.

//+------------------------------------------------------------------+
//|                                                   cand_color.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_chart_window                //Indicador en ventana separada

                                          //Indicar el número de buffers del indicador
//4 buffers para velas + 1 buffer de color + 1 buffer para almacenar los datos RSI
#property indicator_buffers 6

//Indicar los nombres en la ventana de datos
#property indicator_label1 "Open;High;Low;Close"

#property indicator_plots 1                     //Número de representaciones gráficas
#property indicator_type1 DRAW_COLOR_CANDLES    //Estilo de dibujo - velas de color
#property indicator_width1 3                    //Grosor de la representación gráfica (opcional)

                                          //Declaración de buffers
double buffer_open[],buffer_high[],buffer_low[],buffer_close[]; //Buffers para datos
double buffer_color_line[];    //Buffer para índices de color
double buffer_tmp[1];           //Buffer temporal para copiar los datos de RSI
double buffer_RSI[];            //Buffer del indicador para RSI
int handle_rsi=0;               //Identificador del indicador RSI
//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizado            |
//+------------------------------------------------------------------+
int OnInit()
  {
/**
        *       La asignación del orden de los buffers es ¡MUY IMPORTANTE!
        *  Primero los buffers de datos
        *       Después los buffers del color
        *       Y finalmente, los buffers para los cálculos internos.
        */
//Asignar los arrays con los buffers del indicador
   SetIndexBuffer(0,buffer_open,INDICATOR_DATA);
   SetIndexBuffer(1,buffer_high,INDICATOR_DATA);
   SetIndexBuffer(2,buffer_low,INDICATOR_DATA);
   SetIndexBuffer(3,buffer_close,INDICATOR_DATA);

//Asignar el array de los índices de color con el buffer de índices de color del indicador
   SetIndexBuffer(4,buffer_color_line,INDICATOR_COLOR_INDEX);

//Asignar el array con el buffer de datos del indicador RSI
   SetIndexBuffer(5,buffer_RSI,INDICATOR_CALCULATIONS);

//Determinar el número de índices de color, usado para la representación gráfica
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

//Definir el color para cada índice
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Índice cero -> Azul
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //Primer índice  -> Naranja
   
//Obtener el identificador del indicador RSI, necesario para obtener sus valores
   handle_rsi=iCustom(_Symbol,_Period,"Examples\\RSI");
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de iteración del indicador personalizado                 |
//+------------------------------------------------------------------+
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[])
  {
//Rellenamos en los bucle los buffers de datos y los buffers de índices de color para cada barra
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //copiar los datos del indicador RSI en el buffer temporal - buffer_tmp
      CopyBuffer(handle_rsi,0,BarsCalculated(handle_rsi)-i-1,1,buffer_tmp);
      //copiar los valores desde el buffer temporal al buffer del indicador
      buffer_RSI[i]=buffer_tmp[0];

      //Configurar los datos para el trazado
      buffer_open[i]=open[i];  //Precio de apertura - Open
      buffer_high[i]=high[i];  //Precio alto - High
      buffer_low[i]=low[i];    //Precio bajo - Low
      buffer_close[i]=close[i];//Precio de cierre - Close

                               //Añadir una condición sencilla -> Si RSI inferior al 50%:
      if(buffer_RSI[i]<50)
        {   buffer_color_line[i]=0;   } //Asignar la barra con índice de color igual a 0
      else
        {  buffer_color_line[i]=1;   }  //Asignar la barra con índice de color igual a 1
     }
   return(rates_total-1); //Devolver el número de barras calculadas, 
                         //Restar 1 para volver a calcular la última barra
  }
//+------------------------------------------------------------------+

Así se verá:

El indicador en color, en función de los valores RSI

Se ve bien, pero vamos a ir más allá.

Vamos a colorear las velas según los valores de RSI mediante muchos colores, el llamado relleno degradado.

Se pueden especificar los colores manualmente, pero no es ni cómodo ni sencillo especificar 30-40 colores. Haremos lo siguiente: escribiremos dos funciones, la primera para los índices de color, y la segunda para obtener el color en función de los argumentos de la función. La idea está escrita en los comentarios.

//+------------------------------------------------------------------+
//|                                               cand_color_RSI.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_chart_window                //Indicador en una ventana separada

//Indicar el número de buffers del indicador
//4 buffers para velas + 1 buffer para índices de color + 1 buffer para almacenar los datos de RSI
#property indicator_buffers 6

//Indicar los datos que se muestran en la ventana de datos
#property indicator_label1 "Open;High;Low;Close"

#property indicator_plots 1                     //Número de representaciones gráficas
#property indicator_type1 DRAW_COLOR_CANDLES    //Estilo de dibujo - velas de color
#property indicator_width1 3                    //Grosor de la línea (opcional)

                                          //Declaración de buffers
double buffer_open[],buffer_high[],buffer_low[],buffer_close[];//Buffers para datos
double buffer_color_line[];     //Buffer para índices de color
double buffer_tmp[1];          //Buffer temporal para los valores de RSI
double buffer_RSI[];            //Buffer del indicador para RSI
int handle_rsi=0;               //Identificador del indicador RSI
//+------------------------------------------------------------------+
//|       Ajustar los colores de la representación gráfica           |
//+------------------------------------------------------------------+
/*
*       La función ajusta los colores de la representación gráfica 
*       50 colores desde el Verde hasta el Azul
*       La función recibe el índice de la representación gráfica

void setPlotColor(int plot)
  {
   PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,50); //Indicar el número de colores

                                               //Indicamos los colores en los bucles
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i,StringToColor("\"0,175,"+IntegerToString(i*7)+"\""));
     }
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i+25,StringToColor("\"0,"+IntegerToString(175-i*7)+",175\""));
     }
  }
//+------------------------------------------------------------------+
//|  Obtener el índice de color                                      |
//+------------------------------------------------------------------+
/*
*       La función devuelve el índice del color
*       El primer parámetro es el valor actual del indicador
*       El segundo parámetro es el valor mínimo del indicador
*       El tercer parámetro es el valor máximo del indicador
*/
int getPlotColor(double current,double min,double max)
  {
   return((int)NormalizeDouble((50/(max-min))*current,0));
  }
//+------------------------------------------------------------------+
//| Función de inicialización del indicador personalizado            |
//+------------------------------------------------------------------+
int OnInit()
  {
/**
        *       El orden de los buffers del indicador es ¡MUY IMPORTANTE!
        *  Primero los buffers de datos
        *       Después los buffers del color
        *       Y finalmente, los buffers para los cálculos internos.
        */
//Asignar los arrays con los buffers del indicador
   SetIndexBuffer(0,buffer_open,INDICATOR_DATA);
   SetIndexBuffer(1,buffer_high,INDICATOR_DATA);
   SetIndexBuffer(2,buffer_low,INDICATOR_DATA);
   SetIndexBuffer(3,buffer_close,INDICATOR_DATA);

//Asignar el array con el buffer de los índices de color
   SetIndexBuffer(4,buffer_color_line,INDICATOR_COLOR_INDEX);

//Asignar el array con el buffer del indicador RSI
   SetIndexBuffer(5,buffer_RSI,INDICATOR_CALCULATIONS);

//Indicar los índices de color
   setPlotColor(0);

//Obtener el identificador del indicador RSI, necesario para obtener sus valores
   handle_rsi=iCustom(_Symbol,_Period,"Examples\\RSI",6);
   return(0);
  }
//+------------------------------------------------------------------+
//| Función de iteración del indicador personalizado                 |
//+------------------------------------------------------------------+
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[])
  {
//Mediante el bucle rellenamos los buffers de datos y de índices de color para cada barra
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //copiar los datos del indicador RSI en el buffer temporal buffer_tmp
      CopyBuffer(handle_rsi,0,BarsCalculated(handle_rsi)-i-1,1,buffer_tmp);
      //Y luego copiar los datos desde el buffer temporal
      buffer_RSI[i]=buffer_tmp[0];

      //Configurar los datos para el trazado
      buffer_open[i]=open[i];  //Precio de apertura - Open
      buffer_high[i]=high[i];  //Precio alto - High
      buffer_low[i]=low[i];    //Precio bajo - Low
      buffer_close[i]=close[i];//Precio de cierre - Close

      //Colorear las velas en función de los valores del indicador RSI
      //RSI = 0     - vela Verde
      //RSI = 100   - vela Azul
      //0<RSI<100   - color de vela entre Verde y Azul 
      buffer_color_line[i]=getPlotColor(buffer_RSI[i],0,100);

     }
   return(rates_total-1); //Devolver el número de barras calculadas 
                         //Restar 1 para volver a calcular la última barra
  }
//+------------------------------------------------------------------+

Así se verá:

RSI_gradient

Prueba con otros colores, mediante el ejemplo. Intenta cambiar el indicador RSI por otro.

La práctica es siempre importante.

Estilos de dibujo: Clásico y multicolor

Para poder colorear un indicador que ya existe, tienes que hacer lo siguiente: cambiar el estilo de dibujo a multicolor, añadir buffers, asignarlos con los buffers del indicador y especificar los detalles de los colores.

A continuación hay una tabla con los estilos clásicos de dibujo y sus correspondientes estilos de dibujo multicolor (coloreados):

Antes
Después
DRAW_LINE DRAW_COLOR_LINE
DRAW_SECTION DRAW_COLOR_SECTION
DRAW_HISTOGRAM DRAW_COLOR_HISTOGRAM
DRAW_HISTOGRAM2 DRAW_COLOR_HISTOGRAM2
DRAW_ARROW DRAW_COLOR_ARROW
DRAW_ZIGZAG DRAW_COLOR_ZIGZAG (ejemplo)
DRAW_CANDLES DRAW_COLOR_CANDLES

Este es el código del indicador RSI modificado, coloreado en función de sus propios valores.

Todas las modificaciones están comentadas.

//+------------------------------------------------------------------+
//|                                                          RSI.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Relative Strength Index"
//--- indicator settings
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 30
#property indicator_level2 70
/////////////////////////////////////////////////////////////////////
#property indicator_buffers 4 //Se ha incrementado el numero de buffers de 1
#property indicator_width1 5  //Se establece el grosor de la línea a 4 píxeles
/////////////////////////////////////////////////////////////////////
#property indicator_plots   1
/////////////////////////////////////////////////////////////////////
//Se ha cambiado el estilo de dibujo de DRAW_LINE a DRAW_COLOR_LINE
#property indicator_type1   DRAW_COLOR_LINE
/////////////////////////////////////////////////////////////////////
#property indicator_color1  DodgerBlue
//--- input parameters
input int InpPeriodRSI=14; // Period
//--- indicator buffers
double    ExtRSIBuffer[];
double    ExtPosBuffer[];
double    ExtNegBuffer[];
//--- global variable
int       ExtPeriodRSI;

//////////////////////////////////////////////////////////////////////
double buffer_color[]; //Declarar un array para los índices de color

//Añadir dos funciones
//+------------------------------------------------------------------+
//|    Definir el color de la representación gráfica                 |
//+------------------------------------------------------------------+
/*
*       La función indica el color de la representación gráfica 
*       Hay disponibles 50 colores desde el Verde al Azul
*       La función recibe el índice de la representación gráfica
*/
void setPlotColor(int plot)
  {
   PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,50); //Definir el número de colores

                                                    //Indicar los colores en el bucle
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i,StringToColor("\"0,175,"+IntegerToString(i*7)+"\""));
     }
   for(int i=0;i<=24;i++)
     {
      PlotIndexSetInteger(plot,PLOT_LINE_COLOR,i+25,StringToColor("\"0,"+IntegerToString(175-i*7)+",175\""));
     }
  }
//+------------------------------------------------------------------+
//|  Obtener el índice del color                                     |
//+------------------------------------------------------------------+
/*
*       La función devuelve el índice del color
*       El primer parámetro es el valor actual del indicador
*       El segundo parámetro es el valor mínimo del indicador
*       El tercer parámetro es el valor máximo del indicador
*/
int getPlotColor(double current,double min,double max)
  {
   return((int)NormalizeDouble((50/(max-min))*current,0));
  }
//////////////////////////////////////////////////////////////////////


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input
   if(InpPeriodRSI<1)
     {
      ExtPeriodRSI=12;
      Print("Incorrect value for input variable InpPeriodRSI =",InpPeriodRSI,
            "Indicator will use value =",ExtPeriodRSI,"for calculations.");
     }
   else ExtPeriodRSI=InpPeriodRSI;
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtRSIBuffer,INDICATOR_DATA);
   
/////////////////////////////////////////////////////////////////////
//Asignar el array con el buffer de los índices de color
        SetIndexBuffer(1,buffer_color,INDICATOR_COLOR_INDEX);
// ¡Ha cambiado el orden de los buffers!
        SetIndexBuffer(2,ExtPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,ExtNegBuffer,INDICATOR_CALCULATIONS);
//Definir los colores
   setPlotColor(0);
/////////////////////////////////////////////////////////////////////

//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);
//--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtPeriodRSI)+")");
//--- initialization done
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   int    i;
   double diff;
//--- check for rates count
   if(rates_total<=ExtPeriodRSI)
      return(0);
//--- preliminary calculations
   int pos=prev_calculated-1;
   if(pos<=ExtPeriodRSI)
     {
      //--- first RSIPeriod values of the indicator are not calculated
      ExtRSIBuffer[0]=0.0;
      ExtPosBuffer[0]=0.0;
      ExtNegBuffer[0]=0.0;
      double SumP=0.0;
      double SumN=0.0;
      for(i=1;i<=ExtPeriodRSI;i++)
        {
         ExtRSIBuffer[i]=0.0;
         ExtPosBuffer[i]=0.0;
         ExtNegBuffer[i]=0.0;
         diff=price[i]-price[i-1];
         SumP+=(diff>0?diff:0);
         SumN+=(diff<0?-diff:0);
        }
      //--- calculate first visible value
      ExtPosBuffer[ExtPeriodRSI]=SumP/ExtPeriodRSI;
      ExtNegBuffer[ExtPeriodRSI]=SumN/ExtPeriodRSI;
      ExtRSIBuffer[ExtPeriodRSI]=100.0-(100.0/(1.0+ExtPosBuffer[ExtPeriodRSI]/ExtNegBuffer[ExtPeriodRSI]));
      //--- prepare the position value for main calculation
      pos=ExtPeriodRSI+1;
     }
//--- the main loop of calculations
   for(i=pos;i<rates_total;i++)
     {
      diff=price[i]-price[i-1];
      ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(ExtPeriodRSI-1)+(diff>0.0?diff:0.0))/ExtPeriodRSI;
      ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(ExtPeriodRSI-1)+(diff<0.0?-diff:0.0))/ExtPeriodRSI;
      ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
/////////////////////////////////////////////////////////////////////
//Colorear
                buffer_color[i] = getPlotColor(ExtRSIBuffer[i],0,100);
/////////////////////////////////////////////////////////////////////
     }
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+

Esto es lo que sucede, puedes comparar el color de las velas y el indicador RSI.

RSI color

Cómo obtener el color del indicador a partir de Expert Advisor/Indicador/Script

Es a menudo necesario obtener el color de la línea para el trading automatizado en un Expert Advisor o para otros fines.

La implementación es sencilla, vamos a ver el script.

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"
#property link      "http://"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
        int handle = 0; //identificador del indicador
        double tmp[1];  //array temporal para el buffer del índice de color
        //Obtener el identificador de nuestro RSI modificado
        handle = iCustom(_Symbol,_Period,"Examples\\RSI",6);
        
        //Recordemos que los valores se almacenan en el buffer  1 de nuestro RSI modificado
        //Los índices de colore se almacenan en el buffer 0
        //Copiar los datos del buffer "1" del indicador RSI
        CopyBuffer(handle,1,0,1,tmp);
        
        //Mostrar un aviso con el último índice de color devuelto por RSI
        Alert(tmp[0]); //Por ejemplo, si se devuelve 0, se trata de RSI
        //de color verde y su nivel actual está cerca de 0.
  }
//+-----------------------------------------------------------------+
Ten en cuenta que sólo podemos obtener el valor del índice de color, ¡no el color!

Debes conocer la relación entre los índices de colores y los valores de los colores. Además, debes conocer el buffer de los índices de color.

Para averiguarlo, necesitas comprender el criterio de ajustes del índice de color o hacerlo de modo empírica mediante este script u otros métodos.

Conclusión

Hemos visto los siguientes estilos de dibujo de MQL5: DRAW_COLOR_LINE, DRAW_COLOR_CANDLES. Hemos coloreado las velas y aprendido cómo colorear el indicador RSI (DRAW_LINE -> DRAW_COLOR_LINE). Además, hemos aprendido cómo obtener el valor de los índices del buffer de color.

El lenguaje MQL5 dispone de muchos estilos de dibujo, el único límite es tu imaginación. El uso de líneas de colores permite mejorar la percepción del mercado.

Utiliza las nuevas posibilidades para un trading más confortable.