Do básico ao intermediário: Indicador (III)
No artigo anterior Do básico ao intermediário: Indicador (II), tivemos um momento de bastante diversão e aprendizado. Já que foi demonstrado como poderíamos implementar uma média móvel de forma muito simples, prática e perfeitamente funcional. Mas aquilo que foi mostrado, podemos dizer que foi apenas uma breve introdução, ao que seria o mundo de um programador MQL5. Visto que aquele material é bem básico, simples e direto. Mas podemos fazer muito mais do que o que foi mostrado.
Então meu caro leitor, tente compreender os conceitos adotados aqui. Não tente simplesmente copiar o código ou achar, que só por você não está conseguindo fazer, ninguém mais sabe como fazer está ou aquela coisa. Entender o conceito é mais importante do que entender o próprio código. Já que o código pode vir a mudar dependendo de quem o estiver escrevendo. Porém o conceito irá sempre se manter. Então vamos começar com algo bem simples. Já que o que será visto pode vir a ser muito complicado se já aplicarmos certas funcionalidades assim, de uma hora para outra.
Um indicador e múltiplas plotagens
Você muito provavelmente já deve ter visto, pessoas programando, ou mesmo você já deve ter experimentado, criar algum tipo de sistema ou setup operacional. Isto para tentar fazer dinheiro operando no mercado de capitais. Não é raro, muitos destes sistemas, fazer uso de diversas médias móveis. Sendo em muitos casos uma contra outra. Além disto, temos também sistemas de canais, como as famosas bandas de Bollinger, onde nos são apresentados um sistema de duas médias móveis. Uma que representaria a banda superior e outra que seria a banda inferior. Mas não estou aqui, para explicar como este sistema poderia ser utilizado para operar no mercado. Meu objetivo aqui, é mostrar como poderíamos fazer algo daquele estilo. Isto de maneira simples e prática.
No caso das bandas de Bollinger, que estou utilizando como exemplo, mas poderia ser qualquer outra coisa. Temos de fato duas linhas sendo plotadas, as vezes três, onde uma representaria a média interna do canal. Mas vamos simplificar as coisas para apenas duas. Isto para que você consiga entender como implementar qualquer quantidade de linhas. Para começar, vamos utilizar o código visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_LINE 05. #property indicator_color1 clrBlack 06. //+----------------+ 07. #property indicator_buffers 1 08. #property indicator_plots 1 09. //+----------------+ 10. double gl_buffer[]; 11. //+------------------------------------------------------------------+ 12. int OnInit() 13. { 14. SetIndexBuffer(0, gl_buffer, INDICATOR_DATA); 15. 16. return INIT_SUCCEEDED; 17. }; 18. //+------------------------------------------------------------------+ 19. 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 &TickVolume[], const long &Volume[], const int &Spread[]) 20. { 21. for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) 22. gl_buffer[c] = High[c]; 23. 24. return rates_total; 25. }; 26. //+------------------------------------------------------------------+
Código 01
Muito bem, acredito que não preciso mostrar o que este código irá fazer, quando o mesmo for executado e colocado em um gráfico. Isto por que, já explicamos isto em detalhes nos dois artigos anteriores. Tudo que precisamos fazer é olhar o que está sendo feito na função de tratamento de eventos. No caso a função OnCalculate. Você pode ver, que ali claramente estamos utilizando o valor de máxima. Ou seja, teremos uma linha de plotagem que seguirá a máxima de cada barra. Já que não estamos efetuando nenhum tipo de cálculo de suavização. E sim, meu caro leitor, os cálculos de média móvel, visam justamente suavizar a curva que estará sendo plotada na tela. Criando assim um valor médio entre tantos valores que foram utilizados no cálculo. Mas isto envolve explicar material matemático, algo que foge ao que é proposto ao artigo.
Beleza, este indicador visto no código 01, funciona perfeitamente. Note que estamos utilizando a versão estendida da função OnCalculate. O motivo, para isto, será visto agora. Pois bem, meu caro e estimado leitor. Agora tenho uma pergunta a lhe fazer: Como você poderia colocar uma segunda linha de plotagens no gráfico? Isto a fim de plotar, por exemplo, as mínimas de cada barra. Bem, você poderia me dizer o seguinte: Bastaria criarmos um novo indicador, e modificar o código visto na linha 22. Isto de forma que ao invés de High, usaríamos Low. De fato você estaria correto ao fazer isto. De forma alguma esta ideia é errada, ou poderia ser considerada errada. Já que de fato funciona.
Porém isto faria, com que viéssemos a ter dois indicadores presentes no gráfico. Detalhe: Cada indicador iria trabalhar com uma das linhas de plotagem. No entanto, podemos fazer melhor. Isto por conta do fato de que podemos unir estes dois indicadores em um único código. Mostrar a você, como fazer isto, é o objetivo deste tópico. Sei que pode vir a parecer complicado no início. Mas se você entender o que será mostrado, conseguirá criar qualquer tipo de indicador com múltiplas linhas de plotagem. Lembrando que neste momento, iremos ver a forma mais simples de se fazer isto. Depois, quem sabe, irei mostrar uma forma mais elaborada.
Ok, então com base no código 01, vamos modificar o mesmo, de forma a criar uma segunda linha de plotagem. Vamos fazer isto passo a passo, para que todos consigam de fato acompanhar e entender como fazer.
A primeira coisa que precisamos fazer é criar um novo buffer para conter os novos dados de plotagem. Lembrando que um tipo DRAM_LINE, que é o que estamos utilizando, necessita de um buffer para cada informação de plotagem. Com isto teremos o que é visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_LINE 05. #property indicator_color1 clrBlack 06. //+----------------+ 07. #property indicator_buffers 1 08. #property indicator_plots 1 09. //+----------------+ 10. double gl_buff_max[], 11. gl_buff_min[]; 12. //+------------------------------------------------------------------+ . . .
Código 02
Este código 02, é um fragmento do conteúdo que iremos de fato implementar. Já que estaremos fazendo as coisas passo a passo, fica mais simples desta maneira. Observe que mudei o nome do buffer da linha 10, ao mesmo tempo que adicionei um novo na linha 11. Feito isto, estamos começando a implementar a nossa segunda linha de plotagem. O próximo passo iremos fazer de maneira mais rápida. Já que assim garantimos que tudo estará sendo feito da maneira correta. Então passamos a ter o código visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_LINE 05. #property indicator_color1 clrBlack 06. //+----------------+ 07. #property indicator_buffers 1 08. #property indicator_plots 1 09. //+----------------+ 10. double gl_buff_max[], 11. gl_buff_min[]; 12. //+------------------------------------------------------------------+ 13. int OnInit() 14. { 15. SetIndexBuffer(0, gl_buff_max, INDICATOR_DATA); 16. SetIndexBuffer(1, gl_buff_min, INDICATOR_DATA); 17. 18. return INIT_SUCCEEDED; 19. }; 20. //+------------------------------------------------------------------+ 21. 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 &TickVolume[], const long &Volume[], const int &Spread[]) 22. { 23. for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) 24. { 25. gl_buff_max[c] = High[c]; 26. gl_buff_min[c] = Low[c]; 27. } 28. 29. return rates_total; 30. }; 31. //+------------------------------------------------------------------+
Código 03
Bem, aqui está a parte básica. Porém, este código tem um pequeno problema, que ainda iremos ver como resolver. Mas antes disto, precisamos entender que problema seria este, e por que ele aparece. Observe que na linha 16 estou criando um novo indexador. Cada buffer utilizado no indicador, do qual o MetaTrader 5, terá que manter e observar, necessita de um indexador único. Uma vez que esta linha 16 foi definida, já poderemos utilizar o buffer como mostrado na linha 26.
Este buffer utilizado no sistema de plotagem, podem ter diferentes funções. Por hora, vamos apenas utilizar o tipo, cujo objetivo é o de conter dados a serem utilizados para plotar algo no gráfico. Muito bem, este código 03, pode ser compilado. Porém, ao aplicar ele no gráfico, o resultado é o que vemos logo abaixo.

Imagem 01
Mas o que aconteceu aqui? Não entendi. Por que estamos vendo apenas a linha de plotagem dos valores mínimos? O motivo disto meu caro leitor, é que estamos dizendo para o MetaTrader 5, que o indicador contém apenas um buffer de plotagem e uma informação para ser plotada. Veja isto, sendo declarado nas linhas sete e oito respectivamente. Como temos de fato, dois buffers e duas linhas, tudo que precisamos fazer é modificar aquela mesma informação vista nas linhas mencionadas. Assim sendo, vamos modificar o código, como mostrado logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_LINE 05. #property indicator_color1 clrBlack 06. //+----------------+ 07. #property indicator_buffers 2 08. #property indicator_plots 2 09. //+----------------+ 10. double gl_buff_max[], 11. gl_buff_min[]; 12. //+------------------------------------------------------------------+ . . .
Código 04
Note que mudamos apenas as linhas que foram mencionadas anteriormente. Porém ao aplicar o indicador ao gráfico, o resultado é o que podemos ver logo abaixo.

Imagem 02
De novo isto? Agora que não entendi de vez. Não era para o código plotar duas linhas? Por que estou vendo apenas uma? Calma meu caro leitor. Calma. O motivo de você está vendo apenas uma linha, se deve ao fato de que não existe uma cor de fato sendo aplicada a segunda linha. Para esclarecer isto, veja como está sendo configurado o indicador.

Animação 01
Note que NÃO EXISTE NENHUMA COR PARA A SEGUNDA LINHA. E mesmo tentando atribuir um valor de cor para ela, a mesma não aparece. Para resolver isto, precisamos dizer ao compilador para reservar e criar esta segunda linha. Isto é feito, modificando o código mais uma vez, como mostrado abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_LINE 05. #property indicator_color1 clrRed 06. //+----------------+ 07. #property indicator_type2 DRAW_LINE 08. #property indicator_color2 clrGreen 09. //+----------------+ 10. #property indicator_buffers 2 11. #property indicator_plots 2 12. //+----------------+ 13. double gl_buff_max[], 14. gl_buff_min[]; 15. //+------------------------------------------------------------------+ . . .
Código 05
Observem o que foi adicionado ao código, e que pode ser visto aqui no código 05. Para tornar mais evidente e claro o que estamos fazendo, usei cores diferentes aqui. Assim quando você vier a colocar o indicador no gráfico, poderá finalmente ver o que é mostrado logo abaixo.

Imagem 03
Perceberam como é simples implantar diversas linhas de plotagem em um mesmo indicador? Tudo que você precisa fazer é ir adicionando coisas ao pouco, sabendo o que está fazendo. Como aqui não estamos efetuando nenhum cálculo, as linhas nunca irão se cruzar. Seria mais ou mesmos o que aconteceria caso estivéssemos implementando um indicador de bandas. A diferença, seria que uma das linhas de plotagem receberia valores referentes a uma banda, enquanto a outra linha de plotagem receberia valores da outra banda. Criando assim algo que se pareceria com as famosas bandas de Bollinger. Muito legal este tipo de coisa, não é mesmo?
Acredito que agora, você já conseguirá criar diversos tipos e estilos de indicadores apenas com base neste conhecimento. Mas antes de nos aprofundar ainda mais neste assunto. Já que esta parte sobre a programação é muito interessante e bastante divertida. Que tal modificarmos este mesmo indicador visto na imagem 03, para apresentar as linhas coloridas? Hum, isto parece ser complicado de se fazer. Mas será mesmo algo complicado, ou é você que ainda não sabe como proceder? Bem, vejamos. Mas para isto, vamos a um novo tópico.
Linhas de plotagem coloridas
Uma das coisas que mais chama atenção e deixa muita gente entusiasmada, é o de ver um indicador tendo suas linhas mudando de cor. Até o momento, fizemos apenas um sistema bem simples, onde poderíamos usar uma ou outra cor. Mas mudar de cor? Isto parece ser algo muito difícil de ser feito e implementado. Ainda mais por mim, que estou apenas começando a aprender a programação MQL5. Está certo, meu caro leitor. Mas o fato de você dizer que está apenas começando, não quer dizer que você não possa vir a se interessar pelo que será mostrado. E NÃO. Fazer um indicador cujas linhas a serem plotadas sejam multicoloridas, não é algo complicado de ser feito. Apenas um pouco diferente.
Para você ter uma noção do que estou falando. Vamos pegar o código implementado no tópico anterior. O mesmo para apresentar o resultado visto na imagem 03, precisa conter um conteúdo muito parecido com o mostrado logo abaixo.
//+------------------------------------------------------------------+ #property copyright "Daniel Jose" //+------------------------------------------------------------------+ #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed //+----------------+ #property indicator_type2 DRAW_LINE #property indicator_color2 clrGreen //+----------------+ #property indicator_buffers 2 #property indicator_plots 2 //+----------------+ double gl_buff_max[], gl_buff_min[]; //+------------------------------------------------------------------+ int OnInit() { SetIndexBuffer(0, gl_buff_max, INDICATOR_DATA); SetIndexBuffer(1, gl_buff_min, INDICATOR_DATA); return INIT_SUCCEEDED; }; //+------------------------------------------------------------------+ 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 &TickVolume[], const long &Volume[], const int &Spread[]) { for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) { gl_buff_max[c] = High[c]; gl_buff_min[c] = Low[c]; } return rates_total; }; //+------------------------------------------------------------------+
Código 06
Este código 06, é exatamente, o código resultante de todas aquelas modificações, feitas a partir do código 01, até que pudéssemos plotar duas linhas no gráfico. Agora para tornar aquelas mesmas linhas multicoloridas, tudo que precisamos fazer é seguir um pequeno passo a passo. Começando pelo que é visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_COLOR_LINE 05. #property indicator_color1 clrMaroon, clrTomato, clrBlue 06. //+----------------+ 07. #property indicator_type2 DRAW_COLOR_LINE 08. #property indicator_color2 clrGreen, clrPaleGreen 09. //+----------------+ . . .
Código 07
Agora compare o que era o código 06, com este fragmento que é o código 07. Note que mudamos o tipo de objeto a ser usado na plotagem, saindo do tipo DRAW_LINE para o tipo DRAW_COLOR_LINE. Uma vez tendo feito isto, podemos na propriedade de cor de cada uma das linhas indicar mais de uma cor a ser utilizada. A quantidade de cores é totalmente arbitrária, podendo ser de no máximo 64 valores, segundo a própria documentação do MQL5. Isto tanto é verdade que em uma linha, declarei três cores e na outra duas cores. Mas você pode colocar quantas cores desejar. Porém, somente fazer isto, não basta. Precisamos implementar mais algumas coisas, a fim de que o MetaTrader 5, consiga entender o que planejamos de fato fazer.
Agora preste atenção, meu caro leitor. Quando estamos utilizando um sistema de plotagem multicolorida, precisamos de um buffer extra. Isto pode ser visto na imagem logo abaixo, presente na documentação.

Imagem 04
Observe que todos estes pontos destacados exigem a presença de um buffer para a cor. Sem este buffer, o MetaTrader 5, NÃO SABERÁ QUER COR UTILIZAR. Por conta disto a próxima mudança a ser feita, será no que se refere à declaração dos buffers. Isto pode ser visto sendo feito no fragmento de código visto logo abaixo.
. . . 09. //+----------------+ 10. #property indicator_buffers 4 11. #property indicator_plots 2 12. //+----------------+ 13. double gl_buff_max[], 14. gl_buff_min[], 15. gl_color_max[], 16. gl_color_min[]; 17. //+------------------------------------------------------------------+ . . .
Código 08
Agora com este fragmento visto no código 08, de fato estamos definindo o que seria os nossos buffers. Note que na linha dez estamos informando que precisamos de quatro buffers. Mas por que quatro, sendo que iremos plotar duas linhas? O motivo é que precisamos de um buffer para os valores a serem plotados e outro para cada cor. Pense em uma pequena estrutura de dois valores. O MetaTrader 5 não utiliza uma estrutura para isto. Mas você precisa pensar desta maneira. E por conta deste motivo, do MetaTrader 5, não usar estruturas para tal modelagem, acabamos necessitando de dois buffers. No entanto, como temos duas linhas a serem plotadas, no final precisaremos de quatro buffer. Os mesmos estão sendo declarados a partir da linha treze, como você pode notar no fragmento visto no código 08.
Legal, agora só falta implementarmos o último passo. Este é visto no fragmento logo abaixo.
. . . 17. //+------------------------------------------------------------------+ 18. int OnInit() 19. { 20. SetIndexBuffer(0, gl_buff_max, INDICATOR_DATA); 21. SetIndexBuffer(1, gl_color_max, INDICATOR_COLOR_INDEX); 22. SetIndexBuffer(2, gl_buff_min, INDICATOR_DATA); 23. SetIndexBuffer(3, gl_color_min, INDICATOR_COLOR_INDEX); 24. 25. return INIT_SUCCEEDED; 26. }; 27. //+------------------------------------------------------------------+ 28. 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 &TickVolume[], const long &Volume[], const int &Spread[]) 29. { 30. double mhs = 0, 31. mhi = 0, 32. ml = 0; 33. const double desv = 0.01; 34. 35. for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) 36. { 37. gl_color_max[c] = (mhi > High[c] ? 0 : (mhs < High[c] ? 1 : 2)); 38. mhs = mhi = gl_buff_max[c] = High[c]; 39. mhs += (mhs * desv); 40. mhi -= (mhi * desv); 41. gl_color_min[c] = (ml < Low[c] ? 0 : 1); 42. ml = gl_buff_min[c] = Low[c]; 43. } 44. 45. return rates_total; 46. }; 47. //+------------------------------------------------------------------+
Código 09
Antes de explicar o que estamos fazendo neste fragmento que é visto no código 09. Vamos ver o resultado deste indicador quando aplicado ao gráfico de um ativo qualquer. Isto pode ser visto na imagem logo na sequência.

Imagem 05
Isto que você está vendo, meu caro leitor, é apenas para fins de demonstração. Já que não existe nenhum tipo de objetivo na criação deste indicador. Apenas fins didáticos. Porém você pode notar que o código presente na etapa de inicialização do indicador, quase não mudou. Precisando apenas que fosse adicionadas as linhas 21 e 23. Porém, toda via e, entretanto, é muito importante você entender, o que cada uma destas novas linhas, estão de fato fazendo. Para começar, observe que cada um dos buffers, tem um index diferente. Não importa o tipo de coisa que iremos colocar neles. Cada um, precisa ter um index diferente. Caso contrário, o MetaTrader 5, irá ficar confuso quando os for utilizar.
Depois, muito importante declarar as coisas em uma certa ordem. Ou seja, ANTES de declarar o próximo buffer de dados, devemos declarar todos os buffers a ser utilizados naquela linha de plotagem. No caso será um buffer de cor. Se você quiser ou tentar declarar todos os buffers de dado ou de cor fora de uma ordem lógica. NÃO IRÁ obter o resultado desejado. Por isto preste atenção, no momento de declarar as coisas aqui. A ordem das coisas interfere no resultado final. Uma vez que tenhamos inicializado isto, podemos focar na rotina que irá tratar o evento Calculate, que será disparado pelo MetaTrader 5.
Note que neste caso estamos fazendo alguns cálculos e verificações ali. Isto por que, precisamos dizer ao MetaTrader 5, qual daquelas cores que definimos lá no código 07, deverá ser utilizada no momento de desenhar a linha na tela. Mas espere um pouco aí. Não estou entendendo como isto está sendo feito. Aqui temos apenas números e lá no código 07, tínhamos valores de cor. Como o MetaTrader 5, sabe que cor utilizar?
Certo, meu caro leitor, neste momento é importante, que você tenha compreendido uma outra coisa, que foi explicado em outro artigo. Que são arrays. O que temos ali no código 07, são arrays de cores. Cada uma delas, estaria em um index do array. Por conta deste fato, é que nas linhas 21 e 23, estamos utilizando a enumeração INDICATOR_COLOR_INDEX. Isto porque, NÃO ESTAMOS DIZENDO QUE COR USAR. Mas sim, qual o index da cor, dentro de um determinado array. Mas que array? Se temos dois presentes no código 07? Como o MetaTrader 5 sabe qual utilizar?
É aí que entra a outra questão que mencionei a pouco. Ou seja, a ordem das coisas influência no resultado final. Como normalmente estaremos utilizando este tipo de plotagem, de maneira singular, ou seja, um indicador, uma linha de plotagem. O MetaTrader 5, irá utilizar o esquema de cor, que esteja diretamente relacionado ao index do tipo a ser plotado. Sei que pode parecer confuso. Mas note que nas linhas quatro e cinco temos um valor de index, no caso um. Já nas linhas sete e oito, um outro index, no caso dois. Assim, quando estivermos associando um valor ao indicador a ser plotado, o compilador irá utilizar aquele index para saber que esquema de cor deverá ser utilizado.
E justamente para mostrar isto, que defini quantidades diferentes de cor em cada uma das declarações vistas no código 07. Para que você pudesse entender isto, quando vier a experimentar e praticar no código real.
Apesar desta parte ser um tanto quanto confusa, justamente por estarmos usando tudo de modo estático e colocando mais um uma linha de plotagem ao mesmo tempo. Na prática, você irá notar que é bem simples de entender como declarar e utilizar este tipo de coisa.
De qualquer maneira, no final, quando o usuário vier a desejar mudar o esquema de cores, ele irá ter acesso a uma interface como mostrado logo abaixo.

Imagem 06
Perceba o fato de que agora, devido as declarações feitas nas linhas cinco e oito do código 07, o usuário, terá mais de uma cor podendo ser ajustada. Por isto é desejável que a interface seja a mais clara e simples possível. Caso contrário, o usuário terá uma má experiência ao utilizar seu código, mesmo quando ele poderia ser bastante útil, para um dado tipo de operacional.
Como os códigos estarão no anexo, você poderá estudar como lidar com este tipo de situação. Mas antes de terminamos este artigo, quero explicar sobre um outro indicador. Que de certa forma fica entre um e outro termo dependendo da forma como você vier a implementar o mesmo. Podendo ser um indicador de bandas ou mesmo um indicador de cruzamento de médias. Mas para separar a explicação. Vamos ver isto em um novo tópico.
Indicador do tipo DRAW_FILLING
Este tipo de indicador é bastante curioso. Já que dependendo da forma como você o implementar, poderá obter um indicador de cruzamento de médias, ou até mesmo um indicador de bandas. Mas no geral ele costuma gerar uma certa dúvida por parte de alguns programadores iniciante, justamente devido a forma como o mesmo precisa ser declarado. Para que você, meu caro leitor, de fato consiga compreender, como é simples declarar e utilizar este tipo de indicador. Vamos tomar como base o código 06. Visto lá no início deste artigo. Isto porque, partindo daquele princípio, será bem mais fácil entender o que estamos tentando fazer, com este indicador DRAW_FILLING.
Uma vez tendo o código 06, como ponto inicial, vamos modificar o mesmo a fim de conseguir entender o indicador DRAW_FILLING. Basicamente o código 06 irá ficar como mostrado logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_FILLING 05. #property indicator_color1 clrRed, clrGreen 06. //+----------------+ 07. #property indicator_buffers 2 08. #property indicator_plots 1 09. //+----------------+ 10. double gl_buff_max[], 11. gl_buff_min[]; 12. //+------------------------------------------------------------------+ 13. int OnInit() 14. { 15. SetIndexBuffer(0, gl_buff_max, INDICATOR_DATA); 16. SetIndexBuffer(1, gl_buff_min, INDICATOR_DATA); 17. 18. return INIT_SUCCEEDED; 19. }; 20. //+------------------------------------------------------------------+ 21. 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 &TickVolume[], const long &Volume[], const int &Spread[]) 22. { 23. for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) 24. { 25. gl_buff_max[c] = Open[c]; 26. gl_buff_min[c] = Close[c]; 27. } 28. 29. return rates_total; 30. }; 31. //+------------------------------------------------------------------+
Código 10
Hum. Interessante. Basicamente e até onde consigo notar o código 06, foi muito pouco modificado. Mas estou com dúvida em relação a algumas questões aqui. Como por exemplo: Por que na rotina que trata o evento Calculate, estamos usando o preço de abertura e fechamento? Bem, o motivo para isto, é justamente causar uma torção ou cruzamento dos valores, de máxima e mínima. Como estão sendo chamados aqui no código 10. Observe o seguinte meu caro leitor, de vez em quando temos uma barra de venda e de vez em quando uma de compra.
Agora pense neste indicador DRAW_FILLING, como sendo um tecido. Onde temos um lado com uma estampa e o lado oposto com outra estampa. Quando os valores de dentro dos buffers definidos nas linhas 15 e 16 cruzam. Temos uma torção, que faz com que o MetaTrader 5, nos mostre um lado ou outro do tecido. A informação a ser mostrada, ou estampada no tecido, está sendo declarada na linha cinco. Por conta disto, podemos pintar uma região de uma cor ou de outra. Caso o cruzamento, ou torção não ocorresse, iriamos ver apenas uma das estampas, ou cor que esteja definida na linha cinco.
Contudo, existe um pequeno detalhe aqui, apesar da extrema simplicidade do código 10, quando o aplicamos a um gráfico, o mesmo irá ficar como mostrado na imagem logo abaixo.

Imagem 07
Ok, não parece muito legal, sendo de alguma forma bastante confuso dependendo do tipo de informação que estejamos calculando e plotando no gráfico. Contudo, o usuário, por conta da linha cinco, terá a possibilidade de ajustar algumas informações como pode ser visto na imagem logo na sequência.

Imagem 08
Ou seja, dependendo do tipo de coisa que venha a ser planejada, este indicador do tipo DRAW_FILLING pode vir a ser bastante interessante. Porém devido a justamente o que pode ser visto na imagem 07, o mais comum, não é plotar este indicador diretamente no gráfico principal. Mas sim em uma janela a parte. Então você logo começa a pensar: Cara, isto está ficando muito confuso e complicado. Eu mal aprendi como criar um indicador colorido, e lá vem você em falar em colocar o indicador em outra janela? Assim você acaba comigo com tanta informação que vou precisar aprender.
Calma, não é para tanto. Na verdade, o MQL5, tendo sido pensado para ser utilizado como meio de programar para o MetaTrader 5. Nos fornece alguns recursos bem interessantes e outros que por sua vez é bastante prático e fácil de ser utilizado.
Entre estes recursos está justamente o de colocar um indicador em outra janela. Porém esta janela irá se manter ligada a janela principal. Uma das formas mais simples e fáceis de se fazer isto. É dizer ao compilador para gerar um código de indicador, de forma que quando o MetaTrader 5, o for aplicar o mesmo no gráfico. Ele, perceba que deverá abrir uma nova janela, ou sub janela, como é de praxe dizer. Isto é feito, adicionando uma única linha no código do indicador. Assim, o mesmo código 10 visto acima, agora irá ficar como mostrado logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_separate_window 05. //+----------------+ 06. #property indicator_type1 DRAW_FILLING 07. #property indicator_color1 clrRed, clrGreen 08. //+----------------+ 09. #property indicator_buffers 2 10. #property indicator_plots 1 11. //+----------------+ 12. double gl_buff_max[], 13. gl_buff_min[]; 14. //+------------------------------------------------------------------+ 15. int OnInit() 16. { 17. SetIndexBuffer(0, gl_buff_max, INDICATOR_DATA); 18. SetIndexBuffer(1, gl_buff_min, INDICATOR_DATA); 19. 20. return INIT_SUCCEEDED; 21. }; 22. //+------------------------------------------------------------------+ 23. 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 &TickVolume[], const long &Volume[], const int &Spread[]) 24. { 25. for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) 26. { 27. gl_buff_max[c] = Open[c]; 28. gl_buff_min[c] = Close[c]; 29. } 30. 31. return rates_total; 32. }; 33. //+------------------------------------------------------------------+
Código 11
Observe que a única e real diferença entre o código 10 e o código 11, é justamente a linha quatro que não existe no código 10, porém existe neste código 11. Depois de compilar este código. Você poderá pedir ao MetaTrader 5 para o adicionar ao gráfico. Ao fazer isto, aquela mesma imagem 07, que antes poderia acabar ficando bastante confusa. Passará agora a ficar como visto logo abaixo.

Imagem 09
Definitivamente esta imagem 09 é muito mais simples de ser entendida. Mesmo que a princípio, um ou outro usuário, possa vir a ficar um tanto quanto confuso a respeito de como ler este gráfico.
Considerações finais
Neste artigo, foi demonstrado como trabalhar com dois tipos de indicadores diferentes. Sendo que você os poderá adaptar de diversas e diferentes formas possíveis. Isto a fim de criar algum tipo de aplicação que você venha a desejar construir para objetivos particulares. Apesar da aparente simplicidade envolvida no que foi mostrado aqui. Creio que você, caso tenha bastante criatividade e senso de curiosidade. Irá perceber que este conteúdo pode ser estendido aos demais tipos de indicadores. Como o DRAW_SECTION, DRAW_HISTOGRAM, DRAW_ARROW, DRAW_ZIGZAG, DRAW_BARS e DRAW_CANDLES. Todos eles funcionam da mesma maneira que estes visto neste artigo. Apesar de termos lidados apenas com dois. Três se contarmos o fato de que usamos o tipo DRAW_COLOR_LINE. Mas isto é um mero detalhe.
O que realmente importa é que você consiga praticar e entender que, tudo que está sendo plotado no gráfico. Por mais complicado que possa parecer. É na verdade bastante simples de ser construído. Basicamente você apenas precisa dizer ao compilador como deverá ser criado o indicador. Usando basicamente uma implementação totalmente estática. No entanto, apesar de ser simples, fácil, prático e divertido criar indicadores estáticos. A verdadeira diversão mora mesmo é nos indicadores dinâmicos. Mas este iremos ver em breve. Por hora procure estudar e praticar o que foi visto aqui neste artigo. Pois em breve iremos tornar este tipo de implementação bem mais divertida e interessante.
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.
Simulação de mercado (Parte 13): Sockets (VII)
Algoritmo do Campo Elétrico Artificial — Artificial Electric Field Algorithm (AEFA)
Redes neurais em trading: Segmentação de dados com base em expressões de referência
Redes neurais em trading: Modelo de dupla atenção para previsão de tendências
- 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