- Символы и таймфреймы
- Технические особенности организации и хранения таймсерий
- Получение характеристик массивов котировок
- Количество доступных баров (Bars/iBars)
- Поиск индекса бара по времени (iBarShift)
- Обзор Copy-функций для получения массивов котировок
- Получение котировок в виде массива структур MqlRates
- Раздельный запрос массивов цен, объемов, спредов, времени
- Чтение цены, объема, спреда и времени по индексу бара
- Поиск максимального и минимального значения в таймсерии
- Работа с массивами реальных тиков в структурах MqlTick
Поиск индекса бара по времени (iBarShift)
Функция iBarShift позволяет получить номер бара для заданного времени. В данном случае нумерация баров всегда подразумевается как в таймсериях, то есть индекс 0 соответствует самому правому, свежему бару, и значения увеличиваются по мере продвижения справа налево (в прошлое).
int iBarShift(const string symbol, ENUM_TIMEFRAMES timeframe, datetime time, bool exact = false)
Функция возвращает индекс бара в таймсерии для указанной пары параметров symbol/timeframe, в который попадает значение параметра time. Напомним, что каждый бар характеризуется временем открытия и длительностью, общей для всех баров ряда, то есть периодом. Например, на часовом таймфрейме бар, помеченный временем открытия 13:00, длится с 13:00:00 по 13:59:59 (включая всю последнюю минуту и секунду).
Если для указанного времени бар отсутствует (например, время приходится на неторговые часы или дни), то функция ведет себя по-разному в зависимости от параметра exact: при exact = true функция вернет -1, а при exact = false — индекс ближайшего бара, у которого время открытия меньше указанного. В случае, когда такого бара нет, то есть история раньше указанного времени отсутствует, функция вернет -1. Но здесь есть нюанс.
Внимание! Возврат из функции iBarShift конкретного номера бара, то есть значения, отличного от -1, не означает, что при последующей попытке доступа к таймсериям по этому индексу удастся получить цены или другие характеристики этого бара. В частности, это может произойти, если запрошенный бар имеет индекс, превышающий лимит баров в окне терминала (TerminalInfoInteger(TERMINAL_MAXBARS)). Такое может произойти по мере формирования новых баров: тогда более старые бары с номерами, превышающими лимит, "сдвигаются" влево за границу видимых баров в окне и чисто номинально остаются на некоторое время в памяти. Обязанность проверять такие ситуации оставлена на плечах прикладных разработчиков.
Проверим работу функций Bars/iBars (см. предыдущий раздел), iBarShift с помощью скрипта SeriesBars.mq5.
void OnStart()
|
Здесь нам встречается еще незнакомая функция ChartTimeOnDropped (мы опишем её позднее): она возвращает время конкретного бара (в активном графике), на который был мышью перемещен из Навигатора и сброшен скрипт. Для начала перетащим скрипт на область графика, где есть котировки.
В журнале создадутся записи следующего вида (числа будут другими, в соответствии с вашими настройками, действиями и текущим временем):
ChartTimeOnDropped()=2021.10.01 09:00:00 / ok
|
В данном случае скрипт был отбуксирован на бар со временем 2021.10.01 09:00 (использовался часовой таймфрейм). Согласно iBarShift это время соответствовало бару под номером 125.
Количество баров от бара под мышью до последнего (текущего времени) составило 126. Это сочетается с номером бара 125, поскольку нумерация начинается с 0.
Общее количество баров на графике, полученное разными способами (iBars, Bars без диапазона дат и Bars с полным диапазоном от 0 до текущего момента TimeCurrent), равно 10004. В настройках терминала стояло ограничение 10000, но за время сеанса успели сформироваться дополнительные 4 часовых бара.
Номер бара, в который попадает текущее время iBarShift(..., TimeCurrent()), всегда равно 0 для существующего символа и таймфрейма, при условии exact = false. Если exact = true, то мы можем иногда получить -1, поскольку серверное время увеличивается по приходу тиков всех инструментов рынка, а текущий символ может временно не торговаться. Тогда серверное время может уйти вперед более чем на размер одного бара, и для TimeCurrent не найдется нового бара для точного попадания в него.
Если перетащить и сбросить скрипт в пустой области справа от текущего, последнего бара (то есть в будущее), получим примерно такую картину:
ChartTimeOnDropped()=2021.10.09 02:30:00 / ok
|
Функция iBarShift в режиме поиска любого предыдущего бара (exact = false) возвращает 0, поскольку текущий бар ближе всего к будущему. Однако точный поиск (exact = true) дает результат -1. Также функции Bars с подсчетом количества баров в диапазоне от текущего времени до "целевого" будущего теперь возвращают 0 (баров там пока нет).
Особую важность функция iBarShift имеет для написания мультивалютных MQL-программ. Довольно часто расписания торгов разными финансовыми инструментами не совпадают, поэтому для конкретного времени бар может существовать на одном символе, но отсутствовать на другом. С помощью функции iBarShift в режиме поиска ближайшего (предыдущего) бара вы всегда можете получить индексы баров с ценами, которые были актуальными для разных символов на один и тот же момент. Как правило, даже для символов Forex индексы исторических баров для одного и того же времени могут отличаться.
Например, следующие инструкции выведут в журнал разные количества баров и их номера на одном и том же диапазоне дат для трех символов: EURUSD, XAUUSD, USDRUB на часовом таймфрейме (сервер MQ Demo):
PRTF(Bars("EURUSD", PERIOD_H1, D'2021.05.01', D'2021.09.01')); // 2087
|