Sincronizar Segundos de EventSetTimer com os Segundos da Vela Atual (ou Com os Segundos do Horário Local)

 

Oi pessoal! Minha dúvida se refere ao timer. Li na documentação que o Expert só comporta um timer (tudo bem, não preciso mais do que um).

Quando ativo o Expert ele conta o número de segundos normalmente e tudo funciona bem. No entanto gostaria que a contagem de 60 segundos do timer fosse sincronizada com os segundos atuais da vela.

Exemplo, ativei o Exper às 15:30:25

O timer iniciaria na contagem 25 (e não 0 como de costume). O efeito seria que o Timer acompanharia o evento do nascimento de uma vela.

(estou prevendo uma sugestão de usar eventos ao invés do Timer, no entanto isso irá me servir para outros propósitos, então se alguém puder dar uma sugestão agradeço e se não for possível fazer isso no MQL5, agradeço o aviso também)

 
israeltandrade:

Oi pessoal! Minha dúvida se refere ao timer. Li na documentação que o Expert só comporta um timer (tudo bem, não preciso mais do que um).

Quando ativo o Expert ele conta o número de segundos normalmente e tudo funciona bem. No entanto gostaria que a contagem de 60 segundos do timer fosse sincronizada com os segundos atuais da vela.

Exemplo, ativei o Exper às 15:30:25

O timer iniciaria na contagem 25 (e não 0 como de costume). O efeito seria que o Timer acompanharia o evento do nascimento de uma vela.

(estou prevendo uma sugestão de usar eventos ao invés do Timer, no entanto isso irá me servir para outros propósitos, então se alguém puder dar uma sugestão agradeço e se não for possível fazer isso no MQL5, agradeço o aviso também)

Israel, nem vou dar boa tarde porque estou de mau humor, eu estou p¨#¨#%$%# da vida comigo mesmo de ter que trabalhar em pleno sábado de sol a pico, abro a porta de casa praia me chamando e eu aqui feito um...um...um...deixa pra lá... mas como não é culpa sua e vejo você sempre buscando melhorar seus códigos então vou tentar te ajudar viu.

Se o evento for "nn" segundos fixos pós cada barra, então você pode utilizar conforme abaixo. onde o PREVTIME2 é um datetime;

No exemplo abaixo, independente do timeline da barra, ele executará aos 25 segundos de cada barra a instrução que você colocar dentro do if.

if(PREVTIME2 != iTime(NULL, PERIOD_CURRENT, 0) && TimeCurrent() > (iTime(NULL, PERIOD_CURRENT, 0) + 25))
{
...evento 25 segundos do candle.
}
PREVTIME2 = iTime(NULL, PERIOD_CURRENT, 0);
Porque a Hospedagem Virtual no MetaTrader 4 e no MetaTrader 5 são Melhores que os VPS Usuais
Porque a Hospedagem Virtual no MetaTrader 4 e no MetaTrader 5 são Melhores que os VPS Usuais
  • www.mql5.com
Alugar um servidor virtual diretamente dos terminais MetaTrader 4 e MetaTrader 5 é a melhor maneira de garantir um trabalho ininterrupto de seus robôs de negociação e das assinaturas de Sinais. Essencialmente, ele é análogo a um VPS, no entanto, ele é melhor e mais adequado para atender às necessidades e desafios que um trader se depara. O...
 
israeltandrade:

Oi pessoal! Minha dúvida se refere ao timer. Li na documentação que o Expert só comporta um timer (tudo bem, não preciso mais do que um).


Oi Israel,

uma barra é aberta no gráfico somente quando ocorre um negócio, então raramente,  exceto para WIN , você tem a coincidência de ter um Tick exatamente no segundo 0(zero) da barra. Saindo da caixa do WIN e DOL você vai ver que existe dezenas de ativos na B3 com umas poucas barras no gráfico de preços de 1 min. Então sincronizar o Timer com a barra OHLC é meio sem sentido.

Porém se você quer sincronizar o relógio do servidor com um TIMER de 60 segundos você pode tentar algo assim:

//+------------------------------------------------------------------+
//|                                                Forum20072401.mq5 |
//+------------------------------------------------------------------+
#property copyright "Rogério Giannetti Torres"
#property link      "mailto:giannetti.rogerio@gmail.com"
#property version   "1.00"
int qtdMinutos = 60;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   Print("Inicio: ", TimeTradeServer());
   qtdMinutos = (int)TimeTradeServer() / 60;
   while((int)TimeTradeServer() / 60 == qtdMinutos)
      Sleep(5);
   Print("Sincronizou: ", TimeTradeServer());
   EventSetTimer(60);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Print("On Timer: ", TimeTradeServer());
  }
//+------------------------------------------------------------------+
 
Ruy Christian Hoffmann:

Israel, nem vou dar boa tarde porque estou de mau humor, eu estou p¨#¨#%$%# da vida comigo mesmo de ter que trabalhar em pleno sábado de sol a pico, abro a porta de casa praia me chamando e eu aqui feito um...um...um...deixa pra lá... mas como não é culpa sua e vejo você sempre buscando melhorar seus códigos então vou tentar te ajudar viu.

Se o evento for "nn" segundos fixos pós cada barra, então você pode utilizar conforme abaixo. onde o PREVTIME2 é um datetime;

No exemplo abaixo, independente do timeline da barra, ele executará aos 25 segundos de cada barra a instrução que você colocar dentro do if.

Oi Ruy! Muito obrigado pela atenção! Estou experimentando aqui com a tua sugestão amigo. Um abraço!

 
Rogerio Giannetti Torres:

Oi Israel,

uma barra é aberta no gráfico somente quando ocorre um negócio, então raramente,  exceto para WIN , você tem a coincidência de ter um Tick exatamente no segundo 0(zero) da barra. Saindo da caixa do WIN e DOL você vai ver que existe dezenas de ativos na B3 com umas poucas barras no gráfico de preços de 1 min. Então sincronizar o Timer com a barra OHLC é meio sem sentido.

Porém se você quer sincronizar o relógio do servidor com um TIMER de 60 segundos você pode tentar algo assim:

Oi Rogerio! Muito obrigado pela ajuda.

O teu código funciona muito bem. Só que como ele está no Oninit ele só faz isso uma vez.

Se jogo o argumento while para dentro da função OnTimer (coloquei EventSetTimer para 1 segundo), ele retorna a cada minuto no mesmo tempo em que adicionei o Expert ao invés do tempo sincronizado.

Como repetir regularmente esse processo a cada minuto E manter o resultado do teu código original?

Detalhe: tentei com TimeLocal ao invés de TimTradeServer (o horário do servidor não faz diferença para minha estratégia, apenas o local já resolve o meu problema e eu não fico dependendo de nada do servidor)
 
israeltandrade:

Oi Rogerio! Muito obrigado pela ajuda.

O teu código funciona muito bem. Só que como ele está no Oninit ele só faz isso uma vez.

Se jogo o argumento while para dentro da função OnTimer (coloquei EventSetTimer para 1 segundo), ele retorna a cada minuto no mesmo tempo em que adicionei o Expert ao invés do tempo sincronizado.

Como repetir regularmente esse processo a cada minuto E manter o resultado do teu código original?

Detalhe: tentei com TimeLocal ao invés de TimTradeServer (o horário do servidor não faz diferença para minha estratégia, apenas o local já resolve o meu problema e eu não fico dependendo de nada do servidor)

Olá Israel,

uma vez sincronizado e iniciado com um TIMER qualquer no OnInit(), se você quer um novo "TIMER" digamos 5 em 5 segundos, também sincronizado com o servidor (    10:15:00 - 10:15:05 - 10:15:10  ), acho que o código abaixo deve funcionar.


OnTimer()
{
if( condição para um sinc de 5 / 5){
   EventKillTimer();   
   qtdMinutos = (int)TimeTradeServer() / 60;
   while((int)TimeTradeServer() / 60 == qtdMinutos)
      Sleep(5);
   EventSetTimer(5);
}
}
 

Mais uma vez muito obrigado Rogerio! Obrigado a todos que me ajudaram neste tópico.

Cheguei a mais duas possibilidades, uma nada prática e outra bem simples:


1ª --> Não tão prática assim, mas talvez ajude outra pessoa em entender alguns princípios da linguagem:

I) Declarar variável tipo datetime para armazenar a função TimeLocal ou TimeCurrent etc.

datetime        horarioLocal = TimeLocal();


II) Declarar variável tipo string para converter a variável datetime anterior (já eliminando data e colocando apenas hora, minuto e segundos):

string            horarioLocal_STR = TimeToString(horarioLocal,TIME_SECONDS);


III) Se você imprimir isso aí, você terá: hh:mm:ss, mas dependendo do timeframe (por exemplo M1) você só quer saber dos segundos, portanto declare uma nova variável e armazene os algarísmos dos segundos (o mesmo pode ser feito com os minutos, basta alterar alguns parâmetros) como demonstrado a seguir:

string            segundoAtual = StringSubstr(horarioLocal_STR,StringLen(horarioLocal_STR)-2,2);


Isso vai armazenar somente os segundos ss. Pronto, basta colocar dentro da função OnTimer com EventSetTimer a 1 segundo sob a condição de:

if(segundoAtual == 00)
        {
        O teu código aqui;
        }


2ª --> Muito melhor na minha opinião:

I- Declare uma estrutura MqlDateTime:

MqlDateTime       horarioLocal_STC;


II- Transfira as informações de TimeLocal() para dentro da estrutura:

TimeToStruct(TimeLocal(),horarioLocal_STC);


III- Pronto! Basta estabelecer uma condição baseado nos segundos da estrutura:

if(horarioLocal_STC.sec == 00)
        {
        O Teu código aqui;
        }

Da mesma maneira, é possível colocar tudo dentro de OnTimer().


Me ocorreu a possibilidade tb de colocar tudo dentro de um loop while de condição true, mas não sei se isso iria fritar o processador. :P

Valeu pessoal!