Explorando as possibilidades de criar gráficos de velas multicoloridas
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
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso