preview
Desenvolvendo um sistema de Replay (Parte 42): Projeto do Chart Trade (I)

Desenvolvendo um sistema de Replay (Parte 42): Projeto do Chart Trade (I)

MetaTrader 5Exemplos | 7 fevereiro 2024, 11:10
214 0
Daniel Jose
Daniel Jose

Introdução

No artigo anterior Desenvolvendo um sistema de Replay (Parte 41): Iniciando a segunda fase (II), demonstrei como você faz para criar um indicador a ser usado como mouse. Você pode ter achado que aquilo é bobagem e que não irá de fato ter alguma serventia no logo prazo. Pois bem, se você pensa, ou pensou assim é por que não conseguiu de fato entender o que está acontecendo.

Toda vez que você precisa criar certas coisas, irá obrigatoriamente, ter que fazer uma serie de testes e criar condições para que um programa, ou processo consiga conviver com outros. Fazer isto, ou de fato conseguir isto, é que mostra o quanto você está ou não preparado para se afirmar como sendo um profissional.

Não é raro, como iniciantes, termos problemas de um programa, ou processo interferir em outro. Quando isto acontece, coisas estranhas acontecem. Um iniciante não irá de fato conseguir resolver tais problemas, mas um profissional deve conseguir lidar com este tipo de situação.

O que quero dizer com isto, é o seguinte: Do que adianta você programar um EA, capaz de fazer mil e uma operações. Ter uma serie de indicadores, elementos gráficos. Um monte de programas, ou processos que lhe ajudam a operar no mercado. Se ao tentar colocar dois destes programas juntos, no mesmo gráfico, eles começam a atrapalhar um ao outro ?!?!

Ou pior, você cria um programa, extremamente seguro e robusto. Daí tem que criar um outro que irá usar parte da funcionalidade daquele primeiro. Mas ao fazer isto, este novo programa começa a ter uma serie de erros e falhas, ainda mais quando colocado junto com outros processos. Definitivamente você irá ficar perdendo tempo, tentando resolver tais falhas. Algumas serão mais simples, porém outras muito complicadas.

Por que estou dizendo isto ?!?! O motivo é justamente o fato de já estarmos com um indicador de mouse criado. A plataforma MetaTrader 5, conta com diversas coisas para nos ajudar. Algumas são mais simples, precisando assim de um upgrade a fim de realmente atender a necessidade pessoal de cada um. Você pode fazer isto, criando assim diversos programas a fim de construir o rifle ideal, a arma perfeita para usar no mercado. Mas gostaria de chamar você a pensar no seguinte: Que tal ao invés de tentar criar a arma perfeita, criamos diversos componentes e peças, de maneira a usá-los e combina-los a fim de ter uma arma adequada para o que iremos e teremos que enfrentar ?!?!

Parece uma boa solução, não é mesmo ?!?! Fizemos isto ao criar o indicador de mouse. Com base naquele indicador iremos começar a criar uma serie de peças e componentes que irão nos ajudar imensamente.

Desde o inicio desta sequencia sobre como desenvolver um sistema de replay / simulação, venho dizendo que a ideia aqui, é usar a plataforma MetaTrader 5, de forma idêntica, tanto no sistema que estamos desenvolvendo, quanto no mercado real. É importante que isto se dê de maneira adequada. Você não vai querer treinar e aprender a lutar usando determinadas ferramentas, e na hora da briga ter que usar outras. Acredite, usar o sistema de replay / simulador, é fazer o treinamento. Já operar na conta REAL, é de fato partir para a briga. Se você vai partir para a briga, deve usar o que aprendeu e se acostumou a usar no treinamento.

Existem duas ferramentas, depois do indicador de mouse, que são mais urgentes de serem criadas. Uma é simples e a outra bastante complicada, devido ao que teremos de fato fazer em termos de modelagem de dados. Então vamos começar pela mais simples. Assim você vai se acostumando e quando for ver a outra, que é muito mais complicada, já terá uma boa noção de como as coisas estarão funcionando.

A ferramenta simples é o Chart Trade. Este foi apresentado, em sua última versão no artigo: Desenvolvendo um EA de negociação do zero (Parte 30): CHART TRADE agora como indicador ?!. Só o que iremos fazer agora, faz aquele indicador, parecer brincadeira de criança. Isto devido ao qual simples ele era e tão pouco versátil. Vamos fazer um novo Chart Trade que consiga conviver em harmonia com o indicador já criado. O indicador do qual estou falando é o indicador de mouse.


Um novo Chart Trade

Aquele Chart Trade visto no artigo acima mencionado irá nos servir como base. No entanto não iremos de fato utilizar o código, ou o template. Iremos criar um outro, bem mais maduro e adequado as nossas necessidades.

Neste novo código que irei apresentar, você irá notar que ele é consideravelmente mais simples e compacto. Como consequência disto, é mais fácil corrigir e modificar as coisas nele. A ideia é usar o indicador de mouse para mover, clicar e interagir com qualquer coisa no gráfico. Ao fazer isto iremos precisar montar um código bem peculiar. Então para que consigam acompanhar o que irá ser feito, irei mostrar as coisas bem devagar. Isto por que a coisa é bem, mas bem diferente do que muitos estão acostumados a ver e a usar no MetaTrader 5. Isto falando de programação. Muitos talvez irão ficar sem entender nada neste começo.

Para começar o nosso Chart Trade, usa um conceito que apresentei a um bom tempo: Programação RAD. Esta palavra RAD, vem de Rapid Application Development, ou traduzindo: Desenvolvimento Rápido de Aplicações. Fui apresentado a este conceito anos atrás quando iniciava na programação para sistema Windows. Ela ajuda bastante a criação eficiente de aplicativos. Já que invés de ficar preocupado com a aparência que do programa irá ter, você usa este sistema de programação, e passará a ficar realmente mais tempo tomando conta do código em si. No artigo  Indicadores múltiplos em um gráfico (Parte 06): Transformando o MetaTrader 5 em um sistema RAD (II), demonstrei como você pode fazer para usar algo parecido no MetaTrader 5.

Aquele mesmo conceito será usado aqui novamente. No entanto, iremos torná-lo ainda melhor. Então se você desejar começar com o pé direito. Leia o artigo mencionado, assim como o artigo anterior, que também é importante para você compreender o que iremos fazer aqui. O dito artigo pode ser lido em:  Indicadores múltiplos em um gráfico (Parte 05): Transformando o MetaTrader 5 em um sistema RAD (I). É importante você compreender o que está sendo falado lá. Pois aqui a coisa será bem mais densa e complicada, apesar deste indicador ser a parte fácil frente ao que irá vim mais para frente.

Nosso novo template terá a aparência mostrada logo abaixo, na figura 01:

Figura 01

Figura 01 - Template RAD

Isto, mesmo. Na figura 01 temos a real aparência que o Chart Trade irá ter. O que você está vendo é o template do Chart Trade, e não o Chart Trade em si. Ele pode ser visto no vídeo 01, logo abaixo, onde demonstro a interação entre ele o o indicador mouse. Vejam o vídeo, e notem como a coisa está funcionando. O vídeo representa exatamente o que irá ser visto neste artigo. Então é importante ver o vídeo ter um melhor entendimento do que irá ser explicado.


Vídeo 01 - Vídeo de demonstração.

Considerando que você viu de fato o vídeo 01. Vamos começar a ver o código do indicador Chart Trade. Mas antes precisamos adicionar uma pequena coisa no código da classe C_Terminal. Tal coisa a ser adicionada é vista no fragmento abaixo:

156. //+------------------------------------------------------------------+
157.            bool IndicatorCheckPass(const string szShortName)
158.                    {
159.                            string szTmp = szShortName + "_TMP";
160.                            
161.                            if (_LastError != ERR_SUCCESS) return false;
162.                            IndicatorSetString(INDICATOR_SHORTNAME, szTmp);
163.                            if (ChartWindowFind(m_Infos.ID, szShortName) != -1)
164.                            {
165.                                    ChartIndicatorDelete(m_Infos.ID, 0, szTmp);
166.                                    Print("Only one instance is allowed...");
167.            
168.                                    return false;
169.                            }
170.                            IndicatorSetString(INDICATOR_SHORTNAME, szShortName);
171.                            ResetLastError();
172.    
173.                            return true;
174.                    }
175. //+------------------------------------------------------------------+

Fragmento da classe C_Terminal.

Este código pode não lhe parecer muito estranho, e de fato ele não é. Ele já foi visto anteriormente, mas agora ele está fazendo parte da classe C_Terminal, de modo que todas as classes, ou indicadores que vierem a usar esta classe irá conseguir se beneficiar deste código acima. Ele faz exatamente o que queremos e desejamos. Evita que o indicador possa ser colocado mais de uma vez no gráfico. Existe uma forma de burlar isto, e nos usaremos isto no futuro, mas por hora, não se preocupe com este detalhe. Se atente ao simples fato de que este código evitará que tenhamos dois indicadores idênticos no gráfico. Isto ao mesmo tempo.

Mas antes de entrarmos na classe inicial que dará suporte ao nosso chart trade. Vamos ver primeiro o código do indicador. Estou mudando a ordem de apresentação, para que a explicação da classe se dê de uma forma mais adequada. O código na integra do indicador pode ser visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. #property description "Base version for Chart Trade (DEMO version)"
04. #property version   "1.42"
05. #property link "https://www.mql5.com/pt/articles/11652"
06. #property indicator_chart_window
07. #property indicator_plots 0
08. //+------------------------------------------------------------------+
09. #include <Market Replay\Chart Trader\C_ChartFloatingRAD.mqh>
10. //+------------------------------------------------------------------+
11. C_ChartFloatingRAD *chart = NULL;
12. //+------------------------------------------------------------------+
13. int OnInit()
14. {
15.     chart = new C_ChartFloatingRAD("Indicator Chart Trade", new C_Mouse("Indicator Mouse Study"));
16.     if (_LastError != ERR_SUCCESS)
17.     {
18.             Print("Error number:", _LastError);
19.             return INIT_FAILED;
20.     }
21.     
22.     return INIT_SUCCEEDED;
23. }
24. //+------------------------------------------------------------------+
25. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
26. {
27.     return rates_total;
28. }
29. //+------------------------------------------------------------------+
30. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
31. {
32.     (*chart).DispatchMessage(id, lparam, dparam, sparam);
33.     
34.     ChartRedraw();
35. }
36. //+------------------------------------------------------------------+
37. void OnDeinit(const int reason)
38. {
39.     delete chart;
40.     
41.     ChartRedraw();
42. }
43. //+------------------------------------------------------------------+

Código fonte do Indicador Chart Trade

Este código do indicador é bastante simples como você pode ver acima. É verdade que ainda iremos adicionar algumas informações, de maneira a fazer uma descrição adequada dele. Mas por hora ele já é suficiente para o que precisamos de fato fazer.

Observe que a única coisa que de fato fazemos, é dizer que não será plotado nenhum dado, isto na linha 07. E depois todo o resto do trabalho, consiste em inicializar o ponteiro para usar a classe que irá dar suporte ao chart trade, e destruir este mesmo ponteiro. Mesmo assim teremos o comportamento visto no vídeo 01.

Acredito que você, não terá dificuldades em compreender nenhuma linha do código do indicador. Talvez a única que dê um pouco mais de trabalho é a linha 15. Mas mesmo ela ainda assim é bem simples. Já que estamos usando dois operadores new de maneira a inicializar ambas as classes.

O único detalhe que você deve se atentar, é com relação a informação passada como sendo strings. A primeira string se refere ao nome que será reconhecido pelo MetaTrader 5, quando o indicador estiver no gráfico. Já a segunda string, se refere ao nome que o indicador de mouse tem. Isto é definido no código do indicador de mouse. Para mais detalhes veja o artigo: Desenvolvendo um sistema de Replay (Parte 41): Iniciando a segunda fase (II).

Agora que você já viu, o qual simples é o código do indicador Chart Trade. Vamos ver o código da classe. Lembrando que o código a ser visto, será o código inicial. Ele ainda irá passar por adições, a fim de tornar o indicador realmente funcional.


A classe C_ChartFloatingRAD

Apesar do nome, esta classe será voltada para trabalhar basicamente com o indicador Chart Trade. No atual estágio de desenvolvimento ela já contém toda a lógica necessária para que tenhamos um comportamento idêntico ao visto no vídeo 01. Ou seja, caso estejamos efetuando um estudo, não poderemos mover a janela, mesmo quando clicamos nela e arrastamos o mouse. Durante um estudo não será possível mover a janela.

Você pode estar achando, que foi preciso criar um verdadeiro esquema para se conseguir isto. Assim como criar a imagem vista no vídeo, onde já temos a aparência final do indicador. Bem, vamos então ver se isto é verdade. Para isto bastará olhar o código da classe. Este pode ser observado na integra logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #include "../Auxiliar/C_Terminal.mqh"
05. #include "../Auxiliar/C_Mouse.mqh"
06. //+------------------------------------------------------------------+
07. class C_ChartFloatingRAD : private C_Terminal
08. {
09.     private :
10.             struct st00
11.             {
12.                     int     x, y, cx, cy;
13.                     string  szObj_Chart;
14.                     long    WinHandle;
15.             }m_Info;
16. //+------------------------------------------------------------------+
17.             C_Mouse *m_Mouse;
18. //+------------------------------------------------------------------+
19.             void CreateWindowRAD(int x, int y, int w, int h)
20.                     {
21.                             m_Info.szObj_Chart = (string)ObjectsTotal(GetInfoTerminal().ID);
22.                             ObjectCreate(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJ_CHART, 0, 0, 0);
23.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XDISTANCE, m_Info.x = x);
24.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YDISTANCE, m_Info.y = y);
25.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XSIZE, w);
26.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YSIZE, h);
27.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_DATE_SCALE, false);
28.                             ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_PRICE_SCALE, false);
29.                             m_Info.WinHandle = ObjectGetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_CHART_ID);
30.                             m_Info.cx = w;
31.                             m_Info.cy = 26;
32.                     };
33. //+------------------------------------------------------------------+
34. inline void UpdateChartTemplate(void)
35.                     {
36.                             ChartApplyTemplate(m_Info.WinHandle, "IDE_RAD.tpl");
37.                             ChartRedraw(m_Info.WinHandle);
38.                     }
39. //+------------------------------------------------------------------+
40.     public  :
41. //+------------------------------------------------------------------+
42.             C_ChartFloatingRAD(string szShortName, C_Mouse *MousePtr)
43.                     :C_Terminal()
44.                     {
45.                             if (!IndicatorCheckPass(szShortName)) SetUserError(C_Terminal::ERR_Unknown);
46.                             m_Mouse = MousePtr;
47.                             CreateWindowRAD(0, 0, 170, 240);
48.                             UpdateChartTemplate();
49.                     }
50. //+------------------------------------------------------------------+
51.             ~C_ChartFloatingRAD()
52.                     {
53.                             ObjectDelete(GetInfoTerminal().ID, m_Info.szObj_Chart);
54.                             delete m_Mouse;
55.                     }
56. //+------------------------------------------------------------------+
57.             void DispatchMessage(const int id, const long &lparam, const double &dparam, const string &sparam)
58.                     {
59.                             static int sx = -1, sy = -1;
60.                             int x, y, mx, my;
61.     
62.                             switch (id)
63.                             {
64.                                     case CHARTEVENT_MOUSE_MOVE:
65.                                             if ((*m_Mouse).CheckClick(C_Mouse::eClickLeft))
66.                                             {
67.                                                     x = (int)lparam;
68.                                                     y = (int)dparam;
69.                                                     if ((x > m_Info.x) && (x < (m_Info.x + m_Info.cx)) && (y > m_Info.y) && (y < (m_Info.y + m_Info.cy)))
70.                                                     {
71.                                                             if (sx < 0)
72.                                                             {
73.                                                                     ChartSetInteger(GetInfoTerminal().ID, CHART_MOUSE_SCROLL, false);
74.                                                                     sx = x - m_Info.x;
75.                                                                     sy = y - m_Info.y;
76.                                                             }
77.                                                             if ((mx = x - sx) > 0) ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XDISTANCE, m_Info.x = mx);
78.                                                             if ((my = y - sy) > 0) ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YDISTANCE, m_Info.y = my);
79.                                                     }
80.                                             }else if (sx > 0)
81.                                             {
82.                                                     ChartSetInteger(GetInfoTerminal().ID, CHART_MOUSE_SCROLL, true);                                                
83.                                                     sx = sy = -1;
84.                                             }
85.                                             break;
86.                             }
87.                     }
88. //+------------------------------------------------------------------+
89. };
90. //+------------------------------------------------------------------+
91. 

Código fonte da classe C_ChartFloatingRAD

Mas é somente isto ?!?! Cadê os código de criação de objetos ?!?! Manipulação do mouse ?!?!

Não estou acreditando, que estes dois simples códigos, visto até aqui, são de fato capazes de fazer o que estou vendo no vídeo 01. Você esta fazendo uma pegadinha com todos nos. Confesse. Não. Não estou fazendo nenhuma pegadinha. De fato apenas estas poucas linhas são capazes de fazer com que aquela janela vista na figura 01, tenha o comportamento visto no vídeo 01.

Você pode efetuar estudos usando o mouse. Pode clicar e arrastar a janela do Chart Trade. Isto tudo usando apenas e somente este código. Existem algumas coisas que ainda serão adicionadas neste código da classe. Isto para tornar a janela funcional, a fim de que o ativo possa ser mostrado. Os botões se tornem funcionais e possamos editar os valores, que ainda não estão presente. De fato ainda falta algumas coisas a serem feitas. Mas não esperem de maneira alguma ver aqueles objetos sendo criados aqui. Irei usar uma forma diferente de tornar esta janela funcional. Mas isto será visto no próximo artigo.

Mas calma lá. Ainda não terminamos. Para que você consiga de fato entender o que está acontecendo, vamos ver a explicação do código da classe. E por que ela tem exatamente este código.

Vamos começar pela linha 07. Observem que a classe C_ChartFloatingRAD, está herdando a classe C_Terminal. Porém como sempre devemos começar dando o mínimo privilégio as heranças, fazemos a herança privativa. Assim nenhum outro código terá acesso a classe C_Terminal. Pelo menos não via a classe C_ChartFloatingRAD. Mas isto não nos é problema. Já que o código do indicador de fato não faz nenhuma menção a qualquer código da classe C_Terminal.

Uma vez entendido este ponto, podemos passar para o constructor. Assim o fluxo de execução será mais facilmente compreendido.

O constructor tem inicio na linha 42. Observem o fato de que ele irá receber uma string e um objeto, na verdade um ponteiro, para referenciar a o indicador de mouse. Pois bem, na linha 43, fazemos a inicialização exigida da classe C_Terminal. Entrando de fato no código do constructor, a partir da linha 45, onde fazemos uma chamada ao código de checagem, a fim de garantir que o indicador Chart Trade, não está presente no gráfico. Se esta checagem falhar iremos indicar isto na constante _LastError. Para fazer isto usamos a chamada SetUserError.

Agora preste bastante atenção a uma coisa. Se você não entender o que irei explicar irá ficar completamente perdido, pelo resto desta sequencia de artigos. Então bastante atenção ao que irei explicar.

Na linha 46, armazenamos o ponteiro que foi passado via chamada ao operador new. Isto lá no código do indicador Chart Trade. Você pode ver esta chamada, ao observar a linha 15 do código do indicador. NÃO IMPORTA o fato do indicador de mouse, está ou não presente no gráfico, no momento que a linha 46 for executada. Vou repetir pois é importante: NÃO IMPORTA o fato do indicador está ou não presente no gráfico no momento da chamada.

O que de fato importa, e isto é que muitos podem não entender. É o nome que está sendo informado, na chamada vista na linha 15, do código do indicador Chart Trade. Aquela string que está sendo passada para o constructor da classe C_Mouse. Aquilo sim importa. O fato do indicador está ou não no gráfico, pouco interfere ou importa.

Você pode estar pensando que isto não faz sentido. Mas faz. Para entender é preciso voltar ao artigo anterior Desenvolvendo um sistema de Replay (Parte 41): Iniciando a segunda fase (II), e observar a linha 169 no código da classe C_Mouse. Aquela linha, e apenas aquela linha é que irá fazer com que este código, visto na classe C_ChartFloatingRAD, consiga fazer o seu trabalho de maneira adequada. Por conta disto é que precisamos informar corretamente o nome do indicador de mouse. Isto para que a plataforma MetaTrader 5, consiga encontra-lo quando for necessário para executar a linha 169 na classe C_Mouse.

Talvez isto ainda esteja confuso. Mas vamos continuar a explicação sobre como o código funciona. Iremos voltar neste ponto um pouco mais a frente, de maneira a deixar as coisas mais claras.

Pois bem, na linha 47, efetuamos uma chamada a função que se encontra presente na linha 19. Esta função na linha 19, nada mais é do que um procedimento que irá criar um objeto OBJ_CHART no gráfico. Somente isto. No entanto, na linha 29, iremos armazenar a ID deste objeto. Isto para que possamos depois usá-lo de uma maneira muito especifica. Acredito que ninguém irá de fato ter dificuldade em entender as demais linhas deste procedimento.

Então voltando ao código do constructor, temos na linha 48, uma outra chamada. Esta irá executar o procedimento presente na linha 34. Dentro deste procedimento, no momento, temos 2 linhas. A linha 36 irá buscar o template que estamos indicado. Este template é exatamente o que é visto na figura 01. E na linha 37, forçamos o MetaTrader 5 a atualizar o objeto OBJ_CHART, a fim de que o template seja mostrado.

Desta maneira temos assim a apresentação do nosso Chart Trade. É bem verdade que ele não está funcional. Mas, porém, toda via e entretanto, já poderemos fazer algum tipo de "manipulação" a fim de compreender a forma de interação entre o indicador de mouse e o indicador Chart Trade.

O código do destructor é bastante simples, não necessitando de nenhuma explicação especial. Mas temos que dar uma boa olhada no código de tratamento de mensagens: O procedimento DispatchMessage, este inicia na linha 57. E é neste ponto que teremos a interação entre os dois indicadores.

Basicamente neste momento, a única coisa que estaremos de fato tratando é o evento de movimentação de mouse. Isto tem inicio na linha 64. Mas atenção, não iremos tratar o evento de mouse da maneira convencional. Iremos tratar ele de uma forma totalmente e completamente diferente. Isto para aqueles que estão acostumados a programar as coisas de um determinada maneira, o que será visto aqui é algo muito louco. Ou como alguns dizem: " Muy loco 😂".

Para conseguir compreender tudo, e por isto não estou mostrando outras coisas neste artigo. Você irá precisar recorrer ao artigo anterior, Desenvolvendo um sistema de Replay (Parte 41): Iniciando a segunda fase (II). Já que iremos estar tratando não de um, mas de dois indicadores ao mesmo tempo. E eles estão se comunicando a fim de que possam viver em harmonia, e o usuário possa fazer as coisas como mostrado no vídeo 01.

Neste código de tratamento de mensagens do indicador Chart Trade, estarei fazendo menção a apenas e somente uma única vez ao indicador de mouse. Esta menção é feita na linha 65. Preste bastante atenção para entender o que está acontecendo. Pois se você entender isto, o restante será moleza.

Existe duas situações aqui. A primeira é quando o indicador de mouse se encontra no gráfico. A segunda é quando o indicador não se encontra no gráfico. Lembrando que ele, deverá ter o nome, que estamos indicando no constructor da classe C_ChartFloatingRAD. Caso o nome seja diferente o MetaTrader 5 não irá nos ajudar, e teremos a situação onde o indicador não está no gráfico. Atenção a este detalhe.

Uma vez que isto já esteja separado, e você esteja ciente destas duas situações. Podemos começar a explicação.

Quando isto acontece, a chamada da linha 65, irá executar a chamada da linha 158 da classe C_Mouse ( Artigo anterior ). Já que na linha 15 do código do indicador Chart Trade, dizemos ao constructor da classe C_Mouse, de que iremos usar a classe C_Mouse como tradutora. A linha 158 da classe C_Mouse, irá chamar a linha 163, para verificar se ocorreu um clique com o botão indicado na linha 65 da classe C_ChartFloatingRAD.

No momento que a linha 165 for se executada na classe C_Mouse. O código irá perceber que estaremos fazendo uso do tradutor. Assim iremos executar a linha 169 a fim de capturar o handle do indicador do mouse. É neste exato momento, que iremos pedir auxilio ao MetaTrader 5, por conta disto que os nomes indicados tem que ser os mesmos. Caso o MetaTrader 5 encontre o indicador que estamos nos referindo, o handle terá o index para acessar o buffer do indicador. Se o buffer poder ser lido, a linha 172 irá capturar os dados do indicador de mouse. Se o buffer não poder ser lido a função irá falhar, fazendo com que a função na linha 158 também falhe. Resultando na falha do teste presente na linha 65 da classe C_ChartFloatingRAD. Assim teremos a indicação de que o clique não ocorreu.

Toda esta logica, irá funcionar em duas situações:

  • O indicador de mouse não esteja presente no gráfico. Lembrando que ele deverá ter o mesmo nome indicado, isto para que o MetaTrader 5 o encontre.
  • Estejamos efetuando um estudo no gráfico, usando para isto o indicador de mouse.

Em qualquer uma destas duas situações a linha 65 da classe C_ChartFloatingRAD, irá indicar falha no clique do mouse.

Achou confuso esta parte ?!?! Calma, a coisa fica ainda mais interessante.

Vamos agora analisar a situação, onde o MetaTrader 5 encontrou o indicador de mouse, e que queremos de fato arrastar o indicador Chart Trade pelo gráfico. Assim como pode ser visto no video 01. Para entender de fato como isto irá acontecer. É preciso que você tenha compreendido os seguintes artigos:

Cada um destes artigos esta preparando, você para o que está por vim. Se você não os leu, ou não compreendeu o conteúdo dos mesmos. Sugiro que retorne a eles e entenda como a comunicação está se dando. Pois apesar de parecer simples, tais conceitos, quando colocados na prática, se tornam bastante complexos de serem entendidos, por aqueles que não fazem uso de tais praticas.

O que estou mostrando aqui é a parte mais simples de todas. O que irá vim mais pela frente, faz isto daqui ser o jardim de infância. Então é preciso que você de fato, consiga compreender como este código daqui está funcionando.

De qualquer maneira, em algum momento, a chamada presente na linha 65 da classe C_ChartFloatingRAD, irá encontrar a chamada presente na linha 181 presente na classe C_Mouse. Quando isto acontecer, a linha 160, na classe C_Mouse, irá testar o código de botão repassado para ela. Se o código bater com o repassado, a função irá retornar um valor verdadeiro. Neste momento, e durante todo o tempo que o botão do mouse estiver pressionado, teremos a execução do código presente entre as linhas 67 a 79.

Existe uma pequena falha, neste código. Mas já que ele é apenas para demonstração, podemos deixar passar por hora.

Agora temos uma questão. Por que nas linhas 67 e 68, estou usando os valores informados pelo MetaTrader 5 e não pelo indicador de mouse ?!?! Isto tem um motivo. Não estou fazendo isto, por parecer mais bonito, ou mais fácil. Existe sim um motivo, para usar os valores informados pelo MetaTrader 5, e não os do indicador. Para entender isto você tem que olhar na classe C_Mouse, o código presente entre as linhas 203 e 206. No meio destas linhas, incluindo as mesmas fazemos uma conversão, transformação e um ajuste nos pontos de coordenadas do mouse. Por fazer tais coisas, as coordenadas do mouse, deixam de ser do tipo tela ( x e y ) e passa a ser do tipo ativo ( preço e tempo ).

Este tipo de coisa é muito boa e bastante útil para se trabalhar com determinados tipos de coisas. Mas é uma coisa chata, quando precisamos trabalhar de outra maneira. Se você usar nas linhas 67 e 68 da classe C_ChartFloatingRAD, um código como mostrado abaixo:

x = (*m_Mouse).GetInfoMouse().Position.X;
y = (*m_Mouse).GetInfoMouse().Position.Y;

Irá ter uma movimentação do objeto OBJ_CHART como se ele fosse ancorado nas coordenadas de ativo ( preço e tempo ). Quando na verdade tal objeto usa coordenadas de tela ( x, y ). Por conta disto, o movimento ficaria bastante estranho, não tendo a mesma suavidade vista no video 01. Mas para alguns tipos de coisas, é de fato desejável usar as coordenadas informadas pelo indicador mouse.


Conclusão

Neste artigo, mostrei como fazer para produzir a primeira etapa do indicador Chart Trade. Nele mostrei, como você pode usar o indicador de mouse, em perfeita harmonia, com o indicador Chart Trade que estamos criando. É verdade que o indicador Chart Trade ainda não tem nenhuma funcionalidade, além do fato de poder ser arrastado no gráfico.

No próximo artigo iremos começar a dar funcionalidade a este indicador Chart Trade.


Arquivos anexados |
Anexo.zip (420.65 KB)
Força bruta para encontrar padrões (Parte VI): otimização cíclica Força bruta para encontrar padrões (Parte VI): otimização cíclica
Neste artigo, mostrarei a primeira parte das melhorias que me permitiram não apenas fechar todo o ciclo de automação para negociação no MetaTrader 4 e 5, mas também fazer algo muito mais interessante. A partir de agora, esta solução me permite automatizar completamente tanto o processo de criação de EAs quanto o processo de otimização, além de minimizar o esforço necessário para encontrar configurações de negociação eficazes.
GIT: Mas que coisa é esta ? GIT: Mas que coisa é esta ?
Neste artigo apresentarei uma ferramenta de suma importância para quem desenvolve programas. Se você não conhece GIT, veja este artigo para ter uma noção do que se trata, tal ferramenta. E como usá-la junto ao MQL5.
Redes neurais de maneira fácil (Parte 55): Controle interno contrastivo (CIC) Redes neurais de maneira fácil (Parte 55): Controle interno contrastivo (CIC)
O aprendizado contrastivo é um método de aprendizado de representação sem supervisão. Seu objetivo é ensinar o modelo a identificar semelhanças e diferenças nos conjuntos de dados. Neste artigo, discutiremos o uso de abordagens de aprendizado contrastivo para explorar diferentes habilidades do Ator.
Testes de permutação de Monte Carlo no MetaTrader 5 Testes de permutação de Monte Carlo no MetaTrader 5
Este artigo explora o uso de testes de permutação, aplicando-os a qualquer Expert Advisor através da reorganização de dados de ticks, recorrendo exclusivamente aos recursos disponíveis no MetaTrader 5.