OnTick() or OnTimer() ?

Para adicionar comentários, por favor Faça o login ou registrar
Marcos Maia
151
Marcos Maia  

Hello Guys,

 I'm building an EA that must place a trade at the beginning of a new bar. Regarding to less time delay from the opening of the new bar time, which one you recommend using: OnTick() or OnTimer() ?

Alain Verleyen
40417
Alain Verleyen  
Marcos Maia:

Hello Guys,

 I'm building an EA that must place a trade at the beginning of a new bar. Regarding to less time delay from the opening of the new bar time, which one you recommend using: OnTick() or OnTimer() ?

Please write in Portuguese on this forum. We have an English section.
Rogerio Figurelli
Moderador
58548
Rogerio Figurelli  

Olá Marcos,

Segue abaixo minha versão da tua pergunta (para compatibilizar com o Fórum aqui), portanto fique à vontade para modificar ela. Mais abaixo, minha opinião a respeito:

"Estou construindo um EA que deve colocar um trade no início de uma nova barra. Em relação a um menor intervalo de tempo a partir da abertura da nova barra, qual alternativa você recomendaria utilizar: OnTick () ou OnTimer ()?"

Se o foco é o tempo de reação, como aparentemente é tua preocupação, eu recomendaria a OnTick() pois você será interrompido em tempo real na mudança do preço, enquanto pela OnTimer() você estará limitado aos atrasos típicos de verificação das mudanças de eventos por polling, que na OnTimer() do MT5 apresenta uma resolução mínima de um segundo.

Marcos Maia
151
Marcos Maia  

Desculpem, não sabia que tinha que ser em português, só achei que escrever em inglês seria mais abrangente e mais pessoas poderiam ver e responder.

 De qualquer forma, obrigado Rogerio Figurelli pela resposta!

Rogerio Figurelli
Moderador
58548
Rogerio Figurelli  
Marcos Maia:

Desculpem, não sabia que tinha que ser em português, só achei que escrever em inglês seria mais abrangente e mais pessoas poderiam ver e responder.

 De qualquer forma, obrigado Rogerio Figurelli pela resposta!

Olá Marcos, perfeitamente, podes também escrever em paralelo em outros idiomas, mas ai são áreas e fóruns independentes.
Rodrigo Malacarne
Moderador
8089
Rodrigo Malacarne  
Rogerio Figurelli:

Olá Marcos,

Segue abaixo minha versão da tua pergunta (para compatibilizar com o Fórum aqui), portanto fique à vontade para modificar ela. Mais abaixo, minha opinião a respeito:

"Estou construindo um EA que deve colocar um trade no início de uma nova barra. Em relação a um menor intervalo de tempo a partir da abertura da nova barra, qual alternativa você recomendaria utilizar: OnTick () ou OnTimer ()?"

Se o foco é o tempo de reação, como aparentemente é tua preocupação, eu recomendaria a OnTick() pois você será interrompido em tempo real na mudança do preço, enquanto pela OnTimer() você estará limitado aos atrasos típicos de verificação das mudanças de eventos por polling, que na OnTimer() do MT5 apresenta uma resolução mínima de um segundo.

Só pra complementar a resposta do Figurelli: dentro de OnTimer() a resolução mínima é de um milisegundo.

Abraços,
Malacarne

Rogerio Figurelli
Moderador
58548
Rogerio Figurelli  
Rodrigo Malacarne:

Só pra complementar a resposta do Figurelli: dentro de OnTimer() a resolução mínima é de um milisegundo.

Abraços,
Malacarne

Olá Malacarne,

É verdade, obrigado, mas estava me referindo à EventSetTimer() por simplificação e não à EventSetMillisecondTimer() que é o que você deve ter pensando.

Isso porque, se formos realmente ser precisos, na verdade nem 1 segundo nem 1 milissegundo estaria correto, pois pela limitação de hardware o limite real é na casa de 10ms a 16ms. 

Abraços,

Rogério Figurelli

Alain Verleyen
40417
Alain Verleyen  
Rogerio Figurelli :

Olá Malacarne,

É verdade, obrigado, mas estava me referindo à EventSetTimer() por simplificação e não à EventSetMillisecondTimer() que é o que você deve ter pensando.

Isso porque, se formos realmente ser precisos, na verdade nem 1 segundo nem 1 milissegundo estaria correto, pois pela limitação de hardware o limite real é na casa de 10ms a 16ms

Abraços,

Rogério Figurelli

Você está certo sobre esta limitação, no entanto, não é um problema de hardware, é uma limitação do Windows que pode ser alterado por software.

(In case translation is not good : You are right about this limitation, however it's not an hardware issue, it's a Windows limitation which could be changed by software.)

Rogerio Figurelli
Moderador
58548
Rogerio Figurelli  
Alain Verleyen:

Você está certo sobre esta limitação, no entanto, não é um problema de hardware, é uma limitação do Windows que pode ser alterado por software.

(In case translation is not good : You are right about this limitation, however it's not an hardware issue, it's a Windows limitation which could be changed by software.)

Antes de mais nada, note que essa informação é da documentação do MQL5 (cópia abaixo), e não minha.

"Ao trabalhar em modo de tempo real, os eventos de timer são gerados não mais do que uma vez em 10-16 milissegundos, devido a limitações de hardware." (fonte: https://www.mql5.com/pt/docs/eventfunctions/eventsetmillisecondtimer).

Note também que o Windows não possui essa limitação, bastando fazer chamadas de API para a função NTSetTimerResolution() para obter resolução de 1ms ou ainda a GetSystemTimeAsFileTime() para resolução de 100ns, ou seja, se o MT5 não endereça esses recursos e divulga essa limitação de hardware, não sou eu que vou questionar isso.

Mas provavelmente se eu tivesse dito que a limitação não é devido ao hardware, algum moderador citaria a documentação acima do MQL5 dizendo que estou errado ;-) 

Documentação sobre MQL5: Trabalhando com Eventos / EventSetMillisecondTimer
Documentação sobre MQL5: Trabalhando com Eventos / EventSetMillisecondTimer
  • www.mql5.com
Trabalhando com Eventos / EventSetMillisecondTimer - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader5
Felipe Dourado Goncalves De Souza
267
Felipe Dourado Goncalves De Souza  
Rogerio Figurelli:

Olá Marcos,

Segue abaixo minha versão da tua pergunta (para compatibilizar com o Fórum aqui), portanto fique à vontade para modificar ela. Mais abaixo, minha opinião a respeito:

"Estou construindo um EA que deve colocar um trade no início de uma nova barra. Em relação a um menor intervalo de tempo a partir da abertura da nova barra, qual alternativa você recomendaria utilizar: OnTick () ou OnTimer ()?"

Se o foco é o tempo de reação, como aparentemente é tua preocupação, eu recomendaria a OnTick() pois você será interrompido em tempo real na mudança do preço, enquanto pela OnTimer() você estará limitado aos atrasos típicos de verificação das mudanças de eventos por polling, que na OnTimer() do MT5 apresenta uma resolução mínima de um segundo.

Rogério, ressuscitando esse tópico pois estava pesquisando e encontrei algo valioso aqui.

Minha questão é a seguinte: usando OnTick(), corro o risco de não haver tempo o suficiente para a leitura de todo o código restante que estiver no EA por uma questão de alteração de preço, por exemplo? Não sei se está claro mas também estou montando um EA que deverá ser rápido assim que o mercado abrir. Os backtestings realizados foram satisfatórios com OnTick(). No entanto, rodando na conta DEMO, percebo que a posição é aberta com um valor um pouco maior do que o previsto, o que não é tão bom.

Para tentar contornar, rodei o backtesting com delay de 1000ms porém isso não alterou em nada, isto é, continuou abrindo posições rapidamente. Daí me surgiu essa dúvida: seria realmente o evento OnTick() o mais recomendado ou posso estar me esquecendo de algo realmente importante que o testador de estratégia não captura?

Obrigado

Loester Silva
41
Loester Silva  

Pessoal, boa tarde, pesquisei bastante no site, mas não achei nada claro ou suficiente sobre a reversão de uma posição aberta com o mql5.

Segue um código que está fazendo se alguém puder indicar algum caminho por favor.


Grato.


void _Valida_Transacao_Aberta()

{

    for (int i=PositionsTotal(); i>=0; i--){

        if (PositionGetSymbol(i) == _Symbol) {

               double preco_corrente=PositionGetDouble(POSITION_PRICE_CURRENT);

               double preco_Abertura=PositionGetDouble(POSITION_PRICE_OPEN);

               int _id = (int)PositionGetInteger(POSITION_TICKET);


               if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){

                   Print("Preço Corrente:"+DoubleToString(preco_corrente));

                   Print("Preço Compra:"+DoubleToString(preco_Abertura));


                   if(preco_Abertura<(preco_corrente-20)){

                       if (!mytrade.PositionClose(_id)) {

                         Print("Não consegui fechar...:"+mytrade.ResultComment());

                         return; }  

                       Print("Fechei a posição de prejuizo, abrindo uma reversão para Venda"); 

                       preco_compra=0;

                       preco_venda=0;

                    

                       double valorSL=DoStoplossSell();

                       Print("Valor do StopLoss para venda é:"+DoubleToString(valorSL));


                       if (!mytrade.Sell(PositionGetDouble(POSITION_VOLUME),NULL,bid,bid-50,bid+50,"ORDEM DE VENDA NA REVERSÃO :"+IntegerToString(_id)))

                           Print(mytrade.ResultComment());

                        else 

                           preco_venda=bid;   

                   }

                 }

               else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){

                  Print("É uma operação de Compra:Preço Corrente:"+DoubleToString(preco_corrente));

                  Print("Preço de compra foi:"+DoubleToString(preco_Abertura));

                   if(preco_Abertura>(preco_corrente+10))

                   {

                       if (!mytrade.PositionClose(_id)){

                         Print("Não consegui fechar...:"+mytrade.ResultComment());

                         return;                         

                       }  

                       Print("Fechei a posição de prejuizo, abrindo uma reversão");

                       preco_compra=0;

                       preco_venda=0;

                       double valorSL=DoStoplossBuy();

                       Print("Abrindo posição de compra em:"+DoubleToString(ask));

                       Print("Valor do StopLoss para Compra é:"+DoubleToString(valorSL));


                       if (!mytrade.Buy(PositionGetDouble(POSITION_VOLUME),NULL,ask,ask+50,ask-50,"ORDEM DE COMPRA NA REVERSÃO :"+IntegerToString(_id)))

                              Print(mytrade.ResultComment());

                       else 

                         preco_compra=ask;

                   }        

                 }

          }

        }

}

Para adicionar comentários, por favor Faça o login ou registrar