English Русский 中文 Español Deutsch 日本語
preview
Explorando as possibilidades de criar gráficos de velas multicoloridas

Explorando as possibilidades de criar gráficos de velas multicoloridas

MetaTrader 5Exemplos | 29 outubro 2021, 09:45
2 170 1
Samuel Manoel De Souza
Samuel Manoel De Souza

Introdução

Neste artigo, veremos as possibilidades de criação de gráficos de velas personalizados, e falaremos sobre suas vantagens e desvantagens. Adicionalmente, consideraremos quatro alternativas para esse tipo de indicadores:

1. Plotagem de velas da mesma cor sem definir sua direção.

2. Plotagem de velas multicoloridas, coloridas de acordo com certas regras.

3. Plotagem de velas com e sem preenchimento usando várias cores para preencher as velas e seus contornos.

4. Plotagem de velas multicoloridas com e sem preenchimento.

Primeiro, vamos estabelecer por que precisamos definir regras para colorir gráficos de velas. Também vamos ver por que será importante definir corretamente essas regras quando você crie seus próprios indicadores. Cada método possui características, vantagens e desvantagens próprias que podem estar associadas, por exemplo, à interação do usuário com o programa ou à otimização do uso de recursos computacionais.

Vamos começar com um modelo de trabalho que funciona com três linhas de preço deslocadas. A primeira linha (preta) é o preço, a segunda (azul), a média móvel de 1 período deslocada 10 períodos para a frente, e a terceira (vermelha) representa a média móvel de 1 período deslocada 20 períodos para a frente. Abaixo mostro plotagem do modelo no gráfico de preços, também adicionei duas médias móveis e mudei para visualização de linha.

Obtivemos um modelo pouco prático, difícil de interpretar. Afinal, necessitamos não apenas determinar a cor das linhas, mas também analisar como elas se relacionam. Isto só causa confusão, o que pode levar a más decisões. Outro modelo ambíguo e de difícil interpretação é o do indicador Average Directional Movement Index. Isso é assim porque, além de determinar as cores das linhas, também é necessário analisar suas relações.

Normalmente, quantas mais variáveis ou indicadores tivermos, mais frequentemente poderão ocorrer erros de interpretação, pelo que a qualidade das decisões tomadas pode ser questionável. Acho que devemos usar tantos indicadores e variáveis quantas pudermos analisar de forma eficaz e tantas quantas pudermos usar para extrair informações relevantes e objetivas.

O uso de regras de coloração permite um melhor aproveitamento de informações valiosas e possibilita uma resposta clara quanto a quando comprar, quando vender e quando é melhor ficar fora do mercado. Assim, todas as informações podem ser apresentadas em três cores: uma mostra compra, a segunda, venda e a terceira é utilizada quando não há condições de compra ou venda. Neste artigo, usarei verde para exibir compra, vermelho para venda e amarelo para todos os outros casos. A definição das cores é mostrada na tabela:

Cor Direção
verde compra
vermelho venda
 amarelo  neutro

Por enquanto, não vamos pensar nas regras que definem como as velas são coloridas. Primeiro, vamos ver como construir um gráfico de velas em MQL5. Se você está escrevendo um programa MQL5 para MetaTrader 5 pela primeira vez, recomendo ler a ajuda sobre MetaEditor, que é o ambiente de desenvolvimento para MetaTrader 5.


Plotando o gráfico de velas

Primeiro, mostrarei como construir um gráfico de velas simples e explicarei algumas das funções básicas. Um gráfico de velas consiste num conjunto de velas. Cada vela é formada com base em quatro valores de preço: abertura, máximo, mínimo e fechamento durante a formação da vela. Para determinar se é uma vela altista ou baixista, precisamos verificar se ela fechou acima ou abaixo do preço de abertura. Se o fechamento for mais alto que a abertura, colorimos de verde; por outra parte, se o fechamento for menor, de vermelho.

Agora criemos um indicador usando o assistente MQL.


Definimos o nome do indicador e indicamos as informações sobre os direitos autorais, ou seja, o nome do autor e o endereço da página web.


No indicador, usaremos a função OnCalculate que conterá uma série temporal de preços de abertura, máximos, mínimos e de fechamento.


Como o indicador será exibido como um gráfico de velas, no campo "tipo", selecionaremos CANDLES e damos o rótulo Candles. Este rótulo será usado na interface do programa e no trabalho com buffers de indicador.


Abaixo está o código criado pelo assistente MQL:

//+------------------------------------------------------------------+
//|                                                      Candles.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   1
//--- plot Candle
#property indicator_label1  "Candle"
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double         CandleBuffer1[];
double         CandleBuffer2[];
double         CandleBuffer3[];
double         CandleBuffer4[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CandleBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,CandleBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,CandleBuffer3,INDICATOR_DATA);
   SetIndexBuffer(3,CandleBuffer4,INDICATOR_DATA);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Após compilarmos o código, o indicador Candles aparecerá no navegador do terminal MetaTrader 5. Mas se o executarmos no gráfico, ele será exibido incorretamente, uma vez que não atribuímos valores aos buffers de indicador. Por isso, atribuímos valores. Em nosso primeiro método, temos 4 buffers: CandleBuffer1 [], CandleBuffer2 [], CandleBuffer3 [], CandleBuffer4 []. A finalidade desses buffers é mostrada na tabela abaixo:

Buffers Faixa de preços
CandleBuffer1 preços de abertura
CandleBuffer2 preços máximos
CandleBuffer3 preços mínimos
CandleBuffer4 preços de fechamento

No código, devemos especificar o número de buffers de indicador, usando a propriedade indicator_buffers do indicador. O próprio assistente MQL já fez isso, mas você pode alterar o número de buffers e especificar de quantos um indicador específico precisa. Faremos isso mais tarde.

#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 4

Atribuiremos valores aos nossos buffers na função OnCalculate aplicando um loop ao longo de toda a faixa de preço. Além disso, assim que o valor for atribuído, este não precisará ser reatribuído novamente caso o tamanho da série aumente. Desse modo, se na saída da função tivermos n velas e na próxima chamada houver n + 1, precisaremos calcular os valores apenas para a última vela. Na função OnCalcultate, as informações sobre o número de velas no gráfico são obtidas usando o parâmetro rates_total, já o número de velas que estavam no gráfico na chamada anterior da função é obtido usando o parâmetro prev_calculated.

A função OnCalculate fica assim:

//+------------------------------------------------------------------+
//| 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[])
  {
//---
   int start = prev_calculated;
   if(start>=rates_total)
      start = rates_total-1;

   for(int i = start; i<rates_total; i++)
     {
      CandleBuffer1[i]=open[i];
      CandleBuffer2[i]=high[i];
      CandleBuffer3[i]=low[i];
      CandleBuffer4[i]=close[i];
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Note que todas as velas em nosso indicador são vermelhas, uma vez que definimos esta cor no assistente MQL. Esta cor pode ser alterada pelo usuário ou no código usando a propriedade indicator_color1. Para entender como definir e trabalhar com cores em MQL5, consulte a documentação sobre dados de tipo Color.

//--- plot Candle
#property indicator_label1  "Candle"
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1


Plotando o gráfico de velas multicoloridas

Foi-nos apresentada a plotagem de um gráfico de velas sem separação por cor e sem determinação da direção das velas. Agora veremos como gerar no gráfico as velas multicoloridas e colori-las com base em certas condições. Primeiro, implementamos uma regra para identificar as velas para cima e para baixo por cor.

Para fazer isso, usamos o tipo de plotagem DRAW_CANDLES definido na propriedade indicator_type1 do indicador. Ela pode ser alterada para DRAW_COLOR_CANDLES, com o propósito de obter velas multicoloridas. Como o tipo de plotagem DRAW_COLOR_CANDLES deve armazenar a cor de cada vela, precisamos de um buffer adicional - vamos chamá-lo de CandleColor. Agora, o número de buffers usados aumentou para 5. Além disso, precisamos adicionar cor para a propriedade indicator_color1.

#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   1
//--- plot Candle
#property indicator_label1  "Candle"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrGreen,clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double         CandleBuffer1[];
double         CandleBuffer2[];
double         CandleBuffer3[];
double         CandleBuffer4[];
double         CandleColor[];

Em seguida, inicializamos o buffer CandleColor, que armazenará as cores das velas - informamos o compilador de que queremos usar esse buffer para armazenar as cores. Para isso, usamos a função SetIndexBuffer e passamos como parâmetro INDICATOR_COLOR_INDEX. No nosso caso, temos duas cores - verde e vermelho. A primeira cor tem índice 0, já a segunda, 1. Se em cor_indicador1 forem definidas n cores, obteremos índices de cor de 0 a n-1:

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,CandleBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,CandleBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,CandleBuffer3,INDICATOR_DATA);
   SetIndexBuffer(3,CandleBuffer4,INDICATOR_DATA);
   SetIndexBuffer(4,CandleColor,INDICATOR_COLOR_INDEX);

//---
   return(INIT_SUCCEEDED);
  }

Observe que as alterações podem ser feitas diretamente no assistente MQL, no qual os buffers são inicializados/declarados e o número de buffers necessários é indicado. É na janela do assistente MQL que precisamos alterar o tipo de plotagem para DRAW_COLOR_CANDLES e selecionar as cores. Esta é uma alternativa muito útil, especialmente ao trabalhar com um indicador que deve traçar mais de um tipo de plotagem no gráfico. Voltaremos a isso mais tarde.

Agora precisamos atribuir valores ao buffer CandleColor. Usaremos o fecho como condição de coloração: se a vela fechar acima da abertura, colorimos de verde, se fechar abaixo, de vermelho. Vamos ver como a função OnCalculate fica agora:

   for(int i = start; i<rates_total; i++)
     {
      CandleBuffer1[i]=open[i];
      CandleBuffer2[i]=high[i];
      CandleBuffer3[i]=low[i];
      CandleBuffer4[i]=close[i];

      //if the close price is higher than the open price we set the 
      //green color (index 0), otherwise, the red color (index 1)
      CandleColor[i]=(close[i]>open[i])?0:1;
 

Como esperado, o resultado é um gráfico padrão com velas de alta e de baixa em cores diferentes.

Vamos mudar a condição de coloração. Em vez de determinar a direção do fechamento da vela (acima e abaixo), usaremos uma condição de negociação muito simples. Na próxima seção, veremos outra maneira de determinar a direção das velas.

Vejamos o modelo de trabalho apresentado no início do artigo. Conforme as regras, se a linha preta (preço de fechamento) for maior que a linha azul (deslocada 10 períodos) e a linha vermelha (deslocada 20 períodos), pode-se comprar. Se a linha preta (preço de fechamento) for menor que as linhas azul e vermelha, pode-se vender. Em todos os outros casos, é preciso esperar que a direção do mercado seja definida. Essas regras são mostradas na tabela:

Regras de negociação Cor de vela
close[0] > close[10] and close[0] > close[20] verde
close[0] < close[10] and close[0] < close[20] vermelho
close[0] > close[10] and close[0] < close[20] amarelo
 close[0] < close[10] and close[0] > close[20]  amarelo

Neste modo, precisamos adicionar mais uma cor à propriedade indicator_color1.

#property indicator_color1  clrGreen,clrRed,clrYellow

Agora, essa condição pode ser adicionada ao código e atribuída aos valores em questão. Aqui está o que temos agora na função OnCalculate:

  {
//---
   int start = prev_calculated;
   if(prev_calculated<20)
      start = 20;
   if(start>=rates_total)
      start = rates_total-1;

   for(int i = start; i<rates_total; i++)
     {
      CandleBuffer1[i]=open[i];
      CandleBuffer2[i]=high[i];
      CandleBuffer3[i]=low[i];
      CandleBuffer4[i]=close[i];

      //Close[0] > Close[10] and Close[0] > Close[20]
      bool buy = close[i]>close[i-10] && close[i]>close[i-20];

      //Close[0] < Close[10] and Close[0] < Close[20]
      bool sell  = close[i]<close[i-10] && close[i]<close[i-20];

      CandleColor[i]=(buy)?0:(sell)?1:2;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

O resultado de funcionamento do indicador:

Agora vamos ver a interface do usuário na janela de parâmetros do indicador MetaTrader 5. Se clicarmos duas vezes no indicador na janela do gráfico, abriremos a janela de parâmetros do indicador. Na figura abaixo, podemos ver que as cores são passadas como parâmetros sem especificar qual cor corresponde às condições para compra, qual para venda e qual para estado neutro. Se tivéssemos mais cores, trabalharíamos com o indicador de maneira completamente inconveniente. Por isso, é necessário explicar ao usuário o que significa cada cor. Isso é o que faremos no último capítulo do artigo.



Plotando o gráfico de velas com e sem enchimento

Vamos voltar ao código inicial, isto é, quando todas as velas eram da mesma cor. Lembre-se de que usamos o tipo de plotagem DRAW_CANDLES com quatro buffers. Para usar cores diferentes para os contornos e o preenchimento, basta definirmos duas cores em nossa propriedade indicator_color1. A primeira cor será usada para o contorno e a segunda para o preenchimento da vela. Vejamos as velas pretas e brancas para visualizar o resultado.

#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrBlack,clrWhite

Se definirmos 3 cores na propriedade indicator_color1, já distinguiremos velas de baixa das de alta. Esta forma de plotagem de velas substitui a primeira regra de coloração que criamos neste artigo. A diferença é que continuamos usando 4 buffers e ainda podemos definir as cores de contorno. Nesse caso, a primeira cor é aplicada aos contornos da vela, a segunda cor, ao preenchimento das velas de alta e a terceira, ao preenchimento das de baixa. A figura abaixo mostra um gráfico desse tipo, para a terceira cor é usado um cinza escuro, que não se confunde com a cor do contorno.

#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrBlack,clrWhite,clrDarkGray

Plotando o gráfico de velas multicoloridas com opções de preenchimento de velas

Para terminar de aprender como criar velas coloridas em MQL5, vamos tornar a interface da janela de parâmetros do indicador mais informativa. Esta é uma etapa intermediária para criar velas multicoloridas - algumas serão preenchidas e outras não. O número de buffers necessários será o mesmo em ambos os casos, mas há mais deles do que o número de buffers nas alternativas discutidas anteriormente. Isso ocorre porque não usaremos plotagens para todas as cores, em vez disso, usaremos uma para cada cor. Nosso modelo possui três plotagens: para compra, para venda e para condições indefinidas, conforme sugerido no início do artigo. Desse modo, para implementarmos tal modelo, precisaremos de 12 buffers. Além disso, para determinar a cor, usaremos as mesmas regras definidas para as médias móveis com deslocamento.

Vamos usar o assistente MQL novamente. Com isso, omitiremos as etapas para definir e inicializar 12 buffers. Em vez da plotagem do tipo Candle, usaremos as construções Buy, Sell e Neutral.


Não precisamos que todos os elementos sejam exibidos ao mesmo tempo. O indicador deve selecionar uma das três alternativas de exibição com base nas regras que definimos, as outras devem estar ocultas por enquanto. Para isso, os buffers de velas ocultas devem ser preenchidos com um valor vazio. O primeiro passo é determinar os valores para os quais a plotagem deve ser dispensada. Para fazer isto, usamos a função PlotIndexSetDouble, como mostrado abaixo.

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BuyBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,BuyBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,BuyBuffer3,INDICATOR_DATA);
   SetIndexBuffer(3,BuyBuffer4,INDICATOR_DATA);
   SetIndexBuffer(4,SellBuffer1,INDICATOR_DATA);
   SetIndexBuffer(5,SellBuffer2,INDICATOR_DATA);
   SetIndexBuffer(6,SellBuffer3,INDICATOR_DATA);
   SetIndexBuffer(7,SellBuffer4,INDICATOR_DATA);
   SetIndexBuffer(8,NeutralBuffer1,INDICATOR_DATA);
   SetIndexBuffer(9,NeutralBuffer2,INDICATOR_DATA);
   SetIndexBuffer(10,NeutralBuffer3,INDICATOR_DATA);
   SetIndexBuffer(11,NeutralBuffer4,INDICATOR_DATA);

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0);

//---
   return(INIT_SUCCEEDED);
  }

Em nosso caso, usamos os valores 0,0 para definir valores vazios em nossos buffers. Os valores 0, 1 e 2, que são passados como o primeiro parâmetro para a função PlotIndexSetDouble, são os índices das plotagens que devem ser exibidas no gráfico de preços. Este é o mesmo índice usado ao declarar propriedades para nossas plotagens.

Tudo o que precisamos fazer é aplicar as regras que definimos anteriormente na função OnCalculate do nosso indicador. Como apenas uma plotagem pode ser exibida por vez, podemos definir outra como invisível (oculta) atribuindo um valor de 0,0 a todas as velas cada vez que a função OnCalculate é chamada. Em seguida, atribuímos os valores dos preços de abertura, máximo, mínimo e fechamento às velas que precisam ser plotadas no gráfico de acordo com as regras. Eis o que temos:

  {
//---
   int start = prev_calculated;
   if(prev_calculated<20)
      start = 20;
   if(start>=rates_total)
      start = rates_total-1;

   for(int i = start; i<rates_total; i++)
     {
      //initializing the candles data
      BuyBuffer1[i]=0.0;
      BuyBuffer2[i]=0.0;
      BuyBuffer3[i]=0.0;
      BuyBuffer4[i]=0.0;

      SellBuffer1[i]=0.0;
      SellBuffer2[i]=0.0;
      SellBuffer3[i]=0.0;
      SellBuffer4[i]=0.0;

      NeutralBuffer1[i]=0.0;
      NeutralBuffer2[i]=0.0;
      NeutralBuffer3[i]=0.0;
      NeutralBuffer4[i]=0.0;

      //Close[0] > Close[10] e Close[0] > Close[20]
      bool buy= close[i]>close[i-10] && close[i]>close[i-20];

      //Close[0] < Close[10] e Close[0] < Close[20]
      bool sell= close[i]<close[i-10] && close[i]<close[i-20];

      //Setting the values to the candles according to the trading rules
      if(buy)
        {
         BuyBuffer1[i]=open[i];
         BuyBuffer2[i]=high[i];
         BuyBuffer3[i]=low[i];
         BuyBuffer4[i]=close[i];
        }
      else
         if(sell)
           {
            SellBuffer1[i]=open[i];
            SellBuffer2[i]=high[i];
            SellBuffer3[i]=low[i];
            SellBuffer4[i]=close[i];
           }
         else
           {
            NeutralBuffer1[i]=open[i];
            NeutralBuffer2[i]=high[i];
            NeutralBuffer3[i]=low[i];
            NeutralBuffer4[i]=close[i];
           }

     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }

Visualmente, o resultado é o mesmo que ao usar o tipo de plotagem DRAW_COLOR_CANDLES. A grande vantagem do novo método é que obtemos uma interface de usuário mais intuitiva, apesar de um aumento significativo no número de buffers necessários. Esta característica pode ser melhorada adicionando cores não apenas para exibir informações de acordo com regras determinadas, mas também para distinguir entre velas de alta e de baixa. Para fazer isso, podemos trabalhar as cores de contorno e de preenchimento. Para cada plotagem, o contorno e o preenchimento para velas descendentes será da mesma cor, enquanto para velas ascendentes usaremos branco contra a tabela de preços com um fundo branco, criando a ilusão de velas não preenchidas. A tabela abaixo mostra o uso de cores para o novo esquema.

Regras de negociação Contorno Preenchimento positivo Preenchimento negativo
compra verde branco verde
venda vermelho branco vermelho
neutro amarelo branco amarelo

As mudanças no código são mostradas abaixo:

#property indicator_color1  clrGreen,clrWhite,clrGreen
#property indicator_color2  clrRed,clrWhite,clrRed
#property indicator_color3  clrYellow,clrWhite,clrYellow

Assim, alcançamos o objetivo deste artigo, que era o de demonstrar como criar regras de coloração com base em certas condições de negociação escolhidas para criar um gráfico de velas personalizado. O resultado do trabalho feito é mostrado na figura abaixo:


Conclusão

Vimos que podemos criar gráficos de velas usando dois tipos de plotagem, nomeadamente DRAW_CANDLES e DRAW_COLOR_CANDLES. Aprendemos como colorir o gráfico de velas com base nas regras de negociação que selecionamos, e como usar várias cores para os contornos e o preenchimento das mesmas, o que nos permite colori-las e mostrar a diferença entre as de alta e as de baixa. É importante destacar que, dependendo da finalidade do indicador que está sendo desenvolvido, talvez não se queira usar várias cores para identificar velas para cima e para baixo. Além disso, se tivermos que usar muitas cores, por exemplo 10, o último método proposto não será muito prático, pois o número de buffers utilizados será muito grande, podendo aumentar o uso de recursos por parte dos usuários.

Neste caso, há duas alternativas que podem ser usadas em vez de explicar a finalidade de cada cor na janela de parâmetros do indicador. Podemos usar o tipo de plotagem DRAW_COLOR_CANDLES ou DRAW_CANDLES e criar a ilusão de velas não preenchidas, desenhando apenas os contornos para aquelas que apontam para baixo, e deixando o preenchimento transparente, desta forma o preenchimento irá combinar com o fundo do gráfico e obteremos a diferença entre velas de alta e de baixa colocadas sobre a plotagem DRAW_COLOR_CANDLES com base nas regras selecionadas.


Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/7815

Últimos Comentários | Ir para discussão (1)
Gustavo Franthesco Kerntopf
Gustavo Franthesco Kerntopf | 5 mar 2022 em 02:25
//+------------------------------------------------------------------+
//|                                                Color Candles.mq5 |
//|                           Copyright 2020, Samuel Manoel de Souza |
//|                          https://www.mql5.com/pt/users/samuelmnl |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Samuel Manoel de Souza"
#property link      "https://www.mql5.com/pt/users/samuelmnl"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 12
#property indicator_plots   3
//--- plot bull
#property indicator_label1  "bull"
#property indicator_type1   DRAW_CANDLES
#property indicator_color1  clrGreen,clrBlack,clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot bear
#property indicator_label2  "bear"
#property indicator_type2   DRAW_CANDLES
#property indicator_color2  clrRed,clrBlack,clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot range
#property indicator_label3  "wait"
#property indicator_type3   DRAW_CANDLES
#property indicator_color3  clrGold,clrBlack,clrGold
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
//--- indicator buffers
double         bullBuffer1[];
double         bullBuffer2[];
double         bullBuffer3[];
double         bullBuffer4[];
double         bearBuffer1[];
double         bearBuffer2[];
double         bearBuffer3[];
double         bearBuffer4[];
double         rangeBuffer1[];
double         rangeBuffer2[];
double         rangeBuffer3[];
double         rangeBuffer4[];

input int inpShift = 0; //Indicator Shift
input int inpBlue = 10;//Blue Shift
input int inpRed = 20; //Red Shift

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(inpBlue <= 0)
     {
      Alert("Blue Shift must be greater then 0!");
      return INIT_PARAMETERS_INCORRECT;
     }
   if(inpRed <= inpBlue)
     {
      Alert("Red Shift must be greater then Blue Shift!");
      return INIT_PARAMETERS_INCORRECT;
     }
//--- indicator buffers mapping
   SetIndexBuffer(0, bullBuffer1, INDICATOR_DATA);
   SetIndexBuffer(1, bullBuffer2, INDICATOR_DATA);
   SetIndexBuffer(2, bullBuffer3, INDICATOR_DATA);
   SetIndexBuffer(3, bullBuffer4, INDICATOR_DATA);
   SetIndexBuffer(4, bearBuffer1, INDICATOR_DATA);
   SetIndexBuffer(5, bearBuffer2, INDICATOR_DATA);
   SetIndexBuffer(6, bearBuffer3, INDICATOR_DATA);
   SetIndexBuffer(7, bearBuffer4, INDICATOR_DATA);
   SetIndexBuffer(8, rangeBuffer1, INDICATOR_DATA);
   SetIndexBuffer(9, rangeBuffer2, INDICATOR_DATA);
   SetIndexBuffer(10, rangeBuffer3, INDICATOR_DATA);
   SetIndexBuffer(11, rangeBuffer4, INDICATOR_DATA);
//---Setting which value make the bars invisible
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0);
//---Setting the shift values for each bar
   PlotIndexSetInteger(0, PLOT_SHIFT, inpShift);
   PlotIndexSetInteger(1, PLOT_SHIFT, inpShift);
   PlotIndexSetInteger(2, PLOT_SHIFT, inpShift);
//---Setting from where the bars must be drawed
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, inpRed - 1);
   PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, inpRed - 1);
   PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, inpRed - 1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
//---If there is no sufficient bars, don't calculate
   if(rates_total < inpRed)
     {
      return rates_total;
     }
//---Defining from where we should start the calculation
   int limit;
   if(prev_calculated < inpRed)
      limit = inpRed;
   else
      limit = prev_calculated - 1;
//---Main calculation loop
   for(int i = limit; i < rates_total; i++)
     {
      int shift = BarIndex2shift(i);
      double open = iOpen(_Symbol, _Period, shift);
      double high = iHigh(_Symbol, _Period, shift);
      double low = iLow(_Symbol, _Period, shift);
      double close = iClose(_Symbol, _Period, shift);
      double red = price[i - (inpRed)]; //Getting the Red line value
      double blue = price[i - inpBlue]; //Getting the Blue line value
      double yellow = price[i];     //Getting the Yellow line value
      //There are three flags for this filter
      //0 = sell, 1= wait, 1 = buy
      // we can buy if 2 lines is above the red
      // we can sell if 2 lines is below the red
      int direction = 0;
      direction += (yellow > red) ? 1 : 0; // If Yellow is above Red, add 1
      red = blue;
      blue = yellow;
      direction += (blue > red) ? 1 : 0; // If Blue is above Red, add 1 .
      //For default bars isn't visible
      bullBuffer1[i] = 0;
      bullBuffer2[i] = 0;
      bullBuffer3[i] = 0;
      bullBuffer4[i] = 0;
      bearBuffer1[i] = 0;
      bearBuffer2[i] = 0;
      bearBuffer3[i] = 0;
      bearBuffer4[i] = 0;
      rangeBuffer1[i] = 0;
      rangeBuffer2[i] = 0;
      rangeBuffer3[i] = 0;
      rangeBuffer4[i] = 0;
      //We'll assign value to each bar according with the direction flag
      switch(direction)
        {
         case 0: // Is bear market
           {
            bearBuffer1[i] = open;
            bearBuffer2[i] = high;
            bearBuffer3[i] = low;
            bearBuffer4[i] = close;
            break;
           }
         case 1: // Is bull market
           {
            rangeBuffer1[i] = open;
            rangeBuffer2[i] = high;
            rangeBuffer3[i] = low;
            rangeBuffer4[i] = close;
            break;
           }
         case 2: // Is range market
           {
            bullBuffer1[i] = open;
            bullBuffer2[i] = high;
            bullBuffer3[i] = low;
            bullBuffer4[i] = close;
            break;
           }
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

int BarIndex2shift(int bar) {return Bars(_Symbol, _Period) - bar - 1;}

//+------------------------------------------------------------------+
Gráficos na biblioteca DoEasy (Parte 84): classes herdeiras do objeto gráfico abstrato padrão Gráficos na biblioteca DoEasy (Parte 84): classes herdeiras do objeto gráfico abstrato padrão
Neste artigo, veremos como se criam classes herdeiras do objeto gráfico abstrato padrão do terminal. O objeto deste tipo de classe descreve propriedades comuns a todos os objetos gráficos, isto é, ele é apenas um tipo de objeto gráfico. Para entender se pertence a um objeto gráfico real, precisamos gerar herança a partir dele, já na classe do objeto herdeiro precisamos escrever as propriedades que são específicas do objeto gráfico em particular.
Analisando o spread para preços de Bid e Ask no MetaTrader 5 Analisando o spread para preços de Bid e Ask no MetaTrader 5
Neste artigo falo de uma ferramenta capaz de ver os spreads, isto é, as diferenças entre os valores Bid e Ask da sua corretora. Os dados de ticks presentes no MetaTrader 5 possibilitam analisar quais valores históricos de spreads existiam de fato entre os valores Bid e Ask. Contudo, não há razão para procurar o valor atual do spread, pois ele pode ser obtido por meio da visualização das linhas Bid e Ask.
Gráficos na biblioteca DoEasy (Parte 85): coleção de objetos gráficos, adicionamos recém-criados Gráficos na biblioteca DoEasy (Parte 85): coleção de objetos gráficos, adicionamos recém-criados
Neste artigo, finalizaremos a criação das classes herdeiras da classe abstrata do objeto gráfico e iniciaremos a implementação do armazenamento desses objetos na classe-coleção. Em particular, criaremos a funcionalidade para adicionar à classe-coleção objetos gráficos padrão recém-criados.
Gráficos na biblioteca DoEasy (Parte 83): classe abstrata de objetos gráficos padrão Gráficos na biblioteca DoEasy (Parte 83): classe abstrata de objetos gráficos padrão
Neste artigo, criaremos uma classe para um objeto gráfico abstrato. Este objeto será a base para a criação de classes de objetos gráficos padrão. Os objetos gráficos têm muitas propriedades, e hoje, antes de criarmos uma classe de objetos gráficos abstratos, precisamos realizar um intenso trabalho preliminar, especificando ditas propriedades nas enumerações da biblioteca.