Справочник MQL4 Доступ к таймсериям и индикаторам Направление индексации в массивах и таймсериях
Направление индексации в массивах, буферах и таймсерияхВсе массивы и индикаторные буферы по умолчанию имеют направление индексации слева направо. Индекс первого элемента всегда равен нулю. Таким образом, самый первый элемент массива или индикаторного буфера с индексом 0 по умолчанию находится на крайней левой позиции, последний элемент находится на крайней правой позиции. Индикаторный буфер представляет из себя динамический массив типа double, размером которого управляет клиентский терминал с тем, чтобы он всегда соответствовал количеству баров, на которых индикатор рассчитывается. Обычный динамический массив типа double назначается в качестве индикаторного буфера с помощью функции SetIndexBuffer(). Для индикаторных буферов не требуется задавать размер с помощью функции ArrayResize(), исполняющая система терминала сама позаботится об этом. Таймсерии представляют из себя массивы с обратной индексацией, то есть самый первый элемент таймсерии находится на крайней правой позиции, а последний элемент таймсерии находится на крайней левой позиции. Так как таймсерии предназначены для хранения исторических ценовых данных по финансовым инструментам и обязательно содержат информацию о времени, то можно сказать, что самые свежие данные в таймсерии находятся в правой крайней позиции, а самые старые в крайней левой позиции. Поэтому, элемент с индексом ноль в таймсерии содержит информацию о самой последней котировке по инструменту. Если таймсерия представляет данные по дневному таймфрейму, то на нулевой позиции содержатся данные текущего незавершенного дня, а на позиции с индексом один хранятся данные вчерашнего дня. Изменение направления индексацииФункция ArraySetAsSeries() позволяет изменять способ доступа к элементам динамического массива, но при этом физически порядок хранения данных в памяти компьютера не изменяется. Эта функция просто изменяет способ адресации к элементам массива, поэтому при копировании одного массива в другой с помощью функции ArrayCopy() содержимое массива-приемника не будет зависеть от направления индексации в массиве-источнике. Нельзя изменять направление индексации для статически распределенных массивов. Даже если массив был передан в качестве параметра в функцию, то и внутри этой функции попытки изменения направления индексации ни к чему не приведут. Для индикаторных буферов, как и для обычных массивов, также разрешается устанавливать направление индексации задом наперед как в таймсерии, то есть, обращение к нулевой позиции в индикаторном буфере в этом случае будет означать обращение к самому последнему значению в соответствующем индикаторном буфере и это будет соответствовать значению индикатора на самом последнем баре. При этом физически размещение данных в индикаторном буфере останется неизменным, как уже упоминалось. Получение ценовых данных в индикаторахВ каждом пользовательском индикаторе обязательно должна присутствовать функция OnCalculate(), которой передаются ценовые данные, необходимые для расчета значений в индикаторных буферах. Направление индексации в этих переданных массивах можно выяснить с помощью функции ArrayGetAsSeries(). Переданные в функцию массивы отражают ценовые данные, т.е. эти массивы имеют признак таймсерии и функция ArrayIsSeries() вернет true при проверке этих массивов. Но тем не менее, направление индексации необходимо в любом случае проверять только функцией ArrayGetAsSeries(). Чтобы не зависеть от умолчаний, необходимо безусловно вызывать функцию ArraySetAsSeries() для тех массивов, с которыми предполагается работать, и установить требуемое направление индексации. Получение ценовых данных и значений индикаторовВ экспертах, индикаторах и скриптах все массивы по умолчанию имеют направление индексации слева направо. При необходимости в любой mql4-программе можно запросить значения таймсерий по любому символу и таймфрейму, а также значения индикаторов, рассчитанных на любом символе и таймфрейме. Для получения таких данных служат функции Copy...():
Все эти функции работают одинаково, и поэтому достаточно рассмотреть механизм получения данных на примере CopyOpen(). Подразумевается, что все запрашиваемые данные имеют направление индексации, как в таймсерии, при этом подразумевается, что в позиции с индексом 0 (ноль) хранятся данные текущего незавершенного бара. Чтобы получить доступ к этим данным, нам необходимо скопировать нужный нам объем данных в массив-приемник, например, в массив buffer. При копировании необходимо указать стартовую позицию в массиве-источнике, начиная с которой будут копироваться данные в массив-приемник. В случае успеха в массив-получатель будет скопировано указанное количество элементов из массива-источник, в данном случае из индикаторного буфера. При этом независимо от того, какое направление индексации установлено в массиве получателе, копирование всегда производится так, как указано на рисунке. Смотри также ArrayGetAsSeries, ArrayIsSeries, ArraySetAsSeries |