Библиотеки: AccurateTimer

 

AccurateTimer:

Штатный таймер в MetaTrader 4/5 основан на вызове системного таймера, и поэтому может работать с погрешностью. Чтобы в этом убедиться, достаточно запустить простой советник:

input int Timer = 1000; // Через сколько миллисекунд срабатывает таймер

#define TOSTRING(A) #A + " = " + (string)(A) + " ms.\n"

const bool Init = EventSetMillisecondTimer(Timer);

// Выводит в комментарий чарта текущую ошибку таймера и ее среднюю величину
void OnTimer()
{
  static ulong StartTime = 0;
  static int Count = 0;
  static int Sum = 0;

  if (StartTime)
  {
    const int RunTime = (int)(GetMicrosecondCount() - StartTime) / 1000;
    const int Error = RunTime - Timer * Count;

    Sum += Error;

    Comment(TOSTRING(Timer) + TimeToString(RunTime / 1000, TIME_SECONDS) + "\n" +
            TOSTRING(Error) + TOSTRING((double)Sum / Count));
  }
  else
    StartTime = GetMicrosecondCount();

  Count++;
}

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

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

Данная библиотека позволяет повысить точность штатного таймера любого советника/индикатора. Для этого нужно в начале кода прописать только одну строку:

#include <AccurateTimer.mqh> // Повышение точности штатного таймера

После такого действия в вышеприведенном советнике можно наблюдать следующую картину:

После десятка минут работы среднее отклонение от идеального (теоретического) таймера составляет ~1 мс, и ошибка не будет расти.

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

Данная кросс-платформенная библиотека совместима со всеми советниками/индикаторами, где используется штатный таймер (OnTimer). Не влияет на скорость выполнения в тестере.

Повышайте точность уже готовых и новых программ всего одной строкой!

Автор: fxsaber

 
А у вас в процессе работы ошибка не возникает? На слабых системах (нетбуках, например) пробовали тестировать?
 
Andrey Khatimlianskii:
А у вас в процессе работы ошибка не возникает? На слабых системах (нетбуках, например) пробовали тестировать?

Никогда не сталкивался с этой ошибкой. На нетбуке надо будет попробовать.

 
fxsaber:

Никогда не сталкивался с этой ошибкой. На нетбуке надо будет попробовать.

У меня возникала пару раз на арендованном на хетзнере сервере.

Намек был на то, что периодическое пересоздание таймера — источник потенциальных сбоев.

 
Andrey Khatimlianskii:

У меня возникала пару раз на арендованном на хетзнере сервере.

Намек был на то, что периодическое пересоздание таймера — источник потенциальных сбоев.

Уловил, Спасибо! От этого бага, конечно, никакой страховки. Возможно, разработчики починят.

 
fxsaber:

Уловил, Спасибо! От этого бага, конечно, никакой страховки. Возможно, разработчики починят.

Судя по отсылке @Slava к описанию системных ошибок — вряд ли =(

 
Andrey Khatimlianskii:

Судя по отсылке @Slava к описанию системных ошибок — вряд ли =(

Слава уже сказал ему свое негативное мнение. Но fxsaber не верит

 
Rashid Umarov:

Слава уже сказал ему свое негативное мнение. Но fxsaber не верит

Возможно, я что-то пропустил. Могли бы повторить?

 
Automated-Trading:

AccurateTimer:

Автор: fxsaber

GetMicrosecondCount и EventSetTimer очевидно используют разные источники времени и они обязаны расходится потому что разное время отсчитывают.

Пытаться их синхронизовать это что-то с чем-то, это неправильно :-)

 
Maxim Kuznetsov:

GetMicrosecondCount и EventSetTimer очевидно используют разные источники времени и они обязаны расходится потому что разное время отсчитывают.

Пытаться их синхронизовать это что-то с чем-то, это неправильно :-)

Поставьте секундный таймер в 00:00:00. И посмотрите, какое время будет после 300-го вызова OnTimer. Поверьте, 00:05:00 (пять минут ровно) Вы не увидите. С библиотекой такого расхождения не будет.

 
fxsaber:

Поставьте секундный таймер в 00:00:00. И посмотрите, какое время будет после 300-го вызова OnTimer. Поверьте, 00:05:00 Вы не увидите. С библиотекой такого расхождения не будет.

ой, какой упёртый, дремучий человек :-)

GetMicrosecondTimer используется для профилирования, измерений производительности и малых задержках в циклах. Очевидно для этого берёт учётное время процесса или треда (могут разработчики уточнить, только зачем?)

EventSetTimer берёт или monotоnic или realtime (скорее первое), по тику таймера тем или иным способом вызывает OnTimer. Для этого задействует системные дескрипторы, что вызывает некоторые проблемы, таймер может просто не запуститься через EventSetTimer

всё упомянутое - разные таймеры. На нагруженной машине расхождения будут существенны и естественны

Причина обращения: