preview
Do básico ao intermediário: Objetos (I)

Do básico ao intermediário: Objetos (I)

MetaTrader 5Exemplos |
165 0
CODE X
CODE X

Introdução

No artigo anterior Do básico ao intermediário: Indicador (V), foi explicado, como poderíamos de maneira simples, adequar mesmo que parcialmente um indicador, ao modo de plotagem que venha a estar sendo utilizado em um gráfico do MetaTrader 5. Apesar de não ter sido mostrado como utilizar os três modelos de plotagem, já que isto necessita de conhecimento, que ainda não foi devidamente explicado por mim aqui ainda.

Podemos dentro de determinados limites, utilizar o modo candle ou o modo barra em um mesmo indicador. E isto sem muitos problemas. E caso queiramos utilizar o modo linha. Um indicador a parte precisará ser criado e colocado de maneira manual no gráfico. Porém, apesar deste pequeno inconveniente, que futuramente irei mostrar como contornar.

Acredito que você, meu caro leitor, tenha conseguido entender como podemos lidar com as limitações existentes. Isto durante um tempo, até que tenhamos alcançado um nível adequado nestes artigos. De modo que você, meu caro leitor, consiga entender como fazer as coisas, sem que seja necessário explicar cada mínimo detalhe envolvido na implementação.

Mas independente disto, existem coisas que já podemos começar a abordar. Apesar de que, as mesmas podem ser mais ou menos interessantes, para este ou aquele leitor específico. Digo isto, pois muitos de vocês, podem não conseguir enxergar um proposito maior no tema que começaremos a abordar neste artigo. Porém, para outros, o que será mostrado e explicado, neste e nos próximos artigos. É sim algo muito interessante, e que pode vir a ter um objetivo bastante nobre.

Então vamos começar vendo uma coisa, que não será completamente abordado neste artigo. Mas que irá server para podemos dar um ponta pé inicial, no que será o tema a ser visto.


Cuidados especiais

Existem alguns tipos de coisas, que muitos operadores gostam de ter no gráfico. Algumas destas coisas, são mais ou menos úteis dependendo de cada momento especifico. Uma destas coisas são contadores de candles ou barras. Para muita gente este tipo de coisa, é completamente inútil e sem nenhum propósito. Enquanto para outros, é um meio de se comunicar com outros operadores de maneira rápida e eficiente, a fim de trocar uma ideia sobre como eles estão enxergando o mercado.

Ok, isto que foi dito, é como algo que colocamos no gráfico, no que seria a visão por parte de um usuário. Porém, para nós, pensando como programadores, a coisa se desenrola de uma maneira ligeiramente diferente.

Isto porque, você pode elaborar formas diferentes e atraentes de demonstrar algo no gráfico. Porém neste meu singelo exemplo, não existem formas muito diferentes de se fazer tal coisa. Já que o objetivo principal é simplesmente colocar um texto no gráfico. Somente isto. A real diferença de fato estará, não no texto em si. Mas sim na forma como iremos colocar ele no gráfico e o atualizar de tempos em tempos.

Muitas pessoas, que programam por hobby, não tem uma visão clara e aguçada, de um programador, que realmente se dedica e estuda sobre um assunto. E por favor, não me interprete mal. Não estou aqui dizendo que uma pessoa que cria programas ocasionais, e com objetivos particulares, não sabe o que está fazendo. O problema, é que nem sempre estas pessoas, tem noção de certos tipos de problemas, que programas mal otimizados, podem acarretar para a plataforma MetaTrader 5. Causando uma degradação, gradual e progressiva da performance a ponto de tornar-se completamente inviável o uso da plataforma, com todas aquelas aplicações rodando no gráfico.

Um simples contador de candles, cujo objetivo é somente colocar um texto no gráfico. Se for mal otimizado, pode acabar consumindo muito mais recursos do que seria de fato necessário. Mesmo aqui, onde a ideia e o intuito estará sempre sendo a didática. Procuro mostrar códigos que não irão trazer grandes prejuízos ao desempenho do MetaTrader 5. E quando isto por ventura possa vir a ocorrer, menciono o perigo e cuidado a ser tomado para evitar dores de cabeça, por parte dos que estejam estudando e praticando o que vem sendo mostrado nos artigos.

Ok, mas vamos voltar a nossa questão: Como você pensaria em um contador de candles, meu caro leitor? Possivelmente, você pensaria em algum tipo de aplicação, que iria escrever valores numéricos nas barras. Mas, a questão ainda continua. Que tipo de aplicação você usuária? Bem, como até o momento, vimos como criar scripts e indicadores. Você muito provavelmente iria ficar entre estes dois casos. No entanto, devido a algumas limitações dos scripts, você acabaria migrado para os indicadores.

E que tipo de limitação seria esta, que existe nos scripts? Se você vem experimentado, estudando e praticando, deve ter notado que sempre que colocamos um script em um gráfico, ele é removido quando mudamos o tempo gráfico. Mesmo que venhamos a utilizar um laço no script a fim de impedir isto. Ok, isto nos forçaria a tomar medidas a fim de a cada mudança no timeframe, repor o script no gráfico. Existe uma forma de se contornar problemas envolvidos na execução de scripts. Mas como isto envolve utilização de serviços e estes quando ligados a gráficos são bem complexos. Não seria de fato uma escolha adequada.

Se você tiver curiosidade e interesse em saber o quanto complicado é este tipo de ligação, procure ver meus artigos sobre a criação de um sistema de replay / simulador. Mas como aqueles artigos, são voltados para quem já tem uma boa base em programação MQL5, o que não acontece neste exato momento, já que ainda estamos começando. Não irei entrar nos detalhes de como manipular um gráfico utilizando para isto serviços.

Restando assim a alternativa de utilizar indicadores. Certo, porém, toda via e entretanto, indicadores na maior parte das vezes, não são adequados para certos tipos de tarefas. Isto porque, indicadores, no MetaTrader 5, são executados em bloco. Como se fossem uma única aplicação rodando em um gráfico. Isto para agilizar cálculos que o MetaTrader 5, esteja efetuando para nos fornecer certos valores. Estes valores dos quais estou mencionando, fazem parte de um conjunto de entradas que podemos escolher durante o momento em que um indicador será colocado no gráfico. Isto foi visto e mencionado em artigos anteriores.

Porém tendo em vista, que um contador de barras, irá ser executado apenas no momento em que uma nova barra surgir no gráfico. Você, meu caro leitor, acaba ficando tentado em utilizar um cronometro para sincronizar as coisas. E é aqui onde as coisas começam a dar problemas. Utilizar um cronometro em um indicador, não algo de fato recomendado. Isto porque, se ocorrer alguma falha, no código do cronometro. Todos os outros indicadores, serão prejudicados. Podendo até mesmo vir a travar o MetaTrader 5, por alguns instantes. Instantes este, que podem de fato ser cruciais.

Mas existe formas de se trabalhar com um sistema, cujo objetivo, é saber se uma nova barra surgiu ou não no gráfico. Fazer isto, utilizando um indicador, de fato é a maneira mais simples e prática, de saber quando uma nova barra surgiu. E desta forma, conseguir contabilizar os candles apresentando um texto de forma posterior. Para chegar neste ponto, onde a contabilização dos candles irá acontecer, precisamos começar de algum ponto. E este se inicia com o código visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. int OnInit()
05. {
06.     return INIT_SUCCEEDED;
07. };
08. //+------------------------------------------------------------------+
09. 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[])
10. {
11.     return rates_total;
12. };
13. //+------------------------------------------------------------------+

Código 01

Agora preste atenção a uma coisa aqui meu caro leitor. Todo indicador, irá receber do MetaTrader 5, um evento Calculate, cada vez que a cotação do ativo presente no gráfico, mudar. O MetaTrader 5, não dispara o evento Calculate, baseado em uma atividade no tempo. Se você estiver utilizando um gráfico, em um tempo de 10 minutos. Toda vez que uma nova barra surgir, depois de aproximadamente 10 minutos, não teremos um evento Calculate. A menos que a cotação de fato tenha mudado. Até lá, nenhum evento Calculate irá acontecer.

Tendo em vista, que em ativos bem voláteis, podemos ter eventos Calculate em períodos bem curtos de tempo, na ordem de milissegundos. Precisamos que este evento Calculate seja executado de maneira o mais rápido quanto for possível ser feito. Ou seja, você não quer ficar calculando ou procurando informações de maneira desnecessária. Visto que isto, tornaria o tratamento do evento algo muito lento.

Prejudicando assim todas outras aplicações ligadas aquele gráfico específico. E lembre-se de que ainda não entramos na questão dos Expert Advisores. E sim, ter indicadores mal otimizados traz sérios prejuízos ao MetaTrader 5. Mas isto será melhor visto em breve.

Por hora, você precisa entender, que a velocidade de execução, depende do como você busca as informações. Neste código 01, você pode observar que temos um array cujo objetivo é nos fornecer o valor de tempo de cada barra. Preste atenção, aqui no evento Calculate, não sabemos em que o momento que a cotação de fato mudou. Apenas sabemos quando a barra foi criada. E com base no tempo gráfico, podemos estimar quanto tempo falta para que ela seja fechada. Esta informação é importante, para que você consiga criar um outro tipo de aplicação, que iremos ver depois.

Mas aqui, nosso objetivo é criar um contador de candles. Ou pelo menos, saber quando temos ou não a presença de uma nova barra no gráfico. Assim, sempre que este array Time, que pode ser visto na linha nove, mudar de valor. Significa que temos uma nova barra no gráfico.

Uma outra forma, que ao meu ver é bem mais simples de se fazer isto, é olhando o valor prev_calculated e rates_total. Mas porquê? O motivo, é que o valor presente no array Time, é do tipo datetime. Porém, os valores prev_calculated e rates_total, são valores que o próprio MetaTrader 5 nos fornece, sendo os mesmos do tipo inteiro. Algo que é muito mais simples e rápido de testar. E como eles somente mudam, quando novas barras surgem no gráfico, a coisa fica muito mais fácil de ser observada.

Além de outra questão que em breve iremos ver. Está percebendo onde estou querendo chegar, meu caro leitor? Não importa como você irá fazer para implementar algo. O que importa, é você entender que tipo de informação tem em mãos, para conseguir atingir seu objetivo. Para provar isto, vamos mudar o código 01, para o código 02 visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. int OnInit()
05. {
06.     return INIT_SUCCEEDED;
07. };
08. //+------------------------------------------------------------------+
09. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
10. {    
11.     return rates_total;
12. };
13. //+------------------------------------------------------------------+

Código 02

Agora sim, temos um ponto de partida, para que você consiga compreender que tudo depende do correto entendimento das coisas. E em entender como utilizar as informações que tem em mãos. Não existe uma forma mais ou menos correta de se fazer as coisas. Apenas uma forma mais ou menos simples de se conseguir o mesmo tipo de objetivo e resultado. Ok, mas como podemos saber se temos ou não uma nova barra surgindo no gráfico? Esta é a parte fácil, meu caro leitor. Para fazer isto, vamos modificar o código 02, para o que é visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. int OnInit()
05. {
06.     return INIT_SUCCEEDED;
07. };
08. //+------------------------------------------------------------------+
09. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
10. {
11.     if ((prev_calculated > 0) && (prev_calculated != rates_total))
12.         Print("New Bar...");
13. 
14.     return rates_total;
15. };
16. //+------------------------------------------------------------------+

Código 03

Este código 03, coloca em prática exatamente o que quero mostrar e foi dito a pouco. Ou seja, temos aqui, uma forma muito simples de saber quando a barra atual foi fechada e quando uma nova surgiu. Para mostrar isto, veja a animação logo abaixo.

Animação 01

Como o código 03 é muito simples, assim como a própria animação. Podemos dispensar qualquer explicação, podendo assim iniciar o que será a parte divertida do artigo. Mas para isto, vamos a um novo tópico.


Objetos e o gráfico

Diferente do que muitos podem pensar. Tudo e qualquer coisa presente em um gráfico, são objetos. Claro que estes objetos, podem ter objetivos completamente diferentes dependendo do tipo de coisa que estejamos tentando criar. Mas isto não muda o fato de que continuam sendo objetos. E detalhe, estes objetos no qual estou me referindo, nada tem a ver como programação orientada em objetos. Agora vem a parte complicada. Existem dois tipos de objetos, ou melhor dizendo, duas formas de posicionar objetos em um gráfico de cotação. Como é o caso, de gráficos criados e mantidos, pelo MetaTrader 5.

O primeiro tipo, são objetos cujo sistema, são coordenadas de tela. E o segundo tipo, são objetos de coordenadas de cotação. Existem diferenças entre estes objetos. Tanto na forma de os apresentar na tela, como na forma de manipular os mesmos. No entanto, existem uma certa relação entre alguns tipos. Saber escolher o tipo certo, facilita e muito o trabalho de implementação. Além é claro agilizar a execução do código.

Então como este é o primeiro contato, que estamos tendo com este tipo de coisa. Vamos dar uma pequena pausa no que seria o contador de candles. Já que primeiro precisamos entender como lidar com estes objetos.

O ponto de partida a ser observado, será o de você olhar na documentação do MQL5, Tipos de objeto. Ali você irá ver uma enumeração com diversos objetos diferentes. Apesar de você, meu caro leitor, imaginar que, talvez, não temos um número adequado de objetos presentes ali, faltando assim alguns. Isto não é verdade. O MQL5, ao meu entender, nos fornece um número mais que o suficiente de objetos, para serem utilizados no gráfico. Para ser sincero, não precisaríamos de todos aqueles objetos. Mas se eles foram implementados e estão a nossa disposição. Não vejo mal algum, em fazer bom uso dos mesmos. Além do que, muitos deles podem ser usados de uma forma bem interessante, nos poupando muito trabalho.

Para demonstrar isto, vamos criar um pequeno código. Como forma de apresentar como seria trabalhar com objetos no gráfico. O código em questão pode ser visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_NameChannel    "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.    ObjectCreate(0, def_NameChannel, OBJ_REGRESSION, 0, 0, 0);
09. 
10.    return INIT_SUCCEEDED;
11. };
12. //+------------------------------------------------------------------+
13. 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[])
14. {
15.    const int   n = 20,
16.                a = 2;
17. 
18.    if ((prev_calculated > (n + a)) && (prev_calculated != rates_total))
19.    {
20.       ObjectMove(0, def_NameChannel, 0, Time[rates_total - (n + a)], Close[rates_total - (n + a)]);
21.       ObjectMove(0, def_NameChannel, 1, Time[rates_total - a], Close[rates_total - a]);
22.    }
23. 
24.    return rates_total;
25. };
26. //+------------------------------------------------------------------+
27. void OnDeinit(const int reason)
28. {
29.    ObjectDelete(0, def_NameChannel);
30.    ChartRedraw();
31. };
32. //+------------------------------------------------------------------+

Código 04

Este código 04, demonstra o que seria nosso primeiro objeto dentro de um indicador. Você pode estar olhando e pesando: Cara, mas isto não é um indicador. Já que ele não tem aquelas estruturas que vimos nos artigos passados. Mas sim meu caro leitor, este código 04, é sim um indicador. E você sabe disto, ao ver a função OnCalculate, que é a responsável por capturar e tratar o evento Calculate, gerado pelo MetaTrader 5.

O fato é que este indicador, no código 04, não é um indicador convencional. Ele tem um objetivo bem mais específico e voltado a uma determinada tarefa. Antes de vermos como este código 04 funciona. Veja ele executando em um gráfico, como pode ser visto na animação logo abaixo.

Animação 02

É necessário que seja visto em animação, já que uma imagem estática não seria o suficiente para entender uma coisa que será visto em breve. Mas antes de começarmos a fazer graça no código. Vamos entender como este código 04 funciona. Na linha quatro temos uma definição, para que possamos dar um nome ao objeto que iremos criar. E sim, meu caro leitor, cada coisa colocada no gráfico precisa ter um nome. De agora em diante comece a se acostumar com isto.

Assim, na linha oito, apenas tentamos criar um objeto. No caso trata-se de um canal de regressão linear. Como não sabemos onde este canal será apresentado não fazemos mais nada. O que acontece agora é o seguinte: O indicador irá esperar que o MetaTrader 5 venha a disparar um evento Calculate com uma certa característica específica. A característica esperada é definida na linha 18. Note que esta linha 18 vista neste código 04, se parece bastante com a linha 11 vista no código 03. Tendo o mesmo objetivo: Aguardar uma nova barra surgir. Até que isto venha a acontecer, o objeto que criamos a linha oito não irá ser apresentado no gráfico.

Assim que uma nova barra seja disparada. Usamos as linhas 20 e 21 para criar o canal de regressão linear. Note como isto está sendo feito. Em breve iremos tratar disto com mais detalhes. Por hora, veja que não tem muito segredo aqui. A linha 20 diz onde o canal começa a ser traçado e a linha 21 onde ele termina. Fazendo isto, temos um canal que irá acompanhar a cotação tendo uma regressão de 20 barras. E que irá desconsiderar a atual barra.

Agora, sempre que você cria um objeto e o coloca no gráfico, por meio de uma aplicação. É de bom tom e educado, que a sua aplicação remova o objeto do gráfico. Para fazer isto, usamos a linha 29, dentro do que seria o tratador de eventos Deinit.

Mas agora vem a parte divertida. E se você mudar a forma de analisar como a regressão linear deveria ser impressa. Como o indicador iria se comportar? Para saber isto, vamos modificar o código 04, como mostrado logo abaixo, na íntegra.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_NameChannel    "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.    ObjectCreate(0, def_NameChannel, OBJ_REGRESSION, 0, 0, 0);
09. 
10.    return INIT_SUCCEEDED;
11. };
12. //+------------------------------------------------------------------+
13. 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[])
14. {
15.    const int   n = 20,
16.                a = 1;
17. 
18.    if (prev_calculated > (n + a))
19.    {
20.       ObjectMove(0, def_NameChannel, 0, Time[rates_total - (n + a)], Close[rates_total - (n + a)]);
21.       ObjectMove(0, def_NameChannel, 1, Time[rates_total - a], Close[rates_total - a]);
22.    }
23. 
24.    return rates_total;
25. };
26. //+------------------------------------------------------------------+
27. void OnDeinit(const int reason)
28. {
29.    ObjectDelete(0, def_NameChannel);
30.    ChartRedraw();
31. };
32. //+------------------------------------------------------------------+

Código 05

Note que neste código 05, mudamos apenas o tratador de eventos OnCalculate. Isto frente ao que ele era no código 04. Mas o resultado, é no mínimo muito interessante, como você pode observar na animação logo abaixo.

Animação 03

Este tipo de coisa que é vista na animação 03 é muito doida. Ainda mais considerando que a regressão está sendo criada em tempo real. Ou seja, a cada nova cotação, temos o canal de regressão linear mudando. E dependendo da configuração que você esteja utilizando, poderá ter um indicador de tendência realmente muito sensível. Até mais que uma média móvel exponencial. Mas isto eu deixo para o traders de plantão e que sempre desejaram ter uma forma de ter um canal de regressão linear que pudesse ser auto ajustável.

Talvez você esteja me olhando e pensando: Cara mais qual seria a utilidade deste tipo de indicador? Minha resposta para isto seria: Não sei. Mas que é bem interessante e divertido. Isto você não pode negar. Porém para aquele com uma visão mais elaborada, já logo pensaram em uma forma de utilizar isto para outros fins. Já que tudo que você precisaria fazer, seria mudar o tipo de objeto a ser criado, e logo depois dizer quais seriam os pontos de ancoragem. E de tempos em tempos, os objetos iria se ajustar automaticamente, sem que você venha a precisar lembrar de ajustar o mesmo. Pois o simples fato de ele estar no gráfico, já será suficiente para que as regras que você criou, venham a ser cumpridas e seguidas.

Então vamos ver um outro exemplo. Neste caso iremos utilizar um outro tipo de objeto. Lembrando que o que irei mostrar é apenas para fins didáticos. O código é visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_NameChannel    "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.    ObjectCreate(0, def_NameChannel, OBJ_TREND, 0, 0, 0);
09.    ObjectSetInteger(0, def_NameChannel, OBJPROP_RAY_RIGHT, true);
10. 
11.    return INIT_SUCCEEDED;
12. };
13. //+------------------------------------------------------------------+
14. 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[])
15. {
16.     const int   n = 60;
17.     double      p = DBL_MIN;
18.     int         t = 0;
19. 
20.     for (int c = rates_total - (n + 1); c < rates_total; c++)
21.         p = (High[c] > p ? High[t = c] : p);
22.     ObjectMove(0, def_NameChannel, 0, Time[t], p);
23.     p = DBL_MIN;
24.     for (int c = t + 1; c < rates_total; c++)
25.         p = ((High[c] > p) && (Open[c] < Close[c]) ? High[t = c] : p);
26.     ObjectMove(0, def_NameChannel, 1, Time[t], p);
27. 
28.    return rates_total;
29. };
30. //+------------------------------------------------------------------+
31. void OnDeinit(const int reason)
32. {
33.    ObjectDelete(0, def_NameChannel);
34.    ChartRedraw();
35. };
36. //+------------------------------------------------------------------+

Código 06

Este código 04, quando executado irá gerar o que pode ser visto logo abaixo.

Animação 04

Não fique empolgado com o que você está vendo meu caro leitor. Pois isto que está sendo feito é apenas para demonstração. De forma alguma deve ser encarado como sendo uma aplicação final. Mas o que podemos ver acontecendo aqui nesta animação 04, é o surgimento de uma linha de tendência de baixa, sendo traçada com base nos critérios programados no código 04. Mas como isto é possível? Simples, apenas informei ao código, como ele deveria fazer para procurar uma linha de tendência de baixa. Isto segundo os meus critérios.

Agora vamos entender o que aconteceu. Na linha oito, assim como era feito no código 03. Estamos dizendo que tipo de objeto queremos colocar no gráfico. Já na linha nove, estamos modificando uma das propriedades do objeto. Sem que esta propriedade fosse definida como mostrado aqui no código 04. O resultado seria o que pode ser visto na imagem logo abaixo.

Imagem 01

Perceba que agora, olhando nesta imagem 01, estamos vendo de onde até onde a linha de tendência foi criada. No caso estamos procurando uma linha de tendência de baixa. Linhas de tendência de alta, seguem outro tipo de critério. Mas como o objetivo aqui, não é mostrar como identificar e criar linhas de tendência automaticamente. O critério e a forma como estamos fazendo isto. De fato, funciona. Ok, mas então como o indicador, conseguir encontrar estes pontos para traçar a linha de tendência? Parece mágica.

Não meu caro leitor, isto definitivamente não é mágica. É apenas a aplicação de um critério elementar. Observe o tratador de eventos Calculate. Note que nele temos dois laços. Um para identificar o que seria o primeiro ponto para se traçar a linha de tendência. E um outro laço para identificar, qual seria o segundo ponto, a fim de traçar a linha de tendência. Quando o primeiro ponto é encontrado, usamos a linha 22 para dizer ao objeto onde estaria o primeiro ponto de ancoragem. Logo depois de encontrar o segundo ponto, usamos a linha 26 para dizer onde está o segundo ponto de ancoragem. E o resto é feito pelo próprio MetaTrader 5.

Porém, mesmo assim vou ressaltar o fato de que você NÃO DEVE TOMAR este indicador como algo plausível. Ele foi criado para detectar o que você está observando na imagem 01 e na animação 04. Dificilmente ele irá conseguir detectar outros pontos tão perfeitos como estes que você pode observar logo acima.

Ok. Entendi. Mas será que não podemos mudar outras propriedades? A fim de construir objetos mais personalizados? Sim, meu caro leitor. E com um detalhe: Diferente do que acontece quando você tenta ajustar as propriedades diretamente no gráfico. Alguns destes objetos tem propriedades que somente podem ser ajustadas via código.

Porém vamos ver um exemplo simples de mudanças de propriedades. Este é visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_NameChannel    "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.    ObjectCreate(0, def_NameChannel, OBJ_TREND, 0, 0, 0);
09.    ObjectSetInteger(0, def_NameChannel, OBJPROP_COLOR, clrLawnGreen);
10.    ObjectSetInteger(0, def_NameChannel, OBJPROP_WIDTH, 4);
11. 
12.    return INIT_SUCCEEDED;
13. };
14. //+------------------------------------------------------------------+
                   .
                   .
                   .

Código 07

Aqui neste código 07 temos apenas o fragmento que precisou ser modificado, frente ao que pode ser visto no código 06. Mas note que estamos na linha nove dizendo qual a cor queremos que seja utilizada no objeto. Assim como também na linha dez, qual a espessura da linha que deverá ser utilizada. Como resultado da execução deste código, temos o que é visto na imagem logo abaixo.

Imagem 02

Agora preste atenção meu caro leitor. Da forma como este código foi implementado, você NÃO CONSEGUIRÁ mudar nem a cor, e tão pouco a espessura da linha. Isto usando um acesso direto as informações do indicador. Como você pode observar na imagem logo abaixo.

Imagem 03

Para modificar estas propriedades do objeto, você precisará utilizar uma outra caixa de mensagem. Ou seja, no caso, você precisará utilizar o que é mostrado na imagem logo abaixo.

Imagem 04

Sei que isto parece um tanto quanto complicado e confuso. Mas esta seria a forma clássica de utilizar o MetaTrader 5. Apesar de tudo, existem meios de contornar este tipo de coisa. Permitindo que o usuário, possa modificar as propriedades de um objeto, com base em alguma configuração que seria feita, diretamente no indicador. Mas vamos com calma. Pois este está sendo apenas o primeiro contato que estamos tendo com objetos. Sendo assim, acredito que você já terá bastante coisa a ser experimentada e testada. Isto a fim de que venha a estar preparado para o próximo artigo.


Considerações finais

Neste artigo, começarmos a ver como poderíamos trabalhar com objetos diretamente no gráfico. Isto utilizando um código construído especialmente para apresentar algo a nós. Apesar deste primeiro contato ter sido um tanto quanto superficial. O mesmo já mostrou que, se o objetivo a ser alcançado for pensado com calma, e bem planejado. Podemos fazer muitas coisas bem interessantes. Sendo que para isto, você precisa de fato praticar e estudar, como cada um dos objetos disponibilizados pelo MQL5 e passiveis de serem utilizados no MetaTrader 5, trabalham. Isto por que, sem de fato entender as possibilidades disponíveis, você não conseguirá colocar em prática ideias que possa vir a ter.

Bem, como sempre, nesta série de artigos, no anexo, você encontrará os códigos na integra. Porém, e especialmente para este artigo, devo alertar que todos os códigos disponibilizados, tem como objetivo, o estudo e uma forma de se praticar o que foi explicado no artigo. Não utilize os códigos vistos aqui, como sendo aplicações finalizadas, ou com proposito diferente do estudo de conceitos. Pois isto pode fazer um grande mal para o seu bolso.

Arquivos anexados |
Anexo.zip (2.82 KB)
Simulação de mercado (Parte 22): Iniciando o SQL (V) Simulação de mercado (Parte 22): Iniciando o SQL (V)
Antes que você chute o balde, e decida abandonar o estudo sobre como usar o SQL. Deixe-me lembrá-lo, meu caro leitor, que aqui estamos ainda usando apenas o básico do básico. Ainda não exploramos algumas coisas que são possíveis de serem feitas no SQL. Assim que as explorarmos você verá que o SQL é bem mais prático do que parece. Mesmo que muito provavelmente, eu venha a mudar a direção do que estamos criando. Isto por que, o processo de criação é dinâmico. Irei mostrar um pouco mais sobre como fazer as coisas no SQL. Isto por que, ele de fato é algo que você precisa entender e conhecer. Ficar simplesmente achando que é mais capaz, que toda uma comunidade de programadores e desenvolvedores, apenas lhe fará perder tempo e oportunidade. Tenha calma, pois a coisa irá se tornar ainda mais interessante.
Robô de trading multimódulo em Python e MQL5 (Parte I): Criando a arquitetura básica e os primeiros módulos Robô de trading multimódulo em Python e MQL5 (Parte I): Criando a arquitetura básica e os primeiros módulos
Estamos desenvolvendo um sistema de trading modular que combina Python para análise de dados com MQL5 para execução de ordens. Quatro módulos independentes monitoram paralelamente diferentes aspectos do mercado: volumes, arbitragem, economia e riscos, utilizando RandomForest com 400 árvores para análise. É dado um foco especial no gerenciamento de risco, pois sem uma gestão adequada, até os algoritmos de trading mais avançados tornam-se inúteis.
Expert Advisor Autônomo com MQL5 e Python (Parte III): Decifrando o Algoritmo do Boom 1000 Expert Advisor Autônomo com MQL5 e Python (Parte III): Decifrando o Algoritmo do Boom 1000
Nesta série de artigos, discutimos como podemos construir Expert Advisors capazes de se ajustarem autonomamente às condições dinâmicas do mercado. No artigo de hoje, tentaremos ajustar uma rede neural profunda aos mercados sintéticos da Deriv.
Algoritmo de tribo artificial (Artificial Tribe Algorithm, ATA) Algoritmo de tribo artificial (Artificial Tribe Algorithm, ATA)
O artigo analisa em detalhes os componentes-chave e as inovações do algoritmo de otimização ATA, que é um método evolutivo com um sistema de comportamento duplo único, que se adapta conforme a situação. Utilizando cruzamento para uma diversificação aprofundada, e migração para busca quando há estagnação em ótimos locais, o ATA combina aprendizado individual e social.