preview
Do básico ao intermediário: Eventos de mouse

Do básico ao intermediário: Eventos de mouse

MetaTrader 5Exemplos |
85 0
CODE X
CODE X

Introdução

No artigo anterior Do básico ao intermediário: Ponteiro para função, falamos sobre como implementar eventos em um script. Mas principalmente foi falado como podemos utilizar um tipo muito especial de dado. O conhecido ponteiro. Como quero e pretendo que você meu caro leitor, estude com muita calma o que foi mostrado no artigo anterior. Pois aquele tipo de coisa é muito importante. Principalmente se você pretende se aprofundar em programação que faz uso de objetos gráficos. Vamos focar em outra coisa, um pouco mais simples neste atual artigo.

O tema principal aqui será objetos e eventos de mouse. Para tornar as coisas devidamente separadas, vamos começar com o que será o primeiro tópico deste artigo.


Eventos de mouse

Bem, vamos começar entendendo uma coisa: O mouse, é um ser abestado, chato, horroroso e saído do mais profundo dos infernos. Sendo algo completamente aleatório e sem nenhum tipo de consideração, tanto para o código, quanto para o programador. Apesar de ser algo muito útil e que nos permite ter bastante agilidade ,quando a questão envolve interface gráfica. Porém apesar de tudo, o MetaTrader 5, por padrão não gera eventos de mouse para alguma aplicação que esteja sendo executada na plataforma. Mas por que? O motivo é justamente o fato de que o MetaTrader 5, tem como foco ser uma plataforma com uma excelente performance e desempenho. E o mouse, bem, o mouse acaba atrapalhando isto. Principalmente quando aplicações colocadas no gráfico, tentem a ser muito mal otimizadas para eventos relacionados ao mouse.

Talvez você, meu caro e estimado leitor, não tem a devida noção, do quanto eventos de mouse são um problema, caso uma aplicação esteja mal otimizada, para tratar e lidar com eventos de mouse. Porém no decorrer dos  artigos, iremos ver isto mais de perto. Mas antes precisamos entender outras coisas.

A primeira das coisas, a ser entendida será, algo que você possa estar pensando: Ok, meu bom amigo autor, acho que você pode estar equivocado, quanto ao uso do mouse na plataforma. Já que quando pressionamos o botão direito em um gráfico, temos acesso a uma coleção de coisas que podemos utilizar ali de imediato. Além disto, também podemos enviar e manipular ordens usando para isto o recurso de One Click do MetaTrader 5. Então está de falar que o mouse é um problema, não passa de pura falta de conhecimento da sua parte.

Ok, devo concordar com você. Você de fato está correto nesta declaração, meu caro leitor. Porém, eu não disse que o mouse é um problema para a plataforma. Eu disse que o mouse é um problema para aplicações que estejam rodando em um gráfico. Ainda mais quando o tratador de eventos de tal aplicação esteja mal otimizado. Ou no mínimo, muito bagunçado. E quanto maior o código, maior é a bagunça. Por isto procuro sempre criar códigos que são relativamente curtos e sempre buscando a simplicidade acima de tudo. E o motivo é justamente este. Evitar ter um código mal otimizado, por conta de alguma negligência da minha parte.

Próximo ponto: Como por padrão, o MetaTrader 5, não dispara eventos de mouse para aplicações rodando em um gráfico. Somos sempre levados a implantar código que garante, ou diz ao MetaTrader 5, que desejamos receber eventos de mouse. E uma fez registrado que um gráfico deverá receber eventos vindos do mouse. Você, como programador, quando implementar um código, que ligou o evento de mouse, junto ao MetaTrader 5, precisa dizer a ele, quando a aplicação for encerrada, que eventos de mouse deverão ser desligados.

O que na maior parte das vezes não acontece. Isto faz com que o MetaTrader 5, continue disparando eventos de mouse para o gráfico. Já que sua aplicação não desligou o que a via ligado novamente. Então seja educado e organizado. Se ligou, desligue. Não espere que a plataforma dê um jeito de resolver o problema para você.

Próximo ponto, não procure ligar, ou usar, mais recursos do que o necessário. Existem pequenas diferenças entre os eventos que o MetaTrader 5, faz ao disparar eventos de mouse. Se sua aplicação não precisa utilizar certos recursos, não os ligue. Mantem o simples e o básico. Somente ligue aquilo que você realmente precisa usar.

Ok, esta breve introdução, apesar de parecer um pouco grosseira. Precisa ser de fato colocada e exposta de forma clara. Isto para que você, que está aprendendo a programar, comece sua carreira da forma correta. Já vi muita gente fazer coisas, além do necessário, e depois ficar reclamando por conta que o programa está lento ou não está performando como esperado.

Quando vamos olhar para ver o que está acontecendo, acabamos notando que o problema é o excesso de recursos alocados de maneira completamente desnecessária. Removendo as partes desnecessárias, a aplicação, como mágica, passa a ter uma performance dentro do esperado. E não estou me referindo necessariamente a programas voltados ao MetaTrader 5. Estou falando de uma forma generalizada.

Beleza, então vamos começar, tendo em vista, que eventos de mouse somente podem ser capturados pelo tratador OnChartEvent. Sendo assim, apenas dois tipos de aplicação podem capturar eventos de mouse. Um seria o Expert Advisor, que iremos tratar mais no futuro. E o outro seria um indicador. Mas tudo que for tido aqui, também se aplica ao Expert Advisor, já que será tudo direcionado ao tratador de eventos OnChartEvent. É importante que você entenda isto, meu caro leitor, para que não fique pensando: Poxa, você explicou sobre como trabalhar com o mouse em um indicador. Porém ainda não explicou como fazer isto em um Expert Advisor.

Tudo começa de fato, com o código logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_Prefix  "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.     IndicatorSetString(INDICATOR_SHORTNAME, def_Prefix);
09. 
10.     return INIT_SUCCEEDED;
11. };
12. //+------------------------------------------------------------------+
13. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
14. {
15.     return rates_total;
16. };
17. //+------------------------------------------------------------------+
18. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
19. {
20.     switch (id)
21.     {
22.         case CHARTEVENT_MOUSE_MOVE:
23.             break;
24.         case CHARTEVENT_MOUSE_WHEEL:
25.             break;
26.     }
27. };
28. //+------------------------------------------------------------------+
29. void OnDeinit(const int reason)
30. {
31. };
32. //+------------------------------------------------------------------+

Código 01

Aqui temos o que poderíamos chamar de esqueleto básico de um indicador, que irá utilizar o mouse em suas operações. Preste atenção ao seguinte fato: Dentro do tratador de eventos OnChartEvent, temos dois tipos de eventos de mouse podendo ser capturados. O primeiro é o que se encontra na linha 22 e o segundo na linha 24. O fato de você estar utilizando um evento, ou outro não interfere na forma como o código irá ser executado ou compilado. No entanto, da forma como este código se encontra, nenhum destes dois eventos irá em momento algum ser disparado pelo MetaTrader 5. Isto por que, ambos estão desligados, por padrão. Para que OnChartEvent receba um destes dois eventos, precisamos ligar o tipo de evento que queremos receber.

Ligar e desligar estes eventos é algo muito simples e fácil de ser feito. Porém, toda via e, entretanto, a forma de lidar com estes eventos é um pouco diferente. Sendo que o evento CHARTEVENT_MOUSE_WHEEL, que por algum motivo, tem um funcionamento ligeiramente diferente do que seria o evento CHARTEVENT_MOUSE_MOVE. Mas não se preocupe com isto neste momento. Logo você entenderá e estará se divertindo. Pensando em como utilizar o mouse, em cada vez mais aplicações de diferentes maneiras. Pois de fato, ele é uma ferramenta muito útil e versátil sem bem programado. Ainda mais em uma plataforma gráfica.

Muito bem, para que possamos ver o mouse em ação e assim entender diversas outras coisas, que são mais simples de se entender, quando as vemos acontecer. Vamos ligar um dos eventos de mouse, e ao mesmo tempo, vamos imprimir algumas coisas diretamente no gráfico. Assim você irá aprender na prática como a coisa realmente funciona. Para isto, vamos modificar o código 01 para o código 02 visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_Prefix  "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.     IndicatorSetString(INDICATOR_SHORTNAME, def_Prefix);
09.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
10. 
11.     return INIT_SUCCEEDED;
12. };
13. //+------------------------------------------------------------------+
14. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
15. {
16.     return rates_total;
17. };
18. //+------------------------------------------------------------------+
19. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
20. {
21.     string sz = "";
22. 
23.     switch (id)
24.     {
25.         case CHARTEVENT_MOUSE_MOVE:
26.             Comment(sz);
27.             sz += "Mouse position X: " + (string)(short)lparam;
28.             sz += "\nMouse position Y: " + (string)(short)dparam;
29.             Comment(sz);
30.             break;
31.         case CHARTEVENT_MOUSE_WHEEL:
32.             break;
33.     }
34. };
35. //+------------------------------------------------------------------+
36. void OnDeinit(const int reason)
37. {
38.     Comment("");
39.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, false);
40. };
41. //+------------------------------------------------------------------+

Código 02

Quando este código 02 for executado em um gráfico, você irá ver o resultado parecido com o visto na animação logo abaixo.

Animação 01

Observe no canto superior esquerdo que conforme movemos o mouse, a indicação de onde ele está irá mudar. Porém, existem regiões onde a indicação não mudará. Por que? O motivo é que estas regiões que você nota que a indicação de posição não muda, estará fora do que é considerado região da área cliente.

E sim meu cara leitor, uma janela gráfica é dívida em regiões. Este tipo de coisa, é vista quando se estuda programação para ambientes gráficos, como programação para criar aplicações Windows por exemplo. Sendo algo com muitos detalhes envolvidos. No entanto, irei tentar simplificar ao máximo o que precisa ser explicado. De maneira, que você venha a saber o que realmente é importante aqui para programar em MQL5.

Em uma interface gráfica, como é o caso do sistema operacional Windows, temos uma imensa região chamada Desktop. Ou para os leigos, área de tela. Cada pixel desta região corresponde a uma posição nesta chamada área de Desktop. Ok, dentro desta região temos inicialmente duas outras. Uma que é a região onde está a barra de tarefas e a outra que é a região onde as janelas das aplicações irão ficar. Não importa se você suas configurações irão ou não ocultar esta região que seria a barra de tarefas. Qualquer coisa fora dela, é considerada região de aplicação.

Ok, para tornar a coisa mais plausível. Pense no seguinte exemplo: Suponhamos que você esteja em uma tela com 1920 x 1080 pixel, ou seja uma tela Full HD. Se a região da barra de tarefas ocupar 48 pixels. Então a área útil de sua tela será de 1920 x 1032 pixel. Então qualquer aplicação que esteja em uma janela maximizada, e com a barra de tarefas visível, irá poder ocupar estas dimensões informadas a pouco, ou seja, menos que a tela Full HD. O efeito é quase imperceptível. Mas como curiosidade, se você estiver olhando uma imagem de 1920 x 1080 pixel nesta tela um pouco menor, ela irá ficar levemente diferente, já que temos que compensar os 48 pixels faltantes.

Bem, dentro desta região cliente, que normalmente é configurada como sendo o quarto quadrante. E depois iremos falar mais sobre esta questão dos quadrantes. Podemos colocar janelas de programas. Esta janela tem também regiões. Sendo basicamente três regiões a serem consideradas. A primeira região é a barra de título, a segunda região é a borda da janela e a terceira região é a área de cliente.

Da mesma forma que o Desktop, estas janelas vão ficando cada vez menores. Já que cada região, que não faça parte da região cliente, irá remover área útil para podemos utilizar. A área onde realmente podemos utilizar, é justamente a que faz o valor da posição do mouse mudar, indo de 0 x 0, que fica no canto superior esquerdo até um máximo qualquer, que fica no canto inferior direito. Isto quando estamos usando o modelo de plotagem padrão, que fica no quarto quadrante.

Assim sendo, se você mover o mouse, para fora da região cliente de uma janela. Isto usando uma aplicação do MetaTrader 5. O mouse irá parar de responder aos eventos destinados a ele. Existe uma forma de contornar isto. Fazendo com que o mouse, continue a responder a eventos, mesmo fora da região cliente, da janela onde está o tratador de eventos. Mas isto é assunto para outro momento. Quem sabe no futuro eu venha a mostrar como fazer isto.

Mas então está é a parte mais simples e fácil de entender. Um detalhe: Não importa onde a janela cliente esteja posicionada. O MetaTrader 5, sempre irá corrigir os valores de posição de tela, a ponto de que a nossa aplicação continue achando que está utilizando toda aquela região, que pertence a tela principal. Ou seja, o desktop.

Ao fazer este ajuste para nós, o MetaTrader 5, nos poupa muito trabalho. Trabalho este que em um ambiente de programação diferente do MQL5, talvez você precisaria fazer na mão. A fim de evitar que a aplicação imaginasse estar recebendo eventos quando na verdade não deveria estar respondendo a eles.

Acho que deu para entender. Mas e quanto aos botões? Como podemos saber quando um ou outro botão foi pressionado? A questão dos botões é resolvida com uso de uma máscara. Sendo a forma mais simples, a utilização de alguma macro no código. Assim fica mais fácil programar e filtrar eventos diversos. Já que podemos estar clicando em algo e ao mesmo tempo arrastando este algo.

Agora antes de entrarmos nesta questão, note que na linha nove do código 02 ligamos e evento de mouse. Já na linha 39 deligamos o evento. E como as informações são colocadas em tipos de dados diferentes. Precisamos fazer com que as coisas venham a ser convertidas de maneira a mostrar valores adequados a nossa expectativa. Por isto, estamos usando as conversões explicitas de tipo, como pode ser visto nas linhas 27 e 28. Simples assim.


Botões do mouse

A questão dos botões do mouse, é um assunto um tanto quanto controverso. E o motivo é igualmente controverso. Alguns usuários talvez, imaginam ser simples criar coisas ligadas ao mouse. Porém na prática isto é um pouco mais complicado do que parece. Sendo o motivo, algo aparentemente estranho à primeira vista. Não é raro, muitas aplicações usarem os botões do mouse para objetivos particulares. Ou até mesmo o sistema operacional. No caso do MetaTrader 5, o botão do meio, é responsável por criar a cruz de analise simples. Já o botão da direita, abre um menu para manipulações e configurações diversas do gráfico.

Porém, pode ser que sua aplicação queira fazer uso destes mesmos botões para outros objetivos, também particulares. E isto gera um certo conflito de interesse, entre você, o usuário e o MetaTrader 5. E em alguns casos podemos incluir o sistema operacional nesta disputa. Bem com relação a parte que tange o MetaTrader 5, ele não se importa de que você, como programador, pegue estes botões emprestados para um uso qualquer, e por um dado período de tempo. Porém é de extremo mal gosto, você não os devolver, quando sua aplicação é removida do gráfico. Salvo o fato de ela quebrar. Neste caso não tem como.

Sua aplicação irá levar junto, aqueles botões que ela pegou emprestado. Impedindo que o usuário tenha acesso a eles durante aquele período de uso do MetaTrader 5, naquele gráfico especifico. Para reaver os botões, que sua aplicação tomou e não devolveu, por ter quebrado. O usuário terá que fechar o gráfico do ativo e o abrir novamente. Somente assim o MetaTrader 5, tomará novamente o controle daqueles botões. Por isto você, precisa tomar cuidado ao programar as coisas, meu caro leitor. Caso contrário irá ter, ou gerar, uma experiência de uso muito desagradável por parte do usuário de sua aplicação.

Certo, acho que conseguir compreender o problema. Mas e então, caso eu queira por qualquer motivo, tomar o controle dos botões da direita e do meio. Como devo proceder? E para devolver o controle destes mesmos botões ao MetaTrader 5, qual é o melhor caminho? Ok, estas são ótimas perguntas meu caro leitor. E aproveitando a deixa, vou explicar uma outra coisa, também bastante interessante. Nos artigos onde falei do evento de teclado, não mencionei o fato de que você também pode assumir um controle ainda maior sobre o teclado. Mas como iremos tomar o controle dos botões do mouse. Assim como o controle de outras coisas. Acho que é uma boa oportunidade, para mostrar como tomar o controle total, dos elementos de interação com o usuário. Isto é feito usando o código a logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_Prefix  "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.     IndicatorSetString(INDICATOR_SHORTNAME, def_Prefix);
09.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
10. //+----------------+    
11.     ChartSetInteger(0, CHART_MOUSE_SCROLL, false);
12.     ChartSetInteger(0, CHART_CONTEXT_MENU, false);
13.     ChartSetInteger(0, CHART_CROSSHAIR_TOOL, false);
14. //+----------------+
15.     ChartSetInteger(0, CHART_KEYBOARD_CONTROL, false);
16.     ChartSetInteger(0, CHART_QUICK_NAVIGATION, false);
17. //+----------------+
18. 
19.     return INIT_SUCCEEDED;
20. };
21. //+------------------------------------------------------------------+
22. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
23. {
24.     return rates_total;
25. };
26. //+------------------------------------------------------------------+
27. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
28. {
29.     string sz = "";
30. 
31.     switch (id)
32.     {
33.         case CHARTEVENT_MOUSE_MOVE:
34.             Comment(sz);
35.             sz += "Mouse position X: " + (string)(short)lparam;
36.             sz += "\nMouse position Y: " + (string)(short)dparam;
37.             Comment(sz);
38.             break;
39.         case CHARTEVENT_MOUSE_WHEEL:
40.             break;
41.     }
42. };
43. //+------------------------------------------------------------------+
44. void OnDeinit(const int reason)
45. {
46.     Comment("");
47.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, false);
48. //+----------------+    
49.     ChartSetInteger(0, CHART_MOUSE_SCROLL, true);
50.     ChartSetInteger(0, CHART_CONTEXT_MENU, true);
51.     ChartSetInteger(0, CHART_CROSSHAIR_TOOL, true);
52. //+----------------+
53.     ChartSetInteger(0, CHART_KEYBOARD_CONTROL, true);
54.     ChartSetInteger(0, CHART_QUICK_NAVIGATION, true);
55. //+----------------+
56. };
57. //+------------------------------------------------------------------+

Código 03

Este código 03, enquanto estiver sendo executado, irá impedir que o usuário venha a fazer uso de elementos, e controles definidos por padrão pelo MetaTrader 5. Como por exemplo, a cruz de analise simples, ou mesmo pressionar a tecla ENTER a fim de trocar atual ativo presente no gráfico. Então vamos entender como isto foi conseguido: Primeiro na linha 11, estamos dizendo ao MetaTrader 5 que o usuário não mais poderá arrastar o gráfico, a fim de visualizar barras que não estejam sendo mostradas. Para religar este tratamento padrão do MetaTrader 5, usamos a linha 49.

Na linha 12, estamos desligando o menu de contexto para o gráfico onde o código esteja executando. Este menu é acessado quando você pressiona o botão direito do mouse. Para religar este recurso padrão do MetaTrader 5, usamos a linha 50. Na linha 13, estamos desligando a cruz de analise simples, que é acessada quando pressionamos o botão do meio. Para religar este recurso, usamos a linha 51.

Agora na linha 15, estamos desligando os recursos ligados a movimentação, mudança de escala via teclado. Para religar isto novamente, usamos a linha 53. E finalmente na linha 16 estamos desligando aquele recurso, que permite ao usuário pressionar ENTER e digitar o nome de uma ativo, ou tempo gráfico. Para religar este mesmo recurso, usamos a linha 54.

Este tipo de código, é mais fácil de entender se você o utilizar de maneira direta. Experimentando o gráfico antes e durante a execução desta aplicação do código 03 no gráfico. Como no anexo, você terá acesso a este código como ele está sendo mostrado. Não vejo como tornar mais simples a sua experiência e aprendizado sobre como lidar com estes tipos de evento. Somente experimentando e vendo o que acontece, é que você conseguirá entender como resolver pequenos problemas. Digo isto, pois você pode ligar e desligar estes recursos a qualquer momento. Podendo ser interessante ligar os mesmo em dados momentos e os desligar em outros. De qualquer forma, aqui estamos apenas demonstrando os mesmos, com o objetivo de que tudo fique o mais didático possível.

Agora sim, podemos focar em uma questão mais abrangente. Que é a dos botões do mouse. Mas vamos adicionar também o teclado. Assim, você poderá experimentar todo o sistema de forma muito mais completa. Isto é feito usando o código logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_Prefix  "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.     IndicatorSetString(INDICATOR_SHORTNAME, def_Prefix);
09.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
10. //+----------------+    
11.     ChartSetInteger(0, CHART_MOUSE_SCROLL, false);
12.     ChartSetInteger(0, CHART_CONTEXT_MENU, false);
13.     ChartSetInteger(0, CHART_CROSSHAIR_TOOL, false);
14. //+----------------+
15.     ChartSetInteger(0, CHART_KEYBOARD_CONTROL, false);
16.     ChartSetInteger(0, CHART_QUICK_NAVIGATION, false);
17. //+----------------+
18. 
19.     return INIT_SUCCEEDED;
20. };
21. //+------------------------------------------------------------------+
22. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
23. {
24.     return rates_total;
25. };
26. //+------------------------------------------------------------------+
27. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
28. {
29.     string sz = "";
30. 
31.     switch (id)
32.     {
33.         case CHARTEVENT_KEYDOWN:
34.             Comment(sz);
35.             sz += "Key press: " + (string)lparam;
36.             Comment(sz);
37.             break;
38.         case CHARTEVENT_MOUSE_MOVE:
39.             Comment(sz);
40.             sz += "Mouse position X: " + (string)(short)lparam;
41.             sz += "\nMouse position Y: " + (string)(short)dparam;
42.             sz += StringFormat("\nHexadecimal mask of mouse buttons is: 0x%02X", (uchar)sparam);
43.             Comment(sz);
44.             break;
45.         case CHARTEVENT_MOUSE_WHEEL:
46.             break;
47.     }
48. };
49. //+------------------------------------------------------------------+
50. void OnDeinit(const int reason)
51. {
52.     Comment("");
53.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, false);
54. //+----------------+    
55.     ChartSetInteger(0, CHART_MOUSE_SCROLL, true);
56.     ChartSetInteger(0, CHART_CONTEXT_MENU, true);
57.     ChartSetInteger(0, CHART_CROSSHAIR_TOOL, true);
58. //+----------------+
59.     ChartSetInteger(0, CHART_KEYBOARD_CONTROL, true);
60.     ChartSetInteger(0, CHART_QUICK_NAVIGATION, true);
61. //+----------------+
62. };
63. //+------------------------------------------------------------------+

Código 04

Como este código 04, assim como o código 03, pode acabar estressando muito iniciante. Vamos primeiro ver como finalizar ou remover ele de um gráfico. Já que você não poderá fazer isto, da maneira que possivelmente deve estar acostumado a fazer com outros indicadores. Para conseguir encerrar este código que você pode ver logo acima, onde existe um bloqueio total das atividades, que são o padrão do MetaTrader 5. Você, meu caro leitor, precisará acessar o que é visto na imagem logo abaixo.

Imagem 01

Selecionando esta opção vista na imagem 01 no MetaTrader 5. No caso de estamos usando um indicador com bloqueio total. Caso seja um Expert Advisor, você precisará acessar Expert List. Quando fizer isto, você terá acesso a lista de indicadores ou Expert Advisores presentes no gráfico, ou abertos na plataforma. Assim conseguirá remover eles do gráfico. Algo que de outra maneira não seria possível de ser feita. Já que bloqueamos completamente o acesso do usuário, a todo e qualquer coisa que seria o padrão utilizado no MetaTrader 5.

Ok, explicado isto. Agora vamos ver uma apresentação demo logo abaixo do que o código 04 faz.

Animação 02

É importante você notar o seguinte meu caro leitor: Esta apresentação vista na animação 02, tem como objetivo apenas, como o mouse e o teclado seria interpretado pelo MQL5. É imprescindível que você experimente este indicador que vemos no código 04, de maneira a entender o que a combinação de botões e teclado podem fazer. Isto por que é um tanto quanto difícil explicar certas coisas, por mais que elas aparentemente possam parecer simples. O ideal é você experimentar e entender como as coisas podem ser combinadas.

Mas ao visualizar a combinação entre botões, e teclado, você irá notar que esta linha 42 vista no código 04, as vezes, irá mostrar um resultado, e em outros casos iremos ver outro resultado. Parece um tanto estranho. Mas isto acontece quando pressionamos as teclas SHIFT e/ou CTRL. Estas duas teclas tem uma característica interessante. Quando você as pressionar, sem mexer no mouse, irá notar que elas serão apresentadas devido a linha 35.

Porém, se você mexer no mouse, o MetaTrader 5 irá disparar um evento que irá acionar a linha 42. Porque? O motivo é que estas duas teclas, SHIFT e CTRL, estão ligadas ao mouse, fazendo parte da máscara de bits. Entender isto, permitirá a você criar certas coisas que de outra forma seria muito mais complicado de serem feitas. Portanto, é muito importante, que se você realmente queira entender como o mouse e o teclado funcionam no MQL5, procure estudar os resultados apresentados por este código 04.

Porém ainda falta falar de um outro tipo de evento. E este é o que é acionado pela linha 45 do no código 04. Mas este evento da roda do mouse, é um evento um tanto quanto estranho por assim dizer. Pelo menos aqui no MQL5. Já que ele é disparado e tem uma composição de dados um pouco diferente do que você poderia esperar. Talvez por isto, ele não seja tão utilizado assim, aqui em aplicações escritas em MQL5.

Para entender isto, vamos adicionar ao tratador de eventos, o código necessário para podermos visualizar esta diferença que existe entre CHARTEVENT_MOUSE_MOVE e CHARTEVENT_MOUSE_WHEEL. E acredite, é algo realmente bem interessante de ser visto na prática. Assim, o código que será utilizado é visto logo abaixo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. #define def_Prefix  "Demo"
05. //+------------------------------------------------------------------+
06. int OnInit()
07. {
08.     IndicatorSetString(INDICATOR_SHORTNAME, def_Prefix);
09.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
10.     ChartSetInteger(0, CHART_EVENT_MOUSE_WHEEL, true);
11. //+----------------+    
12.     ChartSetInteger(0, CHART_MOUSE_SCROLL, false);
13.     ChartSetInteger(0, CHART_CONTEXT_MENU, false);
14.     ChartSetInteger(0, CHART_CROSSHAIR_TOOL, false);
15. //+----------------+
16.     ChartSetInteger(0, CHART_KEYBOARD_CONTROL, false);
17.     ChartSetInteger(0, CHART_QUICK_NAVIGATION, false);
18. //+----------------+
19. 
20.     return INIT_SUCCEEDED;
21. };
22. //+------------------------------------------------------------------+
23. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
24. {
25.     return rates_total;
26. };
27. //+------------------------------------------------------------------+
28. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
29. {
30.     string sz = "";
31. 
32.     switch (id)
33.     {
34.         case CHARTEVENT_KEYDOWN:
35.             Comment(sz);
36.             sz += "Key press: " + (string)lparam;
37.             Comment(sz);
38.             break;
39.         case CHARTEVENT_MOUSE_MOVE:
40.             Comment(sz);
41.             sz += " **** Chart Event Mouse Move ****";
42.             sz += "\nMouse position X: " + (string)(short)lparam;
43.             sz += "\nMouse position Y: " + (string)(short)dparam;
44.             sz += StringFormat("\nHexadecimal mask of mouse buttons is: 0x%02X", (uchar)sparam);
45.             Comment(sz);
46.             break;
47.         case CHARTEVENT_MOUSE_WHEEL:
48.             Comment(sz);
49.             sz += " **** Chart Event Mouse Wheel ****";
50.             sz += "\nMouse position X: " + (string)(short)lparam;
51.             sz += "\nMouse position Y: " + (string)(short)(lparam >> 16);
52.             sz += "\nMouse Delta: " + (string) dparam;
53.             sz += StringFormat("\nHexadecimal mask of mouse buttons is: 0x%02X", (uchar)(lparam >> 32));
54.             Comment(sz);
55.             break;
56.     }
57. };
58. //+------------------------------------------------------------------+
59. void OnDeinit(const int reason)
60. {
61.     Comment("");
62.     ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, false);
63.     ChartSetInteger(0, CHART_EVENT_MOUSE_WHEEL, false);
64. //+----------------+    
65.     ChartSetInteger(0, CHART_MOUSE_SCROLL, true);
66.     ChartSetInteger(0, CHART_CONTEXT_MENU, true);
67.     ChartSetInteger(0, CHART_CROSSHAIR_TOOL, true);
68. //+----------------+
69.     ChartSetInteger(0, CHART_KEYBOARD_CONTROL, true);
70.     ChartSetInteger(0, CHART_QUICK_NAVIGATION, true);
71. //+----------------+
72. };
73. //+------------------------------------------------------------------+

Código 05

E aqui está meu caro leitor. Este código 05, fecha o que quero mostrar neste artigo. Observe que aqui não estou fazendo nenhum tipo de manipulação a fim de trabalhar com o mouse ou o teclado. Estamos fazendo uso de algo que é limpo, simples e direto. Isto para que você de fato consiga entender o que está acontecendo. Ao usar este código 05, você poderá ver algo parecido com o que é visto na animação logo abaixo.

Animação 03

Note que entre o código 04 e este código 05, existe muita pouca diferença. Mas esta pouca diferença que existe, de fato faz com que tenhamos um código com finalidade muito diferente entre si. Na linha 10 deste código 05, ligamos o evento a fim de receber qualquer tipo de movimento que o usuário venha a fazer na roda do mouse. Assim como na linha 63, desligamos o recebimento destes mesmos eventos. Porém, quero chamar a sua atenção, meu caro leitor, para o que é visto no tratador de eventos. Pois ali temos uma diferença crucial.

Observe que o tratador de CHARTEVENT_MOUSE_WHEEL se parece muito com o CHARTEVENT_MOUSE_MOVE. Porém, note de onde vem os valores? A localização dos valores, de posição, e botões pressionados é diferente em ambos os casos. Mas, e é aqui onde realmente a diferença de torna de fato muito grande. Você SOMENTE IRÁ RECEBER UM EVENTO CHARTEVENT_MOUSE_WHEEL, se e somente se, houver algum evento na roda do mouse. Fora isto, todos os eventos serão direcionados ao CHARTEVENT_MOUSE_MOVE. Por isto, é tão pouco comum, vermos aplicações ou códigos usando o evento CHARTEVENT_MOUSE_WHEEL. Isto por que, não recebemos atualização de outras condições do mouse, como movimento, ou pressionar dos botões, sem que para isto, venha a ocorrer um evento na roda do mouse.

Então como foi dito antes, o mouse é um grande aliado. No entanto, dependendo do que você venha a desejar implementar, ele pode ser algo saído do mais profundo dos infernos para lhe atormentar.


Considerações finais

Este artigo, talvez e até este momento, tenha sido um dos que definitivamente, é necessário não apenas ver o código e o estudar para compreender o que estará acontecendo. É de fato, necessário, criar uma aplicação executável e a utilizar em um gráfico qualquer. Isto maneira a conseguir entender pequenos detalhes, que de outra forma são muito complicados de serem compreendidos. Como por exemplo, a combinação de teclado com o mouse, a fim de construir certos tipos de coisas.

Pois entendendo, como esta combinação pode se dar, você com toda a certeza irá entender, por que certos códigos, não necessitam incluir o tratador CHARTEVENT_KEYDOWN, para verificar se a tecla SHIFT e a tecla CTRL estão ou não pressionadas. Assim como também, pode criar combinações dos próprios botões do mouse, a fim de construir coisas bem mais elaboradas, e de uso particular.

No anexo, você terá acesso aos códigos vistos aqui. Assim sendo, procure estudar o resultado que cada um dos códigos produz no gráfico. Experimentando combinações de movimento, e pressionar dos botões e teclas. A fim de conseguir assimilar de maneira adequada princípios que na teoria parecem completamente chatos. Mas que na prática se mostram muito interessantes e perfeitamente compreensíveis.

Arquivo MQL5 Descrição
Code 01 Demonstração do mouse


Arquivos anexados |
Code_01.mq5 (2.88 KB)
Do básico ao intermediário: Objetos (III) Do básico ao intermediário: Objetos (III)
Neste artigo iremos ver como podemos implementar um sistema de interação muito bacana e bastante interessante. Ainda mais para quem esteja começando a praticar programação MQL5. Não se trata de algo realmente novo. Porém a forma como irei abordar o assunto, de fato, tornará tudo muito mais simples de entender. Já que iremos ver na prática uma programação estrutural sendo feita com um objetivo bastante divertido.
Analisamos o código binário dos preços no mercado (Parte I): Um novo olhar sobre a análise técnica Analisamos o código binário dos preços no mercado (Parte I): Um novo olhar sobre a análise técnica
Este artigo apresenta uma abordagem inovadora para a análise técnica, baseada na conversão dos movimentos de preço em código binário. O autor mostra como diferentes aspectos do comportamento do mercado - desde movimentos simples de preço até padrões complexos - podem ser codificados em sequências de zeros e uns.
Computação quântica e trading: Um novo olhar sobre as previsões de preços Computação quântica e trading: Um novo olhar sobre as previsões de preços
Este artigo analisa uma abordagem inovadora para prever os movimentos de preços nos mercados financeiros mediante computação quântica. O foco principal está na aplicação do algoritmo de estimativa de fase quântica (QPE) para buscar precursores de padrões de preços, o que permite acelerar significativamente o processo de análise de dados de mercado.
Redes neurais em trading: Agente multimodal com ferramentas complementares (FinAgent) Redes neurais em trading: Agente multimodal com ferramentas complementares (FinAgent)
Apresentamos o framework do agente multimodal para negociação financeira FinAgent, projetado para analisar dados de diferentes tipos que refletem a dinâmica do mercado e padrões históricos de negociação.