Do básico ao intermediário: Indicador (IV)
Introdução
No artigo anterior Do básico ao intermediário: Indicador (III), vimos como poderíamos criar qualquer tipo de indicador de uma forma muito simples, fácil e bastante prática. Isto fazendo uso de diretivas de compilação. Porém nem sempre podemos fazer, ou precisamos fazer as coisas daquela maneira. Aquele tipo de abordagem, é chamada de implementação estática. Já que uma vez definido o tipo de indicador, não podemos, ou melhor dizendo, não permitimos ao usuário trocar o tipo de plotagem a ser feita.
No entanto, indicadores podem ser muito mais do que aquilo que tem sido mostrado ou visto até este momento. É bem verdade que para uma ampla e imensa faixa de atividades, aquele tipo de implementação já será mais que o suficiente. Porém, toda via e, entretanto, existem situações em que podemos precisar de indicadores um pouco diferentes para operar ou analisar o mercado.
Aqui neste artigo, iremos aprender e compreender como criar alguns indicadores um pouco quanto diferentes. Isto por que, eles servem muito bem, para nos auxiliar, na comunicação com outros operadores. Ao mesmo tempo que nos permite analisar certos tipos de movimentação de modo um pouco mais automatizado. Se é que podemos dizer assim.
Então vamos começar com um bem simples e que ao meu ver é bem divertido. Isto por conta, que você consegue criar diversos outros utilizando um conceito muito simples e bastante fácil de entender.
Indicador de Inside bar
Existe um tipo de indicador, ou melhor, metodologia de operação, que faz o uso do que é conhecido como inside bar. Um inside bar, seria literalmente falando, uma barra, ou candle, que fica dentro de outro imediatamente anterior. Apesar de que, dependendo do operador e do ativo. Pode-se considerar um inside bar, toda e qualquer barra que esteja dentro de uma outra, não imediatamente anterior. Podendo esta estar a uma certa distância. Desde que o movimento não tenha violado esta mesma barra. Apesar de esta última forma de considerar algo como sendo um inside bar, não ser de fato, um princípio adotado na maior parte dos operadores.
Outros a considera algo válido. De qualquer forma, existe esta metodologia de operação, sendo muito assertiva em diversos momentos. Porém analisar o gráfico o tempo todo, buscando saber se estamos ou não tendo um inside bar, é no mínimo uma tarefa bem complicada para muita gente. Principalmente iniciantes. Por conta disto, podemos fazer uso de um indicador, que irá acompanhar o gráfico, a fim de nos mostrar a presença ou não de tal construção, isto quando o gráfico estiver aberto e ativo.
Detalhe: Um inside bar, NÃO É necessariamente, um DOJI.
Ok, mas por que você decidiu mostrar como criar este indicador? O motivo para isto é bem simples, meu caro leitor. Muitos iniciantes tentam criar indicadores, a fim de conseguir adicionar padrões de cores em candles ou barras, como alguns costumam chamar os candles. E tais programadores iniciantes, acabam desistindo por conta da questão relacionada, a forma como o indicador precisa ser declarado. Não que seja uma tarefa difícil de ser feita, criar um padrão de cores em candles. O problema é outro. Criar o indicador em si, de fato, é uma tarefa bastante simples, como você já deve estar imaginando.
No entanto, assim como acontece com outros indicadores que foram mostrados nos artigos anteriores. Precisamos tomar cuidado no momento em que estivermos declarando os buffers. Se você já tentou criar um padrão de cores em candles, sabe muito bem que isto pode ser desafiador, para todo iniciante. Então, se fizermos isto na ordem errada, ou indicarmos o index dos buffers na sequência errada, o MetaTrader 5, irá plotar algo que não é exatamente o que esperávamos ver no gráfico. E a culpa, não poderá recair nem no MetaTrader 5, tão pouco no programador. Já que dependendo do que se queira implementar, o que para uns será considerado um erro, para outros, será exatamente o resultado desejado.
Sendo assim, vamos começar vendo como seria a declaração do indicador propriamente dito. Isto antes mesmo de criarmos o indicador de inside bar. Normalmente você, pode imaginar que poderia declarar as coisas de qualquer maneira. Como é visto no código logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #property indicator_type1 DRAW_COLOR_CANDLES 05. #property indicator_color1 clrRed, clrRoyalBlue, clrGreen 06. //+----------------+ 07. #property indicator_buffers 5 08. #property indicator_plots 1 09. //+----------------+ 10. double gl_Buff_High[], 11. gl_Buff_Open[], 12. gl_Buff_Close[], 13. gl_Buff_Low[], 14. gl_Buff_Color[]; 15. //+------------------------------------------------------------------+ 16. int OnInit() 17. { 18. SetIndexBuffer(0, gl_Buff_High, INDICATOR_DATA); 19. SetIndexBuffer(1, gl_Buff_Open, INDICATOR_DATA); 20. SetIndexBuffer(2, gl_Buff_Close, INDICATOR_DATA); 21. SetIndexBuffer(3, gl_Buff_Low, INDICATOR_DATA); 22. SetIndexBuffer(4, gl_Buff_Color, INDICATOR_COLOR_INDEX); 23. 24. return INIT_SUCCEEDED; 25. }; 26. //+------------------------------------------------------------------+ 27. 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[]) 28. { 29. for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) 30. { 31. gl_Buff_High[c] = High[c]; 32. gl_Buff_Open[c] = Open[c]; 33. gl_Buff_Close[c] = Close[c]; 34. gl_Buff_Low[c] = Low[c]; 35. 36. gl_Buff_Color[c] = (Open[c] > Close[c] ? 0 : 2); 37. } 38. 39. return rates_total; 40. }; 41. //+------------------------------------------------------------------+
Código 01
Agora lhe pergunto, meu caro leitor, isto que você vê no código 01. Está certo ou errado? Pois bem, a resposta correta para esta questão é: Depende do objetivo que você está procurando obter. Mas de qualquer forma, esta implementação, vista no código 01, definitivamente está longe de estar completamente errada. Já que o código irá ser compilado e você o poderá utilizar. Mas como eu disse, dependendo do objetivo a ser alcançado, pode ser que este código de fato, esteja errado. Então preste atenção, no que irá acontecer, quando você vier a utilizar este código em um gráfico qualquer. Isto pode ser visto, na animação logo abaixo.

Animação 01
Ou seja, o resultado não, exatamente como o esperado. Mas por que? Não entendi. Aparentemente o código está correto. Não fiz absolutamente nada de errado no momento de declarar os buffers. Mas mesmo assim o resultado não foi como esperado, já que as barras, ou candles mudaram o seu formato, e não apenas a cor. Definitivamente não consigo entender onde está o erro. Será que existe algum tipo de macete, para as coisas venham a de fato funcionar e apresentar o resultado desejado? Neste caso sim, meu caro leitor.
Você pode ver que mesmo o código, estando correto. Já que ele de fato mudou a cor das barras como era esperado. O mesmo não podemos dizer a respeito da mudança no formato das barras. Se o objetivo fosse mudar as cores e ao mesmo tempo mudar as barras, ok. Mas não era isto que pretendíamos. E o motivo para isto, é justamente o fato de que a ordem com que os buffers, foram declarados está incorreta. Assim quando o MetaTrader 5, vier a utilizar os buffers, ele os irá utilizar em uma certa ordem. Com esta ordem está errada, o formato das barras foi alterado. Sabendo disto, tudo que precisamos fazer será mudar esta ordem, para uma ordem que seja adequada. Esta simples mudança, que precisa ser feita, pode ser observada no código abaixo.
. . . 18. SetIndexBuffer(1, gl_Buff_High, INDICATOR_DATA); 19. SetIndexBuffer(0, gl_Buff_Open, INDICATOR_DATA); 20. SetIndexBuffer(3, gl_Buff_Close, INDICATOR_DATA); 21. SetIndexBuffer(2, gl_Buff_Low, INDICATOR_DATA); . . .
Código 02
Observe, que neste fragmento mostrado no código 02, a única coisa que foi feita, é a mudança no valor do index de cada buffer. Usando esta sequência de buffers, ou seja, preço de abertura, máxima, mínima, e preço de fechamento. O resultado, que será gerado pelo mesmo código 01, pode ser observado logo abaixo.

Animação 02
Notaram como agora o MetaTrader 5, conseguiu entender como cada barra, ou candle, deveria ser desenhada? Este é um tipo de problema muito simples, para quem já sabe como fazer. Porém para quem não entende, isto é definitivamente a coisa mais complicada e difícil que existe. De qualquer maneira, agora, você meu caro e estimado leitor, já sabe como fazer tal coisa. Podendo assim, começar a construir padrões de cores a fim de criar indicadores para modelar este ou aquele sistema de trade. Então para demonstrar como podemos fazer isto, vamos olhar de como resolver e indicar um inside bar, diretamente no gráfico.
Para resolver esta questão, observe na linha 36, como estamos calculando o index da cor. Ela será o index zero, para o que seria uma barra de venda, ou index dois, para indicar o que seria uma barra de compra. Mas e o index um, para que ele irá nos servir? Bem, este index, estamos reservando para ser utilizado pelo que seria um inside bar.
Agora vem o ponto chave. O laço da linha 29, começa em um ponto antigo, que pode ou não ser a primeira barra do gráfico. E vai caminhando até encontrar o que seria a barra mais recente presente no gráfico. É importante saber e entender disto. Pois um inside bar, somente pode ser indicado, caso exista uma barra anterior com uma certa característica. Caso contrário, a barra atual, não poderá ser considerada, ou mostrada no gráfico como sendo ou não um inside bar.
Ok, entendido isto, tudo que precisamos fazer agora, é implementar o que seria o critério de verificação. Para isto, precisamos mudar, ou melhor incrementar algo no código visto anteriormente. Já que conseguimos dar cor as barras, ou candles. Porém ainda não estamos testando a presença ou não do tal inside bar. Este incremento que precisa ser feito, é visto no fragmento de código 03, logo abaixo.
. . . 36. gl_Buff_Color[c] = (Open[c] > Close[c] ? 0 : 2); 37. if ((c - 1) > 0) 38. gl_Buff_Color[c] = ((High[c - 1] > High[c]) && (Low[c - 1] < Low[c]) ? 1 : gl_Buff_Color[c]); 39. } 40. 41. return rates_total; 42. }; 43. //+------------------------------------------------------------------+
Código 03
Agora sim, a cada evento Calculate que nosso indicador receber, iremos verificar se estamos ou não com um inside bar presente no gráfico. Mas espere um pouco. Por que testar este tipo de coisa a todo instante? O motivo é simples meu caro leitor, durante uma fase de negociação, pode ser que de fato exista um inside bar presente no gráfico. No entanto, pode acontecer e não é raro, que ele venha a ser desconfigurado. Isto por que somente podemos considerar sendo ou não um inside bar. Depois que o fechamento da barra, ou candle de fato tenha ocorrido. Antes disto é prematuro afirmar que temos um inside bar no gráfico.
Porém como a linha 38 irá verificar de tempos em tempos se a condição de inside bar, pode ou não ser aplicada. Acaba que no final, caso a barra venha a desconfigurar o inside bar, o teste não irá passar. Com isto, devido ao fato de já termos atualizado antes a cor na linha 36. Acaba que a indicação que antes existia deixa de ser mostrada no gráfico.
Apesar de saber que funciona, o ideal será que você realmente veja isto ocorrendo na prática. Isto para entender por que fiz a implementação desta maneira. De qualquer forma, na animação logo abaixo, podemos ver como o processo inicial acontece. Apenas não é fácil mostrar este segundo passo, que é a desconfiguração do que seria um inside bar. Já que isto necessitaria de um momento muito específico e demanda tempo para gravar o ponto exato. Mas a animação abaixo, já lhe dará alguma ideia de como o processo acontece.

Animação 03
Perfeito, aqui temos a indicação do que seria um inside bar. Mas como foi dito, existem operadores que observam diversas barras, e enquanto as novas barras estiverem dentro da anterior, consideram todas estas novas barras como sendo um inside bar. E é aí que vem a pergunta: Como poderíamos implementar este mesmo tipo de indicador? Apenas modificando o indicador anterior?
Esta é uma questão, que pode ter diversas respostas diferentes, ou melhor dizendo, formas diferentes de implementar o mecanismo envolvido. O real problema, não é exatamente implementar o código, mas sim o de bolar uma forma de manter um valor por um longo período. Aqui irei mostrar uma possível proposta. Claro que dependendo do caso, você pode usar outra que vier achar mais interessante ou adequada.
Legal, então como quero deixar as coisas o mais simples possível. Irei utilizar uma mudança apenas no que se refere a implementação do tratador de eventos OnCalcualate. Com isto, o código original que criou a animação 03, será modificado como mostrado no fragmento logo abaixo.
. . . 26. //+------------------------------------------------------------------+ 27. 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[]) 28. { 29. static double high = DBL_MIN, 30. low = DBL_MAX; 31. 32. for (int c = (prev_calculated > 0 ? prev_calculated - 1 : 0); c < rates_total; c++) 33. { 34. gl_Buff_High[c] = High[c]; 35. gl_Buff_Open[c] = Open[c]; 36. gl_Buff_Close[c] = Close[c]; 37. gl_Buff_Low[c] = Low[c]; 38. 39. gl_Buff_Color[c] = (Open[c] > Close[c] ? 0 : 2); 40. if ((c - 1) > 0) 41. { 42. high = (High[c - 1] > high ? High[c - 1] : high); 43. low = (Low[c - 1] < low ? Low[c - 1] : low); 44. gl_Buff_Color[c] = ((high > High[c]) && (low < Low[c]) ? 1 : gl_Buff_Color[c]); 45. if (gl_Buff_Color[c] != 1) 46. { 47. high = DBL_MIN; 48. low = DBL_MAX; 49. } 50. } 51. } 52. 53. return rates_total; 54. }; 55. //+------------------------------------------------------------------+
Código 04
Agora preste atenção meu caro leitor. Quando este fragmento mostrado no código 04, for colocado no código que estava gerando a animação 03. O resultado será, ou poderá ser diferente, do observado na animação anterior. Para que isto de fato fique evidente, observe atentamente e compare a animação abaixo com a anterior.

Animação 04
Nesta animação 04, estamos fazendo exatamente o que muitos operadores podem vir a considerar um inside bar. Ou seja, enquanto não vir a existir ou ocorrer uma violação da máxima ou mínima da barra, ou candle anterior, estaremos considerando a barra atualmente analisada como sendo um inside bar. Sei que isto parece muito confuso, ainda mais se você não tem costume de operar ou observar inside bar. Mas de fato, este fragmento visto no código 04, consegue reconhecer o padrão, mesmo que diversas barras venham a surgir e todas estejam dentro de uma barra bem mais antiga.
Mas então, como este fragmento mostrado no código 04, funcionam? E como ele consegue detectar um inside bar desta forma como é mostrado na animação 04? Para entender isto, meu caro leitor, primeiro você precisa entender como o indicador anterior e mais simples funciona. Somente assim conseguirá entender este daqui. Além disto, você precisa entender como variáveis estáticas trabalham. Como já foi feito um artigo voltado a explicar apenas e somente esta questão no passado. Vou considerar que você já tenha compreendido esta questão sobre variáveis estática.
Para que não leu o artigo, ele pode ser encontrado em Do básico ao intermediário: Variáveis (II). Agora observando o código 04, você claramente pode notar que a mudança necessária precisou ser feita justamente dentro do que se refere ao teste de inside bar. O tal teste ainda continua sendo feito ali. Porém ele mudou de posição, sendo que agora, antes de ele acontecer, temos dois outros testes ocorrendo. O primeiro é feito na linha 42, ali é onde verificamos se houve ou não a violação da máxima. Já na linha 43, fazemos uma verificação similar, só que neste caso, estaremos testando a violação da mínima. Com isto, temos de fato o limite no qual um inside pode existir entre diversas barras diferentes. Não apenas na imediatamente anterior. Somente depois de conhecer estes limites é que verificamos se existe ou não um inside bar na barra atualmente analisada. E isto é feito na linha 44.
A parte importante, é a linha 45. Ali checamos se o teste da linha 44, denunciou ou não a presença de um inside bar. Caso não tenhamos um inside bar, precisamos destruir os limites atualmente impostos. Isto para que venhamos a procurar a presença da formação de um novo padrão de inside bar. Sem que este teste da linha 45 ocorresse, teríamos falsas indicações sendo dadas a todo momento.
Agora, para que você possa entender algo sobre esta questão do indicador inside bar, que mostrei aqui. Veja a animação logo abaixo.

Animação 05
Aqui nesta animação 05, vemos algo muito interessante, que é justamente o fato de que um inside bar, existia em um dado momento. Porém, como ocorreu a violação, no caso a mínima foi violada. O que antes era um inside bar deixou de ser, passando agora a ser uma barra como todas as demais. E mesmo que o preço venha a voltar a ponto de que poderíamos voltar a pensar que teríamos um inside bar. O indicador não irá mostrar isto, como você pode observar na imagem logo abaixo.

Imagem 01
Perceba que de fato, o ativo voltou a ser negociado dentro da barra, ou candle que gerou três indicações passadas de inside bar. Porém, para os critérios implementados no indicador. Esta última barra, ou candle, já não seria, ou poderia ser considerada um inside bar. Resumo da ópera: O indicador de fato funciona. Mas precisamos definir e deixar bastante claros, os critérios a serem adotados para que ele nos forneça a informação adequada e desejada.
Muito bem, considero explicado de maneira adequada como implementar indicadores de cores em candles. Então podemos ver outras questões, estas podem ou não estar relacionadas a indicadores. Porém, devido à natureza do próprio conceito do que seria ou não um indicador. Creio ser adequado mostrar algumas outras coisas neste mesmo tipo de cenário e assunto.
O que ver e o que não ver
Não é raro termos perfis diferentes, para uma mesma metodologia de operação no mercado. Alguns operadores gostam de ter diversas informações sendo mostradas tempo todo no gráfico. Já outros, preferem ter um mínimo de informações. Saber o que mostrar ou não, é algo particular de cada operador ou perfil operacional. No entanto, para nós programadores, isto é algo completamente irrelevante. Não devemos, e não nos importamos como cada um prefere ter seu gráfico configurado. Tudo que importa, é fornecer meios simples e fáceis, a fim de qualquer pessoa possa ajustar o gráfico, conforme seu interesse pessoal.
Ok, o MetaTrader 5, nos permite configura muitas destas coisas, sem necessidade de nenhuma aplicação extra ou externa. Porém, existem elementos dos quais, não é possível remover, ou modificar, pelos meios que são ofertados pelo MetaTrader 5. E é neste ponto que a programação entra de fato. Você, meu caro leitor, como programador, precisa entender que NÃO EXISTE LIMITES para o que podemos ou não fazer. O que de fato existe, é a maior ou menor capacidade técnica de cada programador em particular. Alguns conseguirão fazer as coisas de maneira mais simples, enquanto outros necessitarão de meios, ou meu ver, mais complicados.
De qualquer maneira o objetivo é sempre tentar conseguir desenvolver uma aplicação que consiga tornar o gráfico, naquilo que queremos. Mesmo que seja uma bagunça completa, na visão de outros operadores. Mas se você, o está compreendendo é consegue ganhar dinheiro operando. Ok, é isto que realmente vale.
Pois bem, usando o MQL5, podemos definir diversas coisas e controlar diversos elementos no gráfico. Para começar, vamos fazer algumas pequenas mudanças bastante simples. Que podem ou não ser interessantes em alguns momentos. Mas o objetivo é mostrar que, ao usarmos o MQL5, teremos total liberdade e controle sobre qualquer coisa presente em um gráfico. Por exemplo: Você sabia que podemos remover aquela região onde podemos observar a cotação e o horário, de um gráfico? Bem, se você tentar fazer isto diretamente, pelo MetaTrader 5, não irá conseguir obter sucesso. Porém, uma das maneiras de se fazer isto é via código. E o código a ser implementado é bastante simples diga-se de passagem. Então vamos começar por este ponto. O código inicial é visto logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. int OnInit() 05. { 06. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, false); 07. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false); 08. 09. return INIT_SUCCEEDED; 10. }; 11. //+------------------------------------------------------------------+ 12. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 13. { 14. return rates_total; 15. }; 16. //+------------------------------------------------------------------+
Código 05
Note o nível de simplicidade adotado aqui, neste código 05. Sem precisar explicar absolutamente nada, você nitidamente consegue entender o que estamos fazendo aqui. Tanto que ao executar este código em um gráfico, você ter como resultado o que é mostrado na animação logo abaixo.

Animação 06
Claro que aqui estamos sendo muito mal educados. Já que, depois de termos removido, sem pedir a autorização do usuário, tanto a escala de preço, quanto a escala de tempo. Não a estamos devolvendo, ao gráfico. Mesmo quando o indicador venha a ser retirado do gráfico. E fazer está tipo de coisa, apesar de parecer adequado para muitos, é considerado por outros como uma falta de educação por parte da aplicação. Já que para reaver as escalas de preço e tempo, precisaremos fechar o gráfico e reabrir o mesmo. Não sendo de fato, algo que muitos iriam gostar de fazer.
Mas aí surge uma pergunta: Como poderíamos devolver o status original do gráfico? E se podemos, qual seria o melhor momento de se fazer isto? Bem, meu caro leitor, de fato existe formas de se fazer isto. Que é via captura do evento Deinit. Porém, é necessário que você entenda o seguinte: Não existe um melhor momento de se fazer isto. Existe sim um momento mais propicio. Digo isto, pois pode acontecer de sua aplicação vir a cometer algo, que force o MetaTrader 5 a remover do gráfico. E caso isto venha a acontecer, o evento Deinit, não será de fato utilizado. Já que a remoção será feita na marra, por assim dizer. Desta forma, toda e qualquer modificação que sua aplicação tiver efetuado, irá permanecer no gráfico. Sendo necessário fechar e abrir o mesmo, para que tudo volte ao normal.
Por conta disto, tais mudanças devem ser feitas sempre tomando os devidos cuidados. E sempre que possível, dê ao usuário a chance se selecionar, o que remover ou não do gráfico. Ainda mais se a sua aplicação, visa tornar as operações mais simples e agradáveis.
Muito bem, então vamos criar o que seria uma forma mais educada de implementar o que foi visto na animação 06. Para isto, iremos modificar o código 05, como mostrado logo abaixo.
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. input bool user01 = true; //Show time scale 05. input bool user02 = true; //Show price scale 06. //+----------------+ 07. struct st_Mem 08. { 09. long View_DateScale, 10. View_PriceScale; 11. }gl_StyleGraphic; 12. //+------------------------------------------------------------------+ 13. int OnInit() 14. { 15. gl_StyleGraphic.View_DateScale = ChartGetInteger(0, CHART_SHOW_DATE_SCALE); 16. gl_StyleGraphic.View_PriceScale = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE); 17. 18. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, user01); 19. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, user02); 20. 21. return INIT_SUCCEEDED; 22. }; 23. //+------------------------------------------------------------------+ 24. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 25. { 26. return rates_total; 27. }; 28. //+------------------------------------------------------------------+ 29. void OnDeinit(const int reason) 30. { 31. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, gl_StyleGraphic.View_DateScale); 32. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, gl_StyleGraphic.View_PriceScale); 33. }; 34. //+------------------------------------------------------------------+
Código 06
Agora, meu caro leitor, note que estamos sendo bem mais educados. Isto por conta de que, nas linhas quatro e cinco, permitimos permissão ao usuário, para remover as escalas. Tanto a de preço quanto a e tempo. E usamos a estrutura na linha sete para armazenar os valores originais. Isto para que possamos de fato recolocar o gráfico no mesmo estado que ele estava antes do indicador ser aplicado. Isto independentemente de qualquer mudança que o usuário venha a fazer.
Assim como foi o código 05 era simples e fácil de entender. Temos a mesma coisa sendo aplicada aqui também. No entanto, quero chamar a sua atenção para um outro ponto. Que é justamente o tratador do evento Deinit. Este pode ser visto na linha 29. A questão aqui é a seguinte: Mesmo depois de termos removido o indicador do gráfico. Irá demorar algum tempo, as vezes segundos, as vezes um pouco mais, para que o MetaTrader 5, de fato, venha a atualizar o gráfico, onde o indicador estaria. Durante este pequeno período de tempo. Algumas informações poderão estar ausentes enquanto outras ainda não foram removidas. Isto pode dar a impressão de que a plataforma é lenta, ou que o equipamento do usuário seja velho e obsoleto. Quando na verdade, o problema está justamente no fato de que o MetaTrader 5, estará ocupado fazendo alguma outra coisa.
Para tornar as coisas bem mais agradáveis, minha sugestão é que você em alguns momentos, utilize uma chamada da biblioteca padrão do MQL5. Isto a fim de forçar o MetaTrader 5, a atualizar o gráfico o quanto antes. Em diversos momentos isto será completamente desnecessário. Porém, se você notar uma certa demora entre um evento e outro. Pode utilizar tal chamada como uma maneira de furar a fila de eventos que o MetaTrader 5 precisará ou estaria lidando naquele momento.
A mudança a ser feita, pode ser observada no fragmento de código logo abaixo.
. . . 28. //+------------------------------------------------------------------+ 29. void OnDeinit(const int reason) 30. { 31. ChartSetInteger(0, CHART_SHOW_DATE_SCALE, gl_StyleGraphic.View_DateScale); 32. ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, gl_StyleGraphic.View_PriceScale); 33. ChartRedraw(); 34. }; 35. //+------------------------------------------------------------------+
Código 07
A simples adição, desta linha 33, vista no código 07, será suficiente para que o usuário, e até mesmo você, venha a experimentar um aparente ganho de performance do MetaTrader 5. Lembrando que isto é apenas aparente. Não existe de fato, um ganho na performance. Mas esta chamada da linha 33, estará dizendo ao MetaTrader 5, que queremos furar a fila de eventos, a fim de que o gráfico seja atualizado o quanto antes. Porém lembre-se do seguinte: Ao furar a fila, você estará tornando algum evento que poderia ser importante, para ser disparado em outro momento. Então tome cuidado ao furar a fila de execução.
Considerações finais
Aqui neste artigo, vimos como é fácil de criar e implementar uma metodologia operacional, visando colorir candles. Sendo este um conceito, que diversos operadores apreciam imensamente. Porém, vimos que é preciso se tomar cuidado ao implementar tal tipo de coisa. Isto para que as barras, ou candles, mantenham a sua aparência original. Visando assim não prejudicar a leitura que muitos operadores fazem candle a candle.
Como bônus, vimos também e foi demonstrado, como podemos mudar diversas coisas em um gráfico. Apesar de que no artigo em si, foi visto apenas como fazer isto com duas propriedades do gráfico. Que seriam as escalas de tempo e preço. Escalas que por sua vez, não poderiam ser removidas, via algum recurso diretamente acessível a um usuário padrão. No entanto, é perfeitamente possível e passivo de ser feito, via código. Mas lembrando que precisamos sempre que possível, restabelecer o gráfico ao seu estado inicial. Já que, isto torna tanto a experiência do usuário mais agradável, como também, demonstra que sua aplicação está sendo educada e foi bem planejada.
Mas como existem, vários atributos e propriedades que podem ser modificadas, e dificilmente irei abordar uma a uma. Sugiro que você, meu caro leitor, venha a praticar e experimentar, a utilização e modificação de tais propriedade via código MQL5. Para facilitar, você pode fazer uso da lista encontrada em propriedades de gráfico, onde cada um dos elementos e valores mostrados ali, muitas das vezes, só serão acessíveis via código MQL5. Então bons estudos. Lembrando que no anexo, teremos apenas os códigos realmente necessários para que você possa praticar e estudar o que foi mostrado no artigo.
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 14): Sockets (VIII)
Sistema de negociação de arbitragem de alta frequência em Python usando MetaTrader 5
Previsão de taxas de câmbio usando métodos clássicos de aprendizado de máquina: Modelos Logit e Probit
Busca de padrões arbitrários em pares de moedas no Python com o uso do MetaTrader 5
- 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