English Русский 中文 Español Deutsch 日本語 한국어 Français Italiano Türkçe
Criando indicadores multicoloridos no MQL5

Criando indicadores multicoloridos no MQL5

MetaTrader 5Indicadores | 26 dezembro 2013, 15:34
11 883 1
Дмитрий Александрович
Дмитрий Александрович

Introdução

Graças aos esforços dos desenvolvedores do MetaTrader 5, a linguagem MQL5 apareceu. Existem muitas inovações, mas aqui eu descrevo e considero a possibilidade de criação de indicadores multicoloridos. No MQL4 a cor pode ser especificada para uma linha, é a mesma para toda linha, e os indicadores multicoloridos são criados usando a sobreposição parcial dos buffers (memória de armazenamento) dos indicadores, o que não é conveniente.

Os desenvolvedores da linguagem MQL5 forneceram uma nova possibilidade - especificar a cor para cada sessão da linha indicadora (para linhas) e cores de objetos separados (para barras, velas, histogramas, setas). Para entender este artigo, é melhor dar uma olhada no MQL5 Reference.

Neste artigo, eu tentarei considerar os seguintes tópicos:

  • Noções básicas dos indicadores;
  • Memória de armazenamento (buffers) de dados do indicador;
  • Memória de armazenamento (buffers) dos índices de cor do indicador;
  • Como converter o modo de desenho de uma cor em multicor no exemplo do indicador RSI (conversão dos estilos de desenho DRAW_LINE para DRAW_COLOR_LINE);
  • Como pintar a planilha de candelabro (usando o estilo de desenho DRAW_COLOR_CANDLES) dependendo dos valores do indicador RSI;
  • Como obter o valor a partir da memória de armazenamento dos índices de cor.
Vamos considerar dois estilos de desenho - DRAW_COLOR_LINE e DRAW_COLOR_CANDLES, os estilos de desenho restantes diferem apenas nos números de reserva.

Porque indicadores de cor?

Usando os indicadores coloridos, você será capaz de:

  • Demonstrar informações adicionais nas velas;
  • Criar híbridos dos indicadores (a cor do MACD depende do valor de RSI);
  • Destacar os sinais importantes do indicador;
  • Apenas simplesmente decorar o seu terminal do cliente.

Simplesmente ativar sua imaginação e fazer seu negócio mais conveniente.

O básico do MQL5

Vamos começar com os princípios do indicador.

De modo geral, o indicador pega dados de entrada (preço, os outros dados indicadores), realiza alguns cálculos e preenche várias memórias de armazenamento com os dados. O terminal do cliente representa graficamente a informação das memórias de armazenamento, providas pelo indicador de acordo com seu tipo de desenho.

O estilo do desenho é definido pelo desenvolvedor. As memórias de armazenamento dos indicadores são arranjos de tipo duplo, declarado a nível global. Várias memórias de armazenamento podem ser combinadas nas representações gráficas, se mais de uma são necessárias para um estilo. Se você nunca criou indicadores personalizados, você deve ler os artigos (o básico está bem descrito neles): "MQL5: Create Your Own Indicator" e "Custom Indicators in MQL5 for Newbies".

Aqui está o código mínimo para o indicador de cor, eu vou descrever os seus componentes:

//+------------------------------------------------------------------+
//|                                         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
  }
//+------------------------------------------------------------------+

Vamos examinar os detalhes da escrita dos indicadores de cor:

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

Na primeira linha nós especificamos o número de memórias de armazenamento dos indicadores, no nosso caso, nós temos duas memórias:

  1. A memória de armazenamento (buffer) para os dados do indicador, no nosso caso, para o preço de abertura;
  2. A memória de armazenamento (buffer) para índices de cor.

Na segunda linha, nós especificamos o número de gráficos. É importante distinguir o gráfico e as memórias de armazenamento dos indicadores. O gráfico é a linha (vela, barra, seta, etc.) do indicador. Um indicador de memória de armazenamento é um arranjo com dados, necessários para planejar, arranjo com índices de cor ou um arranjo para os cálculos internos do indicador (este tipo não é desenhado na janela do indicador).

O número de representações pode ser igual ou menor que o número de memórias de armazenamento, isto depende do estilo de desenho e número de memórias de armazenamento para o cálculo. A tabela com estilos de desenho e número de memórias de armazenamento necessárias para cada estilo está disponível no capítulo Estilos de Desenhos do MQL5 Reference.

O "mais interessante" começa aqui:

#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

Na primeira linha, especificamos o estilo de desenho, em nosso caso, o estilo de desenho é um histograma de linha zero. Este estilo de desenho requer um buffer de dados e um buffer de índice colorido. Todos os estilos de desenho contendo a palavra "COLOR" requerem um buffer para índices de cor.

Na segunda linha, especificamos a largura de uma linha igual a três pixeis, por predefinição, a largura de uma linha é definida para um pixel.

Na terceira linha, especificamos as cores para os índices dos gráficos, neste caso, especificamos três cores "Vermelho", "Verde" e "AzulVioleta". Os índices coloridos estão começando do zero: 0-"Vermelho", 1-"Verde" e 2-"AzulVioleta" As cores são necessárias para definir as cores dos gráficos. As cores podem ser especificadas de diversas formas, "#property indicator_color1" é uma delas. Este é um método "estático", é usado no estágio de compilação de programa. O segundo método é discutido abaixo.

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

Aqui nós podemos declarar dois arranjos que serão usados como memórias de armazenamento (buffers), o primeiro será usado como buffer de dados, o segundo será usado para índices de cor, ambos declarados como arranjos de tipo duplo.

Vamos considerar a função de inicialização do indicador:

SetIndexBuffer(0,buffer_line,INDICATOR_DATA);

Aqui nós atribuímos o buffer do indicador com um arranjo, o tipo de buffer especificado "INDICATOR_DATA" significa que este buffer será usado para armazenar os valores do indicador (ou seja, a reserva de dados do indicador). Note que o primeiro parâmetro é igual a zero (0) - é o índice da memória (buffer).

SetIndexBuffer(1,buffer_color_line,INDICATOR_COLOR_INDEX);

Aqui nós atribuímos o indicador de buffer com um arranjo e especificamos "INDICATOR_COLOR_INDEX" como o tipo de memória de armazenamento (buffer) - isto significa que este buffer será usado para armazenar os índices de cor para cada barra do indicador. Note que o primeiro parâmetro é igual (1), é o índice da memória (buffer).

A ordenação do buffer deve ser especial: primeiro de tudo, os buffers dos dados indicadores, depois os buffers dos índices de cores.

E finalmente, a segunda maneira para especificar as cores dos gráficos (para especificar os índices de cor):

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

Aqui nós especificamos o número de índices de cor: O primeiro parâmetro da função é igual a "0", é o índice gráfico. Note que neste caso, nós devemos especificar o número dos índices de cor (no primeiro método, o compilador o calcula).

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

Aqui nós especificamos a cor para cada índice. O primeiro parâmetro da função é o índice dos gráficos, o terceiro parâmetro é o índice de cor, começando do 0. A segunda maneira de configurar índices de cor difere no seguinte: o número de cores e seus índices podem ser especificamos dinamicamente, por exemplo, usando a função. Se você usar ambos os métodos, lembre-se que o método dinâmico sobrepõe-se ao método estático (primeiro método).

Agora, considere a função OnCalculate, nós calculamos os valores das memórias de armazenamento para os gráficos do indicador. Nós escolhemos a regra mais simples para a seleção de cor para o histograma, se o preço de abertura é maior que o preço de fechamento, nós atribuímos o atual elemento de buffer com o índice de cor (no arranjo "buffer_color_line") igual a 0. O índice de cor, igual a zero (0) corresponde a cor "Azul", especificado acima.

Se o preço de abertura é menor que o preço de encerramento, nós atribuímos o índice de cor, igual a 1, que corresponde a cor correspondente laranja. Aqui está um exemplo simples:

Indicador teste

Pode-se ver, é fácil, nós apenas precisamos de alguma imaginação.

Os métodos de configuração de cor

Agora, vamos considerar os detalhes da configuração da cor.

De acordo com a Referência do MQL5, a cor pode ser especificada usando métodos diferentes:

  • Literalmente;
  • Numéricamente;
  • Usando nome das cores.

Vamos considerar todos eles.

Literalmente

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

As cores são definidas de acordo com o RGB (R para Vermelho, G para Verde e B para Azul), qualquer cor pode ser apresentada como uma combinação destas três cores. Consequentemente, o primeiro número corresponde ao componente de cor Vermelha. O segundo corresponde ao Verde, o terceiro corresponde ao componente Azul. Os números (na forma decimal) podem variar de 0 a 255. Numa base hexadecimal, os valores podem ser de 00 a FF.

A primeira e a segunda linhas são iguais, nos atribuímos a cor Azul a variável color_var. A diferença é a representação de um número em um sistema numeral específico, o decimal na primeira linha, e o hexadecimal na segunda linha. Não existe diferença, você pode escolher o modo, conveniente pra você. O número menor corresponde as cores mais escuras, a cor branca é: "C'255,255,255'" ou "C'0xFF,0xFF,0xFF'", a cor preta é: "C'0,0,0'" ou "C'0x00,0x00,0x00'".

Numéricamente

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

As cores são representadas nos sistemas numerais hexadecimal e decimal. Por exemplo, o valor "0x0000FF" é igual a "C'0xFF,0x00,0x00'", como nós vemos, o primeiro e o último pares dos números estão trocados.

Para obter o valor 16777215 no sistema numérico decimal, nós precisamos converter o número FFFFFF do sistema número hexadecimal para o decimal.

Nomes das cores

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

Esta é a maneira mais simples, mas você pode especificar apenas cores do conjunto web-colors.

Vamos resumir como nós podemos especificar cores.

Todos os três métodos são iguais, por exemplo:

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

Uma prática

Nós aprendemos o básico, agora vamos considerar como colorir as velas do gráfico com cores diferentes, dependendo dos valores indicadores, por exemplo, dependendo dos valores RSI. Para criar o candelabro de cores no gráfico, nós precisamos escrever um indicador que representará as cores de velas impostas no gráfico.

Aqui está o código do indicador, se os valores de RSI forem menores que 50%, ele desenha velas azuis, caso contrário, as velas são desenhadas com a cor Laranja.

Para evitar confusão do leitor, não existe checagem para correção dos dados e erros de processamento. Mas estes detalhes devem ser reconhecidos quando escrevendo o código funcional do indicador.

//+------------------------------------------------------------------+
//|                                                   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
  }
//+------------------------------------------------------------------+

É assim que se parece:

O indicador de cor, dependendo dos valores RSI

Parece bom, mas nós iremos a frente.

Vamos colorir as velas dependendo dos valores de RSI usando várias cores, chamado de gradiente de preenchimento.

As cores podem ser especificadas manualmente, mas não é conveniente e fácil especificar 30-40 cores. Faremos o seguinte: escreveremos duas funções, a primeira para os índices de cor, a segunda para obter a cor dependendo dos argumentos da função. A ideia é escrever em comentários.

//+------------------------------------------------------------------+
//|                                               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
  }
//+------------------------------------------------------------------+

É assim que se parece:

Gradiente_RSI

Usando isto como exemplo, configure outras cores. Tente substituir RSI por outro indicador.

A prática é sempre importante.

Estilos de desenho: convencional e multicor

Você pode pintar um indicador existente, você precisa fazer as seguintes coisas: modifique o estilo de desenho para multicolorido, adicione as memórias de armazenamento, atribua a elas as memórias de armazenamento dos indicadores e especifique os detalhes de pintura.

Aqui está uma tabela dos estilos de desenhos convencionais e estilos de desenhos (pintados) multicoloridos correspondentes:

Antes
Depois
DRAW_LINEDRAW_COLOR_LINE
DRAW_SECTIONDRAW_COLOR_SECTION
DRAW_HISTOGRAMDRAW_COLOR_HISTOGRAM
DRAW_HISTOGRAM2DRAW_COLOR_HISTOGRAM2
DRAW_ARROWDRAW_COLOR_ARROW
DRAW_ZIGZAGDRAW_COLOR_ZIGZAG (example)
DRAW_CANDLESDRAW_COLOR_CANDLES

Aqui está o código do RSI modificado, pintado dependendo de seus próprios valores.

Todas as modificações são 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 //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);
  }
//+------------------------------------------------------------------+

Aqui está, você pode comparar a cor das velas e RSI.

Cor RSI

Como conseguir o valor da cor do indicador a partir do Expert Advisor/Indicador/Script

Comumente é necessário obter a cor de uma linha para negociação automatizada em um Expert Advisor ou para algum outro propósito.

A implementação é simples, vamos considerar um roteiro.

//+------------------------------------------------------------------+
//|                                                         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.
  }
//+-----------------------------------------------------------------+
Note que nós podemos obter o valor do índice de cor, não da cor em si!

Você deve saber a correspondência entre os índices de cor e os valores das cores. Além disto, você deve saber o buffer dos índices de cor.

Para descobrir, você precisa entender o critério da configuração de índice de cor ou determiná-los empiricamente por este script ou utilizando outros métodos.

Conclusão

Consideramos os seguintes estilos de desenho do MQL5: DRAW_COLOR_LINE, DRAW_COLOR_CANDLES. Pintamos as velas e aprendemos como pintar o indicador RSI (DRAW_LINE -> DRAW_COLOR_LINE). Além disto, aprendemos como obter o valor das cores dos índices dos buffers.

A linguagem MQL5 tem vários estilos de desenho, o único limite é sua imaginação. O uso das linhas coloridas permite ver o mercado melhor.

Use a nova oportunidade para uma negociação mais confortável.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/135

Arquivos anexados |
cand_color.mq5 (4.59 KB)
cand_color_rsi.mq5 (5.77 KB)
rsi.mq5 (6.9 KB)
test.mq5 (1.41 KB)

Outros artigos do autor

Últimos Comentários | Ir para discussão (1)
Paulo Eduardo Lemes
Paulo Eduardo Lemes | 16 jul 2019 em 21:29
Muito bom , estou enfrentando uma dificuldade imensa em criar uma regra de coloração com Estocástico. Teria algum exemplo ?
Diversas maneiras de se encontrar uma tendência no MQL5 Diversas maneiras de se encontrar uma tendência no MQL5
Qualquer comerciante daria muito pela oportunidade de detectar precisamente uma tendência em qualquer dado momento. Talvez, este seja o Santo Graal que todo mundo esteja procurando por. Este artigo considerará diversas maneiras de detectar uma tendência. Para ser mais preciso - como programar diversas maneiras clássicas para detectar uma tendência pelos meios do MQL5.
Como criar o seu próprio limite móvel Como criar o seu próprio limite móvel
A regra básica do negociante - aumente o lucro, corte as despesas! Este artigo considera uma das técnicas básicas, permitindo seguir esta regra - mover o nível de parada de proteção (nível Stop Loss) após aumentar o lucro da posição, ou seja - nível do Limite móvel. Você encontrará o procedimento passo-a-passo para criar uma classe para o limite móvel nos indicadores SAR e NRTR. Todos poderão inserir este limite móvel em seus experts ou usá-los independentemente para controlar posições em suas contas.
Avaliação de sistemas de negócio - A efetividade de entrada, saída e negócios em geral Avaliação de sistemas de negócio - A efetividade de entrada, saída e negócios em geral
Existem várias medidas que permitem determinar a eficácia e rentabilidade de um sistema de negócio. No entanto, os negociantes estão sempre prontos para colocar qualquer sistema em um novo teste de impacto. O artigo diz como as estatísticas baseadas em medidas de efetividade podem ser usadas para a plataforma MetaTrader 5. Ele inclui a classe para transformação da interpretação das estatísticas através de negócios para aquele que não contradiz a descrição dada no livro "Statistika dlya traderov" ("Statistics for Traders") por S.V. Bulashev. Ele também inclui um exemplo de uma função de personalização para otimização.
O protótipo do robô de negócio O protótipo do robô de negócio
Este artigo resume e sintetiza os princípios da criação de algoritmos e elementos dos sistemas de negócio. O artigo considera o planejamento do algoritmo de especialista. Como um exemplo, a classe CExpertAdvisor é considerada, o que pode ser usado para facilmente e rapidamente desenvolver sistemas de negócio.