Время локальное и серверное
На платформе MetaTrader 5 всегда существует два типа времени: локальное (клиентское) и серверное (брокера).
Локальное время соответствует времени компьютера, на котором запущен терминал, и увеличивается непрерывно, с равной скоростью, как и в реальном мире.
Серверное время течет иначе. Основу для него задает время на компьютере у брокера, однако к клиенту информация о нем поступает только вместе с очередными изменениями цен, которые упаковываются в специальные структуры, называемые тиками (см. раздел про MqlTick), и передаются MQL-программам с помощью событий.
Таким образом, обновленное серверное время становится известно в терминале только в результате изменения цены хотя бы одного финансового инструмента на рынке, то есть из числа тех, что выбраны в окне "Обзор рынка". Последнее известное время сервера отображается в заголовке этого окна. Если тиков нет, серверное время в терминале стоит на месте. Это особенно заметно в выходные и праздничные дни, когда все биржи и площадки Forex закрыты.
В частности, в воскресенье серверное время будет, скорее всего, отображаться как вечер пятницы. Исключение составят лишь те экземпляры MetaTrader 5, в которых доступны непрерывно торгуемые инструменты, такие как криптовалюты. Однако и в этом случае, в периоды низкой волатильности серверное время может заметно отставать от локального.
Все функции данного раздела оперируют временем с точностью до секунды (точность представления времени в типе datetime).
Для получения локального и серверного времени MQL5 API предоставляет 3 функции: TimeLocal, TimeCurrent и TimeTradeServer. Все три функции имеют по два варианта прототипа: первый возвращает время как значение типа datetime, второй дополнительно принимает по ссылке и заполняет компонентами времени структуру MqlDateTime.
datetime TimeLocal()
datetime TimeLocal(MqlDateTime &dt)
Функция возвращает локальное компьютерное время в формате datetime.
Важно отметить, что время включает в себя поправку на летнее время, если она активирована. То есть TimeLocal равна стандартному времени часового пояса компьютера за вычетом поправки TimeDaylightSavings. Условно формулу можно представить так:
TimeLocalsummer() = TimeLocalwinter() - TimeDaylightSavings() |
Здесь TimeDaylightSavings равно обычно -3600, то есть переводу часов на 1 час вперед (1 час пропадает). Таким образом, летнее значение TimeLocal больше зимнего (при равенстве астрономического времени суток) относительно UTC. Например, если зимой TimeLocal равен UTC+2, то летом UTC+3. Универсальное время UTC можно получить с помощью функции TimeGMT.
datetime TimeCurrent()
datetime TimeCurrent(MqlDateTime &dt)
Функция возвращает последнее известное время сервера в формате datetime. Это время прихода последней котировки из списка всех финансовых инструментов, подключенных в "Обзоре рынка". Единственное исключение: в обработчике события OnTick в экспертах данная функция вернет время обрабатываемого тика (даже если в обзоре рынка уже случились тики с более свежим временем).
Также отметим, что время на горизонтальной оси всех графиков в MetaTrader 5 соответствует времени сервера (на истории). Последний (текущий, самый правый) бар содержит в себе время TimeCurrent. Подробности см. в разделе Графики.
datetime TimeTradeServer()
datetime TimeTradeServer(MqlDateTime &dt)
Функция возвращает расчетное текущее время торгового сервера. В отличие от функции TimeCurrent, результаты которой могут не меняться в отсутствии новых котировок, TimeTradeServer позволяет получить оценку непрерывно увеличивающегося времени сервера. В основу расчета берется последняя известная разница "таймзон" клиента и сервера, которая прибавляется к текущему локальному времени.
В тестере значение TimeTradeServer всегда равно TimeCurrent.
Пример работы функций приведен в скрипте TimeCheck.mq5.
В главной функции организован бесконечный цикл, который выводит в журнал все типы времени каждую секунду, пока пользователь не остановит скрипт.
void OnStart()
|
Помимо стандартных функций здесь применена пользовательская функция TimeTradeServerExact.
datetime TimeTradeServerExact()
|
Она потребовалась потому, что алгоритм встроенной функции TimeTradeServer может устроить не всех. Встроенная функция находит разницу между локальным и серверным временем в часах (то есть разницу "таймзон"), и затем получает серверное время как коррекцию локального времени на эту разницу. В результате, если минуты и секунды тикают на клиенте и сервере не совсем синхронно (что весьма вероятно), стандартная аппроксимация серверного времени покажет минуты и секунды клиента, а не сервера.
В идеале "бортовые" часы всех компьютеров должны быть синхронизированы с глобальным временем, но на практике случаются отклонения, и достаточно небольшого сдвига на одной из сторон, как TimeTradeServer перестанет максимально точно повторять время на сервере.
В нашей реализации этой же функции на MQL5 мы не округляем разницу между временем клиента и сервера до часовых "таймзон". Вместо этого в расчете используется точная разница в секундах. Поэтому TimeTradeServerExact возвращает время, в котором минуты и секунды тикают так же, как на сервере.
Вот пример журнала, генерируемого скриптом.
TimeLocal()=2021.09.02 16:03:34 / ok
|
Видно, что часовые пояса клиента и сервера совпадают, но есть рассинхронизация в несколько минут (для наглядности). При первом вызове TimeTradeServerExact вернула 0. Далее данные для расчета разницы уже поступят, и мы увидим все 4 "типа" времени, размеренно "шагающие" с секундным интервалом.
TimeLocal()=2021.09.02 16:03:35 / ok
|