Indicadores: O manipulador de evento "Nova barra" para indicadores.

 

O manipulador de evento "Nova barra" para indicadores.:

Este indicador permite-lhe executar o recálculo dos dados do indicador somente quando aparecer uma nova barra no gráfico.

A idéia dessa abordagem é descrita no artigo "Handler de evento "Nova barra". O exemplo de seu uso em Expert Advisors é apresentado neste artigo. Aqui você irá encontrar a solução para os indicadores. A ideia é o mesma: ele vai permitir realizar novos cálculos apenas quando a nova barra aparecer. Ela é uma alternativa conveniente para o uso direto da função OnCalculate().

Autor: Konstantin Gruzdev

 
datetime new_time=TimeCurrent()/period_seconds*period_seconds; // Hora de abertura da barra no gráfico atual

Há um erro aqui. Se o período é uma semana ou um mês.

Se o período for uma semana, o início da semana será quarta-feira, porque 1970.01.01 é quinta-feira.

Se o período for um mês e o mês atual não tiver 30 dias, ele também contará incorretamente, pois period_seconds corresponde a 30 dias.

 
Maratori:

Há um erro aqui. Se o período for de uma semana ou de um mês.

Se o período for uma semana, o início da semana será quarta-feira, já que 1970.01.01 é quinta-feira.

Se o período for um mês e o mês atual não tiver 30 dias, ele também contará incorretamente, pois period_seconds corresponde a 30 dias.

Concordo. Você pode usar isso no OnNewBarCalculate.mqh para esses períodos:

//+------------------------------------------------------------------+
//| Função de iteração de indicador personalizado
//+------------------------------------------------------------------+
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& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
//---
   // Quando uma nova barra aparecer, execute o manipulador de eventos NewBar
   if(current_chart.isNewBar()>0) 
      OnNewBarCalculate(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread);
   return(rates_total);
  }
 

Um pouco para outros fins, mas estou usando uma função como essa por enquanto:

datetime getHTFTime(datetime time, ENUM_TIMEFRAMES highTimeFrame) {
  int periodSeconds = PeriodSeconds(highTimeFrame);
  if(periodSeconds <= 60*60*24) return datetime(time/periodSeconds*periodSeconds);
  
  MqlDateTime sTime;
  TimeToStruct(time, sTime);
  
  if(highTimeFrame == PERIOD_W1) {
    TimeToStruct(time - datetime(sTime.day_of_week * 24 * 60 * 60), sTime);
    sTime.hour = 0;
    sTime.min = 0;
    sTime.sec = 0;
  } else if(highTimeFrame == PERIOD_MN1) {
      sTime.day = 1;
      sTime.hour = 0;
      sTime.min = 0;
      sTime.sec = 0;
    }
  return StructToTime(sTime);
}

Uma data/hora e um período de tempo são fornecidos como entrada. Na saída, obtemos a hora de início da barra nesse timeframe, que contém essa hora.

Se você tiver alguma sugestão para otimizar o código, ficarei feliz em ouvir.

É claro que você pode fazer isso dessa forma:

datetime timeOut[1];
CopyTime(_Symbol, highTimeFrame, timeIn, 1, timeOut);

Mas, nesse caso, tive um problema de sincronização. Tenho que esperar o carregamento do histórico.

 

Agradeço por seu indicador personalizado, mas, quando o utilizo, só dou um alerta uma vez e paro de depurar! Por favor, me ajude!

Se, em vez disso, eu usar o OnTick (e remover as funções OnInit e OnCaculate) como neste artigo https://www.mql5.com/pt/articles/159, ele funcionará bem, mas o indicador não será exibido nas janelas do navegador. E ele não funciona quando adiciono as funções OnInit e OnCaculate. Se eu adicionar as funções OnInit e OnCaculate, o indicador será exibido nas janelas do navegador?

Muito obrigado