Доступ к таймсериям и данным индикаторов

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

Из этого правила есть важное исключение: если копирование таймсерий и значений индикаторов необходимо делать часто, например, при каждом вызове OnTick() в экспертах или при каждом вызове OnCalculate() в индикаторах, то в этом случае лучше использовать статически распределенные массивы, так как операции распределения памяти под динамические массивы требуют дополнительного времени и это скажется при тестировании и оптимизации экспертов.

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

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

В разделе Организация доступа к данным дается подробное описание тонкостей получения, хранения и запроса ценовых данных в клиентском терминале MetaTrader 5.

Направление индексации в таймсерии и в обычном массиве

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

Таймфрейм –  период времени, в течение которого формируется один ценовой бар; всего предопределен 21 стандартный таймфрейм.

Функция

Действие

SeriesInfoInteger

Возвращает информацию о состоянии исторических данных

Bars

Возвращает количество баров в истории по соответствующим символу и периоду

BarsCalculated

Возвращает количество рассчитанных данных в индикаторном буфере или -1 в случае ошибки (данные еще не рассчитаны)

IndicatorCreate

Возвращает хэндл указанного технического индикатора, созданного на основе массива параметров типа MqlParam

IndicatorParameters

Возвращает по указанному хэндлу количество входных параметров индикатора, а также сами значения и тип параметров

IndicatorRelease

Удаляет хэндл индикатора и освобождает расчетную часть индикатора, если ею больше никто не пользуется

CopyBuffer

Получает в массив данные указанного буфера от указанного индикатора

CopyRates

Получает в массив исторические данные структуры Rates для указанных символа и периода

CopySeries

Получает в указанный набор массивов синхронизированные таймсерии из структуры Rates для указанного символа-периода в указанном количестве

CopyTime

Получает в массив исторические данные по времени открытия баров по соответствующим символу и периоду

CopyOpen

Получает в массив исторические данные по цене открытия баров по соответствующим символу и периоду

CopyHigh

Получает в массив исторические данные по максимальной цене баров по соответствующим символу и периоду

CopyLow

Получает в массив исторические данные по минимальной цене баров по соответствующим символу и периоду

CopyClose

Получает в массив исторические данные по цене закрытия баров по соответствующим символу и периоду

CopyTickVolume

Получает в массив исторические данные по тиковым объемам для соответствующих символа и периода

CopyRealVolume

Получает в массив исторические данные по торговым объемам для соответствующих символа и периода

CopySpread

Получает в массив исторические данные по спредам для соответствующих символа и периода

CopyTicks

Получает в массив тики в формате MqlTick

CopyTicksRange

Получает в массив тики в указанном диапазоне дат

iBars

Возвращает количество баров в истории по соответствующему символу и периоду

iBarShift

Возвращает индекс бара, в который попадает указанное время

iClose

Возвращает значение цены закрытия бара (указанного параметром shift) соответствующего графика

iHigh

Возвращает значение максимальной цены бара (указанного параметром shift) соответствующего графика

iHighest

Возвращает индекс наибольшего найденного значения (смещение относительно текущего бара) соответствующего графика

iLow

Возвращает значение минимальной цены бара (указанного параметром shift) соответствующего графика

iLowest

Возвращает индекс наименьшего найденного значения (смещение относительно текущего бара) соответствующего графика

iOpen

Возвращает значение цены открытия бара (указанного параметром shift) соответствующего графика

iTime

Возвращает значение времени открытия бара (указанного параметром shift) соответствующего графика

iTickVolume

Возвращает значение тикового объема бара (указанного параметром shift) соответствующего графика

iRealVolume

Возвращает значение реального объема бара (указанного параметром shift) соответствующего графика

iVolume

Возвращает значение тикового объема бара (указанного параметром shift) соответствующего графика

iSpread

Возвращает значение спреда бара (указанного параметром shift) соответствующего графика

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

   datetime TimeAsSeries[];
//--- установим доступ к массиву как к таймсерии
   ArraySetAsSeries(TimeAsSeries,true);
   ResetLastError();
   int copied=CopyTime(NULL,0,0,10,TimeAsSeries);
   if(copied<=0)
     {
      Print("Не удалось скопировать время открытия для последних 10 баров");
      return;
     }
   Print("TimeCurrent = ",TimeCurrent());
   Print("ArraySize(Time) = ",ArraySize(TimeAsSeries));
   int size=ArraySize(TimeAsSeries);
   for(int i=0;i<size;i++)
     {
      Print("TimeAsSeries["+i+"] = ",TimeAsSeries[i]);
     }
 
   datetime ArrayNotSeries[];
   ArraySetAsSeries(ArrayNotSeries,false);
   ResetLastError();
   copied=CopyTime(NULL,0,0,10,ArrayNotSeries);
   if(copied<=0)
     {
      Print("Не удалось скопировать время открытия для последних 10 баров");
      return;
     }   
   size=ArraySize(ArrayNotSeries);
   for(int i=size-1;i>=0;i--)
     {
      Print("ArrayNotSeries["+i+"] = ",ArrayNotSeries[i]);
     }

В результате будет произведен вывод подобный этому:

TimeCurrent = 2009.06.11 14:16:23
ArraySize(Time) = 10
TimeAsSeries[0] = 2009.06.11 14:00:00
TimeAsSeries[1] = 2009.06.11 13:00:00
TimeAsSeries[2] = 2009.06.11 12:00:00
TimeAsSeries[3] = 2009.06.11 11:00:00
TimeAsSeries[4] = 2009.06.11 10:00:00
TimeAsSeries[5] = 2009.06.11 09:00:00
TimeAsSeries[6] = 2009.06.11 08:00:00
TimeAsSeries[7] = 2009.06.11 07:00:00
TimeAsSeries[8] = 2009.06.11 06:00:00
TimeAsSeries[9] = 2009.06.11 05:00:00
 
ArrayNotSeries[9] = 2009.06.11 14:00:00
ArrayNotSeries[8] = 2009.06.11 13:00:00
ArrayNotSeries[7] = 2009.06.11 12:00:00
ArrayNotSeries[6] = 2009.06.11 11:00:00
ArrayNotSeries[5] = 2009.06.11 10:00:00
ArrayNotSeries[4] = 2009.06.11 09:00:00
ArrayNotSeries[3] = 2009.06.11 08:00:00
ArrayNotSeries[2] = 2009.06.11 07:00:00
ArrayNotSeries[1] = 2009.06.11 06:00:00
ArrayNotSeries[0] = 2009.06.11 05:00:00

Как видно из результатов вывода, для массива TimeAsSeries с ростом индекса уменьшается значение времени, находящегося под этим индексом, то есть мы продвигаемся от настоящего к прошлому. Для обычного массива ArrayNotSeries все наоборот - с ростом индекса мы двигаемся из прошлого к настоящему.

Смотри также

ArrayIsDynamic, ArrayGetAsSeries, ArraySetAsSeries, ArrayIsSeries