Русский

Справочник MQL4 Доступ к таймсериям и индикаторам Направление индексации в массивах и таймсериях

Направление индексации в массивах, буферах и таймсериях

Все массивы и индикаторные буферы по умолчанию имеют направление индексации слева направо. Индекс первого элемента всегда равен нулю. Таким образом, самый первый элемент массива или индикаторного буфера с индексом 0 по умолчанию находится на крайней левой позиции, последний элемент находится на крайней правой позиции.

Индикаторный буфер представляет из себя динамический массив типа double, размером которого управляет клиентский терминал с тем, чтобы он всегда соответствовал количеству баров, на которых индикатор рассчитывается. Обычный динамический массив типа double назначается в качестве индикаторного буфера с помощью функции SetIndexBuffer(). Для индикаторных буферов не требуется задавать размер с помощью функции ArrayResize(), исполняющая система терминала сама позаботится об этом.

Таймсерии представляют из себя массивы с обратной индексацией, то есть самый первый элемент таймсерии находится на крайней правой позиции, а последний элемент таймсерии находится на крайней левой позиции. Так как таймсерии предназначены для хранения исторических ценовых данных по финансовым инструментам и обязательно содержат информацию о времени, то можно сказать, что самые свежие данные в таймсерии находятся в правой крайней позиции, а самые старые в крайней левой позиции.

Поэтому, элемент с индексом ноль в таймсерии содержит информацию о самой последней котировке по инструменту. Если таймсерия представляет данные по дневному таймфрейму, то на нулевой позиции содержатся данные текущего незавершенного дня, а на позиции с индексом один хранятся данные вчерашнего дня.

Изменение направления индексации

Функция ArraySetAsSeries() позволяет изменять способ доступа к элементам динамического массива, но при этом физически порядок хранения данных в памяти компьютера не изменяется. Эта функция просто изменяет способ адресации к элементам массива, поэтому при копировании одного массива в другой с помощью функции ArrayCopy() содержимое массива-приемника не будет зависеть от направления индексации в массиве-источнике.

Нельзя изменять направление индексации для статически распределенных массивов. Даже если массив был передан в качестве параметра в функцию, то и внутри этой функции попытки изменения направления индексации ни к чему не приведут.

Для индикаторных буферов, как и для обычных массивов, также разрешается устанавливать направление индексации задом наперед как в таймсерии, то есть, обращение к нулевой позиции в индикаторном буфере в этом случае будет означать обращение к самому последнему значению в соответствующем индикаторном буфере и это будет соответствовать значению индикатора на самом последнем баре. При этом физически размещение данных в индикаторном буфере останется неизменным, как уже упоминалось.

Получение ценовых данных в индикаторах

В каждом пользовательском индикаторе обязательно должна присутствовать функция OnCalculate(), которой передаются ценовые данные, необходимые для расчета значений в индикаторных буферах. Направление индексации в этих переданных массивах можно выяснить с помощью функции ArrayGetAsSeries().

Переданные в функцию массивы отражают ценовые данные, т.е. эти массивы имеют признак таймсерии и функция ArrayIsSeries() вернет true при проверке этих массивов. Но тем не менее, направление индексации необходимо в любом случае проверять только функцией ArrayGetAsSeries().

Чтобы не зависеть от умолчаний, необходимо безусловно вызывать функцию ArraySetAsSeries() для тех массивов, с которыми предполагается работать, и установить требуемое направление индексации.

Получение ценовых данных и значений индикаторов

В экспертах, индикаторах и скриптах все массивы по умолчанию имеют направление индексации слева направо. При необходимости в любой mql4-программе можно запросить значения таймсерий по любому символу и таймфрейму, а также значения индикаторов, рассчитанных на любом символе и таймфрейме.

Для получения таких данных служат функции Copy...():

  • CopyRates – копирование ценовой истории в массив структур MqlRates;
  • CopyTime – копирование значений Time в массив типа datetime;
  • CopyOpen – копирование значений Open в массив типа double;
  • CopyHigh – копирование значений High в массив типа double;
  • CopyLow – копирование значений Low в массив типа double;
  • CopyClose – копирование значений Close в массив типа double;
  • CopyTickVolume – копирование тиковых объемов в массив типа long;

 

Все эти функции работают одинаково, и поэтому достаточно рассмотреть механизм получения данных на примере CopyOpen(). Подразумевается, что все запрашиваемые данные имеют направление индексации, как в таймсерии, при этом подразумевается, что в позиции с индексом 0 (ноль) хранятся данные текущего незавершенного бара. Чтобы получить доступ к этим данным, нам необходимо скопировать нужный нам объем данных в массив-приемник, например, в массив buffer.

CopyOpen

При копировании необходимо указать стартовую позицию в массиве-источнике, начиная с которой будут копироваться данные в массив-приемник. В случае успеха в массив-получатель будет скопировано указанное количество элементов из массива-источник, в данном случае из индикаторного буфера. При этом независимо от того, какое направление индексации установлено в массиве получателе, копирование всегда производится так, как указано на рисунке.

Смотри также

ArrayGetAsSeries, ArrayIsSeries, ArraySetAsSeries