Функции для работы со временем
Время является фундаментальным фактором большинства процессов и играет важнейшую прикладную роль для трейдинга.
Как мы знаем, основная система координат в торговле построена на двух измерениях: цене и времени. На графиках они отображаются, как правильно, по вертикальной и горизонтальной оси, соответственно. Позднее мы затронем еще одну важную ось, которую можно представить перпендикулярной двум первым и уходящей как бы вглубь графика, — на ней отмечаются торговые объемы. Но пока сконцентрируемся на времени.
Это измерение является общим для всех графиков, использует одни и те же единицы измерения и, как бы это странно ни звучало, характеризуется постоянством (ход времени предсказуем).
Общее число встроенных средств, связанных с расчетом и анализом времени, в терминале очень велико. Поэтому знакомиться с ними мы будем постепенно, по мере продвижения по главам книги, от простого — к сложному.
В данной главе мы изучим функции, которые позволяют контролировать время и приостанавливать активность программы на заданный интервал.
В разделе Дата и время в главе про преобразование данных мы уже видели пару функций, связанных со временем: TimeToStruct и StructToTime. Они позволяют разделить значение типа datetime на составляющие или наоборот, сконструировать datetime из отдельных полей: напомним, что они сведены в структуру MqlDateTime.
struct MqlDateTime
|
Но откуда MQL-программа может получить само значение datetime?
Например, исторические цены и время отражены в котировках, а текущие "живые" данные поступают с тиками. И то, и другое обладает метками времени, которые мы научимся получать в соответствующих разделах: про таймсерии и события терминала. Однако MQL-программа имеет возможность запросить текущее время само по себе (без цен или другой торговой информации) с помощью нескольких функций.
Несколько функций потребовалось потому, что система является распределенной: она состоит из клиентского терминала и сервера брокера, находящихся в произвольных частях мира, которые, вполне вероятно, относятся к разным часовым поясам.
Любой часовой пояс характеризуется временным смещением относительно общемировой точки отсчета времени — нулевого гринвичского меридиана (Greenwich Mean Time, GMT). Как правило, смещение часового пояса составляет целое число часов N (хотя есть и экзотические зоны с получасовым шагом) и потому обозначается как GMT+N или GMT-N, в зависимости от того, восточнее или западнее от меридиана находится пояс. Например, расположенная восточнее от Лондона континентальная Европа использует центральноевропейское время (Central European Time, CET), равное GMT+1, или восточноевропейское время (Eastern European Time, EET), равное GMT+2, а в Америке расположены "отрицательные" зоны, такие как Eastern Standard Time (EST) или GMT-5.
Следует отметить, что GMT соответствует астрономическому (солнечному) времени, которое обладает едва заметной нелинейностью, поскольку вращение Земли постепенно замедляется. В связи с этим в последние десятилетия фактически произошел переход к более точной системе учета времени (на основе атомных часов), в которой общемировое время называется всемирным координированным временем (Coordinated Universal Time, UTC). Во многих прикладных областях, включая и трейдинг, различие между GMT и UTC несущественно, поэтому обозначения часовых поясов в новом формате UTC±N и старом GMT±N следует считать аналогами. Например, многие брокеры уже указывают в спецификациях времена сессий через UTC, в то время как в MQL5 API исторически используется обозначение GMT.
MQL5 API позволяет узнать текущее время терминала (фактически, локальное время компьютера) и время сервера: их возвращают, соответственно, функции TimeLocal и TimeCurrent. Кроме того, MQL-программа может получить текущее время GMT (функция TimeGMT), основываясь на настройках часового пояса Windows. Таким образом, у трейдера и программиста появляется привязка локального времени к общемировому, а по разнице между локальным и серверным временем можно определить "таймзону" сервера и котировок. Но здесь есть пара нюансов.
Во-первых, во многих странах мира существует практика перехода на "летнее" время из соображений более эффективного использования дневного света (Daylight Savings Time , DST). Обычно это означает добавление 1 часа к стандартному (зимнему) времени примерно с марта/апреля по октябрь/ноябрь (в северном полушарии, в южном — наоборот). При этом время GMT/UTC всегда остается постоянным, то есть не подвергается поправке DST, и потому потенциально возможны различные варианты схождения/расхождения клиентского и серверного времени:
- в разных странах даты перехода могут отличаться;
- некоторые страны не осуществляют переход на летнее время;
В связи с этим, некоторым MQL-программам требуется отслеживать подобные моменты перестройки часовых поясов, если алгоритмы основаны на привязке к внутридневному времени (например, к выходу новостей), а не к движениям цен или концентрации объемов.
И если перевод времени на компьютере пользователя определить довольно легко, благодаря функции TimeDaylightSavings, то для серверного времени готового аналога нет.
Во-вторых, штатный тестер MetaTrader 5, в котором мы можем отлаживать или оценивать MQL-программы таких типов как эксперты и индикаторы, к сожалению, не эмулирует время торгового сервера. Вместо этого все три вышеуказанные функции TimeLocal, TimeGMT, TimeCurrent вернут одно и то же время, то есть часовой пояс всегда виртуально равен GMT.
Абсолютное и относительное время
Учет времени в алгоритмах, как и в жизни, может вестись в абсолютных или относительных координатах. Каждый момент в прошлом, в настоящем и в будущем описывается абсолютным значением, на которое мы можем сослаться, чтобы указать начало отчетного периода или время выхода экономических новостей. Именно это время мы храним в MQL5 с помощью типа datetime. Вместе с тем, зачастую требуется заглянуть в будущее или отступить в прошлое на заданное количество единиц времени от текущего момента. При этом нас интересует не абсолютное значение, а временной интервал.
В частности, в алгоритмах существует понятие таймаута — периода времени, за который должно выполниться определенное действие, и если оно не выполнилось по любым причинам, мы его отменяем, перестаем ждать результата (потому что, видимо, что-то пошло не так). Измерять интервал можно в разных единицах: часах, секундах, миллисекундах или даже микросекундах (ведь, компьютеры нынче быстры).
В MQL5 часть функций, связанных со временем, работает с абсолютными значениями (например, TimeLocal, TimeCurrent), а часть с интервалами (например, GetTickCount, GetMicrosecondCount).
Однако измерение интервалов или активация программы через заданные промежутки времени могут осуществляться не только с помощью функций из данного раздела, но и встроенных таймеров, работающих по известному принципу будильника. Будучи взведенными, они используют для уведомления MQL-программ специальные события и реализуемые нами функции обработки этих событий — OnTimer (они похожи на OnStart). Этим аспектом управления временем мы займемся в отдельном разделе, после изучения общей концепции событий в MQL5 (см. раздел Обзор функций обработки событий).