Creazione di Indicatori Multicolor in MQL5

Дмитрий Александрович | 9 dicembre, 2021

Introduzione

Grazie agli sforzi degli sviluppatori MetaTrader 5, è comparso il linguaggio MQL5. Ci sono molte innovazioni, ma qui descriverò e prenderò in considerazione la possibilità di creare indicatori multicolor. In MQL4, il colore può essere specificato per una linea, è lo stesso per l'intera linea e gli indicatori multicolor vengono creati utilizzando la sovrapposizione parziale dei buffer dell'indicatore, il che non è conveniente.

Gli sviluppatori del linguaggio MQL5 hanno fornito una nuova possibilità: specificare un colore per ogni sezione della linea dell'indicatore (per linee) e colori di oggetti separati (per barre, candele, istogrammi, frecce). Per capire questo articolo, è meglio dare un'occhiata a MQL5 Reference.

In questo articolo, cercherò di considerare i seguenti argomenti:

Consideriamo due stili di disegno a colori: DRAW_COLOR_LINE e DRAW_COLOR_CANDLES, gli stili di disegno rimanenti differiscono solo per il numero di buffer.

Perché gli indicatori di colore?

Utilizzando gli indicatori di colore, sarai in grado di:

accendere la tua immaginazione e rendere la tua attività di trading più conveniente.

Le basi di MQL5

Cominciamo con i principi dell'indicatore.

Generalmente, l'indicatore riceve dati di input (prezzi, i dati dell'altro indicatore), esegue alcuni calcoli e compila i diversi buffer con i dati. Il client terminal traccia le informazioni dai buffer fornite dall'indicatore in base al tipo di disegno.

Lo stile di disegno viene definito dallo sviluppatore. I buffer indicatori sono array di doppio tipo, dichiarati a livello globale. Diversi buffer possono essere combinati nei grafici, se è necessario più di un buffer per uno stile. Se non hai mai creato indicatori personalizzati, puoi leggere gli articoli (le basi sono ben descritte lì): "MQL5: Crea il Tuo indicatore" e "Indicatori personalizzati in MQL5 per Principianti".

Ecco il codice minimo dell'indicatore di colore del quale descriverò i componenti:

//+------------------------------------------------------------------+
//|                                         test_color_indicator.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_separate_window             //The indicator is plotted in a separate window
#property indicator_buffers 2                   //Number of indicator buffers
#property indicator_plots 1                     //Number of indicator plots
#property indicator_type1 DRAW_COLOR_HISTOGRAM  //Drawing style - Color Histogram
#property indicator_width1 3                    //Line width of a graphic plot (optional)
#property indicator_color1 Red,Green,BlueViolet //Specify 3 colors for a graphic plot

//Declaration of buffers
double buffer_line[]/*Data Buffer*/, buffer_color_line[]/*Color index buffer*/;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//Assign the data array with indicator's buffer
   SetIndexBuffer(0,buffer_line,INDICATOR_DATA);

//Assign the color indexes array with indicator's buffer
   SetIndexBuffer(1,buffer_color_line,INDICATOR_COLOR_INDEX);

//Specify the number of color indexes, used in the graphic plot
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

//Specify colors for each index
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Zeroth index -> Blue
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //First index  -> Orange
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   //For each bar we fill the data buffer and index color buffer with values
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //Lets add a simple drawing condition -> If opening price is greater than closing price, then:
      if(open[i]>close[i])
        {   buffer_color_line[i]=0;   }       //Assign color with index=zero (0)
      else
        {  buffer_color_line[i]=1;   }       //Assign color with index=one (1)
      
      //Specify the data for plotting, in our case it's the opening price
      buffer_line[i]=open[i];
     }

   return(rates_total-1); //Return the number of calculated bars, 
                         //subtract 1 for the last bar recalculation
  }
//+------------------------------------------------------------------+

Esaminiamo i dettagli della scrittura degli indicatori di colore:

#property indicator_buffers 2 //Number of indicator's buffers
#property indicator_plots 1   //Number of graphic plots

Nella prima riga, specifichiamo il numero di buffer indicatori. Nel nostro caso abbiamo due buffer:

  1. il buffer per i dati dell'indicatore, nel nostro caso, per i prezzi di apertura;
  2. il buffer per gli indici di colore.

Nella seconda riga, specifichiamo il numero di grafici. È importante distinguere la grafica ed i buffer dell'indicatore. La grafica è la linea (candela, barra, freccia, ecc.) dell'indicatore. Un buffer indicatore è un array con i dati, necessari per tracciare un array con indici di colore o un array per i calcoli interni dell'indicatore (questo tipo non viene disegnato nella finestra dell'indicatore).

Il numero di grafici può essere uguale o inferiore al numero di buffer; dipende dallo stile di disegno e dal numero di buffer per il calcolo. La tabella con gli stili di disegno e il numero di buffer necessari per ogni stile è disponibile nel capitolo Stili di disegno di MQL5 Reference.

Il "più interessante" inizia qui:

#property indicator_type1 DRAW_COLOR_HISTOGRAM  //Drawing style-color histogram
#property indicator_width1 3                    //Drawing line width (optional)
#property indicator_color1 Red,Green,BlueViolet //Specify 3 colors for a graphic plot

Nella prima riga, specifichiamo lo stile di disegno; nel nostro caso, lo stile di disegno è un istogramma da una linea zero. Questo stile di disegno richiede un buffer di dati ed un buffer di indice di colore. Tutti gli stili di disegno che contengono la parola "COLORE" richiedono un buffer per gli indici dei colori.

Nella seconda riga, specifichiamo la larghezza di una linea pari a tre pixel; di default, la larghezza di una linea è settata su un pixel.

Nella terza riga, specifichiamo i colori per gli indici della grafica, in questo caso, abbiamo specificato tre colori "Red", "Green" e "BlueViolet". Gli indici di colore iniziano da zero: 0-"Rosso", 1-"Verde", 2-"BluViola". I colori sono necessari per configurare i colori della grafica. I colori possono essere specificati in diversi modi, "#property indicator_color1" è uno di questi. Questo è un metodo "statico" che viene utilizzato nella fase di compilazione del programma. Il secondo metodo viene discusso di seguito.

double buffer_line[]/*Data buffer*/, buffer_color_line[]/*Color indexes buffer*/;

Qui dichiariamo due array che verranno utilizzati come buffer. Il primo verrà utilizzato come buffer di dati, il secondo verrà utilizzato per gli indici di colore, entrambi dichiarati come array di doppio tipo.

Consideriamo la funzione di inizializzazione dell'indicatore:

SetIndexBuffer(0,buffer_line,INDICATOR_DATA);

Qui, assegniamo il buffer dell'indicatore con un array, il tipo di buffer "INDICATOR_DATA" specificato significa che questo buffer verrà utilizzato per memorizzare i valori dell'indicatore (cioè è il buffer di dati dell'indicatore). Nota che il primo parametro è uguale a zero (0) - è l'indice del buffer.

SetIndexBuffer(1,buffer_color_line,INDICATOR_COLOR_INDEX);

Qui assegniamo il buffer dell'indicatore con un array e specifichiamo "INDICATOR_COLOR_INDEX" come tipo di buffer - significa che questo buffer verrà utilizzato per memorizzare gli indici di colore per ogni barra dell'indicatore. Nota che il primo parametro è uguale a (1) che è l'indice del buffer.

L'ordine dei buffer deve essere speciale: prima di tutto i buffer dei dati dell'indicatore, poi i buffer degli indici di colore.

E infine, il secondo modo per specificare i colori della grafica (per specificare gli indici di colore):

//Specify the number of color indexes, used in the graphics
PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

Qui specifichiamo il numero di indici di colore. Il primo parametro della funzione è uguale a "0", è l'indice grafico. Nota che in questo caso, dobbiamo specificare il numero di indici di colore (nel primo metodo, il compilatore lo calcola).

PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Zeroth index -> Blue
PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //First index  -> Orange

Qui specifichiamo i colori per ogni indice. Il primo parametro della funzione è l'indice della grafica, il terzo parametro è l'indice del colore, partendo da zero. Il secondo modo di impostare gli indici di colore differisce nel modo seguente: il numero di colori e i loro indici possono essere specificati dinamicamente, ad esempio, utilizzando la funzione. Se utilizzi entrambi i metodi, ricorda che il metodo dinamico sovrascrive quello statico (primo metodo).

Successivamente, consideriamo la funzione OnCalculate, calcoliamo i valori del buffer per i grafici dell'indicatore. Scegliamo le regole più semplici per la selezione del colore per l'istogramma, se il prezzo di apertura è maggiore del prezzo di chiusura, assegniamo all'elemento buffer corrente l'indice di colore (nell'array "buffer_color_line") uguale a zero (0). L'indice di colore, pari a zero (0), corrisponde al colore "Blu", sopra specificato.

Se il prezzo di apertura è inferiore al prezzo di chiusura, assegniamo l'indice di colore, pari a 1, che corrisponde al colore Arancione. Ecco un semplice esempio:

Indicatore di Prova

Si vede, è facile, ci vuole solo un po' di fantasia.

I Metodi di Configurazione del Colore

Ora, consideriamo i dettagli della configurazione del colore.

Secondo MQL5 Reference, il colore può essere specificato utilizzando diversi metodi:

Consideriamoli tutti.

Letteralmente

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

I colori sono definiti secondo l'RGB (Rosso, Verde, Blu), qualsiasi colore può essere presentato come la somma di questi tre colori. Di conseguenza, il primo numero corrisponde al componente di colore Rosso. Il secondo corrisponde al Verde, il terzo alla componente Blu. I numeri (in forma decimale) possono essere compresi tra 0 e 255. In base esadecimale i valori possono essere compresi tra 00 e FF.

La prima e la seconda riga sono uguali: assegniamo il colore Blu alla variabile color_var. La differenza è la rappresentazione di un numero in sistemi numerici specificati, il decimale nella prima riga e l'esadecimale nella seconda riga. Non c'è nessuna differenza, puoi scegliere il modo che più ti conviene. Il numero più piccolo corrisponde ai colori più scuri, il colore bianco è: "C'255,255,255'" o "C'0xFF,0xFF,0xFF'", il colore nero è: "C'0,0,0'" o "C'0x00,0x00,0x00'".

Numericamente

color color_var = 0xFFFFFF;  // white
color color_var = 0x0000FF;  // red
color color_var = 16777215   // white
color color_var = 0x008000   // green
color color_var = 32768      // green

I colori sono rappresentati in sistemi numerici esadecimali e decimali. Ad esempio, il valore "0x0000FF" è uguale a "C'0xFF,0x00,0x00'", come si vede, la prima e l'ultima coppia dei numeri vengono scambiate.

Per ottenere il valore 16777215 nel sistema numerico decimale, dobbiamo convertire il numero FFFFFF dal sistema numerico esadecimale a quello decimale.

Nomi dei colori

color color_var = Red;    //red
color color_var = Blue;   //blue
color color_var = Orange; //orange

Questo è il modo più semplice, ma puoi specificare solo i colori dal set di web color.

Riassumiamo in che modo possiamo specificare i colori.

Tutti e tre i metodi sono uguali, ad esempio:

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)); //prints true

Un po’ di Pratica

Abbiamo imparato le basi, ora consideriamo come colorare le candele del grafico con colori diversi, a seconda degli altri valori dell'indicatore, ad esempio, a seconda dei valori dell’RSI. Per creare le candele colorate sul grafico, dobbiamo scrivere un indicatore che riporterà le candele colorate imposte sul grafico.

Ecco il codice dell'indicatore, se i valori dell’RSI sono inferiori al 50%, traccia le candele blu, altrimenti le candele sono tracciate con il colore arancione.

Per evitare la confusione del lettore, non c'è il controllo della correttezza dei dati e l'elaborazione degli errori. Tuttavia, questi dettagli dovrebbero essere presi in considerazione quando si scrive il working code dell'indicatore.

//+------------------------------------------------------------------+
//|                                                   cand_color.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_chart_window                //Indicator in separate window

                                          //Specify the number of buffers of the indicator
//4 buffer for candles + 1 color buffer + 1 buffer to serve the RSI data
#property indicator_buffers 6

//Specify the names in the Data Window
#property indicator_label1 "Open;High;Low;Close"

#property indicator_plots 1                     //Number of graphic plots
#property indicator_type1 DRAW_COLOR_CANDLES    //Drawing style - color candles
#property indicator_width1 3                    //Width of the graphic plot (optional)

                                          //Declaration of buffers
double buffer_open[],buffer_high[],buffer_low[],buffer_close[]; //Buffers for data
double buffer_color_line[];    //Buffer for color indexes
double buffer_tmp[1];           //Temporary buffer for RSI data copying
double buffer_RSI[];            //Indicator buffer for RSI
int handle_rsi=0;               //Handle for the RSI indicator
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
/**
        *       The order of the buffers assign is VERY IMPORTANT!
        *  The data buffers are first
        *       The color buffers are next
        *       And finally, the buffers for the internal calculations.
        */
//Assign the arrays with the indicator's buffers
   SetIndexBuffer(0,buffer_open,INDICATOR_DATA);
   SetIndexBuffer(1,buffer_high,INDICATOR_DATA);
   SetIndexBuffer(2,buffer_low,INDICATOR_DATA);
   SetIndexBuffer(3,buffer_close,INDICATOR_DATA);

//Assign the array with color indexes with the indicator's color indexes buffer
   SetIndexBuffer(4,buffer_color_line,INDICATOR_COLOR_INDEX);

//Assign the array with the RSI indicator data buffer
   SetIndexBuffer(5,buffer_RSI,INDICATOR_CALCULATIONS);

//Define the number of color indexes, used for a graphic plot
   PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,2);

//Set color for each index
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,Blue);   //Zeroth index -> Blue
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,Orange); //First index  -> Orande
   
//Get handle of RSI indicator, it's necessary to get the RSI indicator values
   handle_rsi=iCustom(_Symbol,_Period,"Examples\\RSI");
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//In the loop we fill the data buffers and color indexes buffers for each bar
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //Copying the RSI indicator's data to the temporary buffer - buffer_tmp
      CopyBuffer(handle_rsi,0,BarsCalculated(handle_rsi)-i-1,1,buffer_tmp);
      //Copying the values from the temporary buffer to the indicator's buffer
      buffer_RSI[i]=buffer_tmp[0];

      //Set data for plotting
      buffer_open[i]=open[i];  //Open price
      buffer_high[i]=high[i];  //High price
      buffer_low[i]=low[i];    //Low price
      buffer_close[i]=close[i];//Close price

                               //Add a simple condition -> If RSI less 50%:
      if(buffer_RSI[i]<50)
        {   buffer_color_line[i]=0;   } //Assign the bar with color index, equal to 0
      else
        {  buffer_color_line[i]=1;   }  //Assign the bar with color index, equal to 1
     }
   return(rates_total-1); //Return the number of calculated bars, 
                         //Subtract 1 for the last bar recalculation
  }
//+------------------------------------------------------------------+

Ecco come appare:

L'indicatore di colore dipende dai valori dell’RSI

Sembra buono, ma andremo avanti.

Coloriamo le candele in base ai valori dell’RSI usando molti colori, il cosiddetto riempimento a gradiente.

I colori possono essere specificati manualmente, ma non coviene e non è semplice specificare 30-40 colori. Faremo quanto segue: scriveremo due funzioni, la prima per gli indici di colore, la seconda per ottenere il colore in base agli argomenti della funzione. L'idea è scritta nei commenti.

//+------------------------------------------------------------------+
//|                                               cand_color_RSI.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"                      //Author
#property indicator_chart_window                //Indicator in a separate window

//Specify the number of indicator's buffers
//4 buffers for candles + 1 buffer for color indexes + 1 buffer to store the data of RSI
#property indicator_buffers 6

//Specify the names, shown in the Data Window
#property indicator_label1 "Open;High;Low;Close"

#property indicator_plots 1                     //Number of graphic plots
#property indicator_type1 DRAW_COLOR_CANDLES    //Drawing style - colored candles
#property indicator_width1 3                    //Width of a line (optional)

                                          //Declaration of buffers
double buffer_open[],buffer_high[],buffer_low[],buffer_close[];//Buffers for data
double buffer_color_line[];     //Buffer for color indexes
double buffer_tmp[1];          //Temporary buffer for RSI values
double buffer_RSI[];            //Indicator buffer for RSI
int handle_rsi=0;               //Handle of the RSI indicator
//+------------------------------------------------------------------+
//|    Set colors for a graphic plot                          |
//+------------------------------------------------------------------+
/*
*       The function sets colors for a graphic plot 
*       50 colors from Green to Blue.
*       The index of a graphic plot is passed to the function.

void setPlotColor(int plot)
  {
   PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,50); //Specify the number of colors

                                               //In the loops we specify the colors
   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\""));
     }
  }
//+------------------------------------------------------------------+
//|  Get index of the color                                          |
//+------------------------------------------------------------------+
/*
*       The function returns the index of the color
*       The first parameter is the current value of the indicator
*       The second parameter is the minimal value of the indicator
*       The third parameter is the maximal value of the indicator
*/
int getPlotColor(double current,double min,double max)
  {
   return((int)NormalizeDouble((50/(max-min))*current,0));
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
/**
        *       The order of the indicator's buffers is VERY IMPORTANT!
        *  The data buffers are first
        *       The color buffers are next
        *       And finally, the buffers for the internal calculations.
        */
//Assign the arrays with the indicator buffers
   SetIndexBuffer(0,buffer_open,INDICATOR_DATA);
   SetIndexBuffer(1,buffer_high,INDICATOR_DATA);
   SetIndexBuffer(2,buffer_low,INDICATOR_DATA);
   SetIndexBuffer(3,buffer_close,INDICATOR_DATA);

//Assign the array with the color indexes buffer
   SetIndexBuffer(4,buffer_color_line,INDICATOR_COLOR_INDEX);

//Assign the array with RSI indicator buffer
   SetIndexBuffer(5,buffer_RSI,INDICATOR_CALCULATIONS);

//Specify color indexes
   setPlotColor(0);

//Get handle of the RSI indicator, it's necessary get its values
   handle_rsi=iCustom(_Symbol,_Period,"Examples\\RSI",6);
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//For each bar we fill the data buffers and buffer with color indexes using the loop
   for(int i=prev_calculated;i<=rates_total-1;i++)
     {
      //Copying the RSI indicator data to the temporary buffer buffer_tmp
      CopyBuffer(handle_rsi,0,BarsCalculated(handle_rsi)-i-1,1,buffer_tmp);
      //Then copying the data from the temporary buffer
      buffer_RSI[i]=buffer_tmp[0];

      //Specify the data for plotting
      buffer_open[i]=open[i];  //Open price
      buffer_high[i]=high[i];  //High price
      buffer_low[i]=low[i];    //Low price
      buffer_close[i]=close[i];//Close price

      //Paint the candles depending on RSI indicator values
      //RSI = 0     - candle is Green
      //RSI = 100   - candle is Blue
      //0<RSI<100   - candle color is between Green and Blue 
      buffer_color_line[i]=getPlotColor(buffer_RSI[i],0,100);

     }
   return(rates_total-1); //Return the number of calculated bars, 
                         //Subtract 1 for the last bar recalculation
  }
//+------------------------------------------------------------------+

Ecco come appare:

RSI_gradient

Usandolo come esempio, configura altri colori. Prova a sostituire l’RSI con un altro indicatore.

La pratica è sempre importante.

Stili di Disegno: Convenzionale e Multicolor

Puoi colorare un indicatore esistente, devi solo fare ciò che segue: cambiare lo stile di disegno in multicolore, aggiungere i buffer, assegnarli ai buffer dell'indicatore e specificare i dettagli della colorazione.

Ecco una tabella degli stili di disegno convenzionali e dei corrispondenti stili di disegno multicolor (colorato):

Prima
Dopo
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 (esempio)
DRAW_CANDLES DRAW_COLOR_CANDLES

Ecco il codice dell'RSI modificato, colorato in base ai propri valori.

Tutte le modifiche vengono commentate.

//+------------------------------------------------------------------+
//|                                                          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 //The number of buffers has increased by 1
#property indicator_width1 5  //The line width has set to 4 pixels
/////////////////////////////////////////////////////////////////////
#property indicator_plots   1
/////////////////////////////////////////////////////////////////////
//Drawing style has been changed from DRAW_LINE to 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[]; //Declare an array for color indexes

//Added two functions
//+------------------------------------------------------------------+
//|    Set color for a graphic plot                                  |
//+------------------------------------------------------------------+
/*
*       The function specify the color for a graphic plot 
*       50 colors from Green to Blue are available.
*       The index of a graphic plot is passed to the function.
*/
void setPlotColor(int plot)
  {
   PlotIndexSetInteger(plot,PLOT_COLOR_INDEXES,50); //Set number of colors

                                                    //Specify colors in loop
   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\""));
     }
  }
//+------------------------------------------------------------------+
//|  Get index of the color                                           |
//+------------------------------------------------------------------+
/*
*       The function returns the color index
*       The first parameter is the current value of the indicator
*       The second parameter is the minimal value of the indicator
*       The third parameter is the maximal value of the indicator
*/
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);
   
/////////////////////////////////////////////////////////////////////
//Assign the array with buffer of color indexes
        SetIndexBuffer(1,buffer_color,INDICATOR_COLOR_INDEX);
//The order of buffers is changed!
        SetIndexBuffer(2,ExtPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,ExtNegBuffer,INDICATOR_CALCULATIONS);
//Set colors
   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]);
/////////////////////////////////////////////////////////////////////
//Paint it
                buffer_color[i] = getPlotColor(ExtRSIBuffer[i],0,100);
/////////////////////////////////////////////////////////////////////
     }
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+

Eccolo, puoi confrontare il colore delle candele e dell'RSI.

Colore dell’RSI

Come Ottenere il valore del Colore dell'indicatore dall'Expert Advisor/Indicatore/Script

Spesso, è necessario ottenere il colore di una linea per il trading automatico in un Expert Advisor o per altri scopi.

L'implementazione è semplice, consideriamo uno script.

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                                                             ProF |
//|                                                          http:// |
//+------------------------------------------------------------------+
#property copyright "ProF"
#property link      "http://"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
        int handle = 0; //handle of the indicator
        double tmp[1];  //temporary array for color index buffer.
        //Get the handle of our modified RSI
        handle = iCustom(_Symbol,_Period,"Examples\\RSI",6);
        
        //Let's remember, that values are stored in the buffer 1 of our modified RSI
        //The color indexes are stored in the buffer 0
        //Copying the data from the buffer "1" of the RSI indicator.
        CopyBuffer(handle,1,0,1,tmp);
        
        //Show alert with last color index, returned by RSI
        Alert(tmp[0]); //For example, if returned 0, it means that RSI
        //is painted with Green color and its current level is near 0.
  }
//+-----------------------------------------------------------------+
Nota bene che possiamo ottenere il valore dell'indice del colore, non il colore stesso!

È necessario conoscere la corrispondenza tra gli indici di colore e i valori dei colori. Inoltre, è necessario conoscere il buffer degli indici di colore.

Per scoprirlo, è necessario comprendere i criteri dell'impostazione dell'indice di colore o determinarli empiricamente mediante questo script o utilizzando altri metodi.

Conclusione

Abbiamo considerato i seguenti stili di disegno MQL5: DRAW_COLOR_LINE, DRAW_COLOR_CANDLES. Abbiamo colorato le candele e imparato a colorare l'indicatore dell’RSI (DRAW_LINE -> DRAW_COLOR_LINE). Inoltre, abbiamo imparato come ottenere il valore degli indici del buffer dei colori.

Il linguaggio MQL5 ha molti stili di disegno, l'unico limite è la tua immaginazione. L'uso di linee colorate permette di vedere meglio il mercato.

Usa le nuove opportunità per un trading più comodo.