Поделитесь опытом использования OnTimer()

 

Насколько корректно отрабатывает таймер? Поделитесь опытом. К примеру выставляю таймер и там раcсчитывать индикаторы. Выставляю на входе таймер под начало бара:

int OnInit()
  {
datetime time_now =TimeCurrent();
datetime time_bar =iTime(_Symbol,PERIOD_CURRENT,0);
Sleep((PeriodSeconds(PERIOD_CURRENT)-(time_now-time_bar)) * 1000);

   EventSetTimer(PeriodSeconds(PERIOD_CURRENT));
}

И не выключаю программу больше  недели. Произойдет ли сбой. Т.е. таймер может запуститься не на начале бара?

Для индикаторов не актуально, особо. А вот в конце периода - бара - да, желательно запуститься надежно. Кто как использует?

 

Как я понимаю, таймер не гарантирует точность. Он для того, чтобы с какой-то (примерной) периодичностью выполнять какие-то действия.

Т.е., если хотим поймать время у окончания бара, дёргаем чаще и сравниваем текущее время с временем начала текущего бара.

 

Для определения начала нового бара на текущем символе используется другой подход:

bool IsNewBar(const ENUM_TIMEFRAMES eTF, datetime &dtLastBarOpened)
{
   if (iTime(NULL, eTF, 0) == dtLastBarOpened)
      return false;
 
   dtLastBarOpened = iTime(NULL, eTF, 0);
   return true;
}

Проверка факта возникновения нового бара:

static datetime dtLastBarOpened = 0;
if (!IsNewBar(ENUM_TIMEFRAMES(Period()), dtLastBarOpened)
   return;

Если нужно словить новый бар на другом символе, то придется через таймер опрашивать нужный символ (частоту опроса установить свою):

int OnInit()
{
   ...
   EventSetMillisecondTimer(100);

   ...
}

bool IsNewBar(const string sSymbol, const ENUM_TIMEFRAMES eTF, datetime &dtLastBarOpened)
{
   if (iTime(sSymbol, eTF, 0) == dtLastBarOpened)
      return false;
 
   dtLastBarOpened = iTime(sSymbol, eTF, 0);
   return true;
}


void OnTimer()
{
   static datetime dtLastBarOpened = 0;
   if (!IsNewBar("GBPJPY", ENUM_TIMEFRAMES(Period()), dtLastBarOpened)
      return;
}
 
vbymrf:

Насколько корректно отрабатывает таймер? Поделитесь опытом. К примеру выставляю таймер и там раcсчитывать индикаторы. Выставляю на входе таймер под начало бара:

И не выключаю программу больше  недели. Произойдет ли сбой. Т.е. таймер может запуститься не на начале бара?

Для индикаторов не актуально, особо. А вот в конце периода - бара - да, желательно запуститься надежно. Кто как использует?

Будет сбой. Не так надо.  Делайте таймер с интервалом 1 сек, или 100 мс, в таймере копируйте время бара и сравнивайте со временем, скопированном при предыдущем вызове таймера. Но в этом случае лучше OnTick() использовать. Если же надо отловить моменты, кода новый бар должен теоретически открываться (незхависимо от реальных тиков), тогда вычислять номер бара (для всех таймфремов в МТ5 подходит): время поделить на таймфрейм в секунда. В таймере отслеживать, когда номер бара изменится. 

 

Code Base

AccurateTimer

fxsaber, 2018.02.02 12:06

Повышение точности штатного таймера.

В комментарии чарта (левый-верхний угол) он показывает, как растет лаг таймера:

На скриншоте видно, что всего за минуту работы секундный таймер создает лаг больше секунды. И со временем он только растет!

 
Andrey Khatimlianskii:
за несколько минут теста я не увидел роста лагов. Да, таймер запускается с некоторой погрешностью. Я сравнивал TimeCurrent и начало бара. И он синхронизирован был с этим временем, но имел отклонение
 
long st;
int n;

int OnInit(){
   n=0;
   EventSetMillisecondTimer(100);
   st=GetTickCount();
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason){
   EventKillTimer();
   Comment("");
}

void OnTimer(){
   n+=100;
   Comment(n-(GetTickCount()-st));
}

Сначала удивляет точностью совпадения, а чуть нагрузка возникнет на процессор и всё.