Доступ к таймсериям

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

copy buffer

 

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

Если ценовые данные предполагается обрабатывать в цикле с большим количество итераций, то рекомендуется проверять факт принудительного завершения программы с помощью функции IsStopped():

int copied=CopyBuffer(ma_handle,// хэндл индикатора
                      0, // индекс индикаторного буфера
                      0, // стартовая позиция для копирования
                      number, // количество значений для копирования 
                      Buffer // массив-получатель значений
 );

if(copied<0) 
   return;

int k=0;
while(k<copied && !IsStopped())
{
   //--- получаем значение для индекса k
   double value=Buffer[k];
   // ... 
   // работа со значением value
   k++;
}

Пример:

input int per=10; // период экспоненты
int ma_handle; // хэндл индикатора

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
   ma_handle=iMA(_Symbol,0,per,0,MODE_EMA,PRICE_CLOSE);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
   double ema[10];
   int copied=CopyBuffer(ma_handle,// хэндл индикатора
                          0, // индекс индикаторного буфера
                          0, // стартовая позиция для копирования
                         10, // количество значений для копирования 
                         ema // массив-получатель значений);
   if(copied<0) return;
   // .... дальнейший код 
}

 

Функция

Действие

SeriesInfoInteger

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

Bars

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

BarsCalculated

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

IndicatorCreate

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

IndicatorParameters

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

IndicatorRelease

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

CopyBuffer

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

CopyRates

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

CopyTime

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

CopyOpen

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

CopyHigh

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

CopyLow

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

CopyClose

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

CopyTickVolume

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

CopyRealVolume

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

CopySpread

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

CopyTicks

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

CopyTicksRange

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

 

SeriesInfoInteger

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

Непосредственно возвращает значение свойства.

long SeriesInfoInteger(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 ENUM_SERIES_INFO_INTEGER prop_id, // идентификатор свойства
 );

Возвращает true или false в зависимости от успешности выполнения функции.

bool SeriesInfoInteger(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 ENUM_SERIES_INFO_INTEGER prop_id, // идентификатор свойства
 long& long_var // переменная для получения информации
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

prop_id — [in] Идентификатор запрашиваемого свойства, значение перечисления ENUM_SERIES_INFO_INTEGER.

long_var — [out] Переменная, в которую помещается значение запрошенного свойства.

Возвращаемое значение

Значение типа long для первого варианта вызова.

Для второго варианта вызова возвращает true, если данное свойство поддерживается и значение было помещено в переменную long_var, иначе возвращает false. Чтобы получить дополнительную информацию об ошибке, необходимо вызвать функцию GetLastError().

Пример:

void OnStart()
{
   Print("Количество баров по символу-периоду на данный момент = ", SeriesInfoInteger(Symbol(),0,SERIES_BARS_COUNT));
 
   Print("Самая первая дата по символу-периоду на данный момент = ", (datetime)SeriesInfoInteger(Symbol(),0,SERIES_FIRSTDATE));
 
   Print("Самая первая дата в истории по символу на сервере = ", (datetime)SeriesInfoInteger(Symbol(),0,SERIES_SERVER_FIRSTDATE));
 
   Print("Данные по символу синхронизированы = ", (bool)SeriesInfoInteger(Symbol(),0,SERIES_SYNCHRONIZED));
}

 

Bars

Возвращает количество баров в истории по соответствующему символу периоду. Существует 2 варианта функции.

Запросить количество всех баров в истории

int Bars(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe // периоду
 );

Запросить количество баров на заданном интервале

int Bars(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time // по какую дату
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

Возвращаемое значение

Если указаны параметры start_time и stop_time, то функция возвращает количество баров в диапазоне дат. Если эти параметры не указаны, то функция возвращает общее количество баров.

Примечание

Если данные для таймсерии с указанными параметрами при вызове функции Bars() еще не сформированы в терминале, или данные таймсерии в момент вызова функции не синхронизированы с торговым сервером, то функция вернет нулевое значение.

При запросе количества баров в заданном диапазоне дат учитываются только те бары, чье время открытия попадает в этот диапазон. Например, если текущий день недели — суббота, то при запросе количества недельных баров с указанием start_time=последний_вторник и stop_time=последняя_пятница функция вернет 0, так как время открытия на недельном таймфрейме всегда приходится на воскресенье, и ни один недельный бар не попадает в указанный диапазон.

Пример запроса количества всех баров в истории:

int bars=Bars(_Symbol,_Period);
if(bars>0)
{
   Print("Количество баров в истории терминала по символу-периоду на данный момент = ",bars);
}
else  //нет доступных баров
{
    //--- видимо, данные по символу не синхронизированы с данными на сервере
    bool synchronized=false;
    //--- счетчик цикла
    int attempts=0;
    // сделаем 5 попыток дождаться синхронизации
    while(attempts<5)
    {
        if(SeriesInfoInteger(Symbol(),0,SERIES_SYNCHRONIZED))
        {
           //--- есть синхронизация, выходим
           synchronized=true;
           break;
        }
  
        //--- увеличим счетчик
        attempts++;
  
        //--- подождем 10 миллисекунд до следующей итерации
        Sleep(10);
    }

    //--- вышли из цикла по факту синхронизации
    if(synchronized)
    {
        Print("Количество баров в истории терминала по символу-периоду на данный момент = ",bars);
        Print("Самая первая в истории терминала дата по символу-периоду на данный момент = ",
               (datetime)SeriesInfoInteger(Symbol(),0,SERIES_FIRSTDATE));
        Print("Самая первая дата в истории по символу на сервере = ",
               (datetime)SeriesInfoInteger(Symbol(),0,SERIES_SERVER_FIRSTDATE));
    }
    //--- синхронизация данных так и не была достигнута
    else
    {
        Print("Не удалось получить количество баров на ",_Symbol);
    }
}

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

int n;
datetime date1 = D'2016.09.02 23:55'; // пятница
datetime date2 = D'2016.09.05 00:00'; // понедельник
datetime date3 = D'2016.09.08 00:00'; // четверг

 //---
n=Bars(_Symbol,PERIOD_H1,D'2016.09.02 02:05',D'2016.09.02 10:55');
Print("Количество баров: ",n); // Выведет "Количество баров: 8", в подсчете будет учтен двухчасовой бар, а одиннадцатичасовой - не будет
n=Bars(_Symbol,PERIOD_D1,date1,date2);
Print("Количество баров: ",n); // Выведет "Количество баров: 1", поскольку в диапазон попало время открытия только одного дневного бара — за понедельник
n=Bars(_Symbol,PERIOD_W1,date2,date3);
Print("Количество баров: ",n); // Выведет "Количество баров: 0", поскольку в заданный диапазон не попадает время открытия ни одного недельного бара

 

BarsCalculated

Возвращает количество рассчитанных данных для запрашиваемого индикатора.

int BarsCalculated(
 int indicator_handle, // handle индикатора
 );

Параметры

indicator_handle — [in] Хэндл индикатора, полученный соответствующей индикаторной функцией.

Возвращаемое значение

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

Примечание

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

Пример:

void OnStart()
{
   double Ups[];

   //--- установим для массивов признак таймсерии
   ArraySetAsSeries(Ups,true);

   //--- создадим хэндл индикатора Fractals
   int FractalsHandle=iFractals(NULL,0);

   //--- сбросим код ошибки
   ResetLastError();

   //--- попытаемся скопировать значения индикатора
   int i,copied=CopyBuffer(FractalsHandle,0,0,1000,Ups);
   if(copied<=0)
   {
      Sleep(50);
      for(i=0;i<100;i++)
      {
         if(BarsCalculated(FractalsHandle)>0)
           break;
         Sleep(50);
      }

      copied=CopyBuffer(FractalsHandle,0,0,1000,Ups);
      if(copied<=0)
      {
         Print("Не удалось скопировать верхние фракталы. Error = ",GetLastError(), "i=",i," copied= ",copied);
         return; 
      }
      else
         Print("Удалось скопировать верхние фракталы.", " i = ",i," copied = ",copied);
   }
   else Print("Удалось скопировать верхние фракталы. ArraySize = ",ArraySize(Ups));
}

 

IndicatorCreate

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

int IndicatorCreate(
 string symbol, // имя символа
 ENUM_TIMEFRAMES period, // период
 ENUM_INDICATOR indicator_type, // тип индикатора из перечисления ENUM_INDICATOR
 int parameters_cnt=0, // количество параметров
 const MqlParam& parameters_array[]=NULL, // массив параметров
 );

Параметры

symbol — [in] Символьное имя инструмента, на данных которого будет вычисляться индикатор. NULL означает текущий символ.

period — [in] Значение периода может быть одним из значений перечисления ENUM_TIMEFRAMES, 0 означает текущий таймфрейм.

indicator_type — [in] Тип индикатора, может принимать одно из значений перечисления ENUM_INDICATOR.

parameters_cnt — [in] Количество параметров, передаваемых в массиве parameters_array[]. Элементы массива имеют специальный тип структуры MqlParam. По умолчанию нулевое значение — параметры не передаются. Если указано ненулевое количество параметров, то параметр parameters_array является обязательным. Можно передавать не более 256 параметров.

parameters_array[]=NULL — [in] Массив типа MqlParam, элементы которого содержат тип и значение каждого входного параметра технического индикатора.

Возвращаемое значение

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

Примечание

Если создается хэндл индикатора типа IND_CUSTOM, то поле type первого элемента массива входных параметров parameters_array обязательно должен иметь значение TYPE_STRING из перечисления ENUM_DATATYPE, а поле string_value первого элемента должно содержать имя пользовательского индикатора. Пользовательский индикатор должен быть скомпилирован (файл с расширением EX5) и находиться в директории MQL5/Indicators клиентского терминала или вложенной поддиректории.

Необходимые для тестирования индикаторы определяются автоматически из вызова функций iCustom(), если соответствующий параметр задан константной строкой. Для остальных случаев (использование функции IndicatorCreate() или использование неконстантной строки в параметре, задающем имя индикатора) необходимо указать свойство #property tester_indicator:

#property tester_indicator "indicator_name.ex5"

Если в пользовательском индикаторе используется первая форма вызова, то при передаче входных параметров последним параметром можно дополнительно указать на каких данных он будет рассчитываться. Если параметр «Apply to» не указан явно, то по умолчанию расчет производится по значениям PRICE_CLOSE.

Пример:

void OnStart()
{
   MqlParam params[];
   int h_MA,h_MACD;

   //--- create iMA("EURUSD",PERIOD_M15,8,0,MODE_EMA,PRICE_CLOSE);
   ArrayResize(params,4);

   //--- set ma_period
   params[0].type =TYPE_INT;
   params[0].integer_value=8;

   //--- set ma_shift
   params[1].type =TYPE_INT;
   params[1].integer_value=0;

   //--- set ma_method
   params[2].type =TYPE_INT;
   params[2].integer_value=MODE_EMA;

   //--- set applied_price
   params[3].type =TYPE_INT;
   params[3].integer_value=PRICE_CLOSE;

   //--- create MA
   h_MA=IndicatorCreate("EURUSD",PERIOD_M15,IND_MA,4,params);

   //--- create iMACD("EURUSD",PERIOD_M15,12,26,9,h_MA);
   ArrayResize(params,4);

   //--- set fast ma_period
   params[0].type =TYPE_INT;
   params[0].integer_value=12;

   //--- set slow ma_period
   params[1].type =TYPE_INT;
   params[1].integer_value=26;

   //--- set smooth period for difference
   params[2].type =TYPE_INT;
   params[2].integer_value=9;

   //--- set indicator handle as applied_price
   params[3].type =TYPE_INT;
   params[3].integer_value=h_MA;

   //--- create MACD based on moving average
   h_MACD=IndicatorCreate("EURUSD",PERIOD_M15,IND_MACD,4,params);

   //--- use indicators
   //--- . . .
   //--- release indicators (first h_MACD)
   IndicatorRelease(h_MACD);
   IndicatorRelease(h_MA);
}

 

IndicatorParameters

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

int IndicatorParameters(
 int indicator_handle, // хэндл индикатора
 ENUM_INDICATOR& indicator_type, // переменная для получения типа индикатора
 MqlParam& parameters[] // массив для получения параметров
 );

Параметры

indicator_handle — [in] Хэндл индикатора, для которого необходимо узнать количество параметров, на которых он рассчитан.

indicator_type — [out] Переменная типа ENUM_INDICATOR, в которую будет записан тип индикатора.

parameters[] — [out] Динамический массив для получения значений типа MqlParam, в который будет записан список параметров индикатора. Размер массива возвращает сама функция IndicatorParameters().

Возвращаемое значение

Количество входных параметров индикатора с указанным хэндлом, в случае ошибки возвращает -1. Чтобы получить информацию об ошибке, необходимо вызвать функцию GetLastError().

Пример:

//+------------------------------------------------------------------+
void OnStart()
{
   //--- количество окон на графике (всегда есть хотя бы одно главное окно)
   int windows=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);

   //--- проходим по окнам графика
   for(int w=0;w<windows;w++)
   {
      //--- сколько индикаторов в данном окне/подконе
      int total=ChartIndicatorsTotal(0,w);

      //--- переберем все индикаторы в окне
      for(int i=0;i<total;i++)
      {
         //--- получим короткое имя индикатора
         string name=ChartIndicatorName(0,w,i);

         //--- получим хэндл индикатора
         int handle=ChartIndicatorGet(0,w,name);

         //--- выведем в журнал
         PrintFormat("Window=%d, indicator #%d, handle=%d",w,i,handle);

         MqlParam parameters[];
         ENUM_INDICATOR indicator_type;
         int params=IndicatorParameters(handle,indicator_type,parameters);

         //--- заголовок сообщения
         string par_info="Short name "+name+", type " +EnumToString(ENUM_INDICATOR(indicator_type))+"\r\n";

         for(int p=0;p<params;p++)
         {
            par_info+=StringFormat("parameter %d: type=%s, long_value=%d, double_value=%G,string_value=%s\r\n", p,
                                   EnumToString((ENUM_DATATYPE)parameters[p].type),
                                   parameters[p].integer_value,
                                   parameters[p].double_value,
                                   parameters[p].string_value);
         }

         Print(par_info);
      }
      //--- прошли по всем индикаторам в окне
   }
}

 

IndicatorRelease

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

bool IndicatorRelease(
 int indicator_handle // handle индикатора
 );

Возвращаемое значение

Возвращает true в случае успеха, иначе false.

Примечание

Функция позволяет удалять хэндл индикатора, если он больше не нужен, и таким образом позволяет экономить память. Удаление хендла производится сразу, удаление расчетной части индикатора производится через некоторое небольшое время (если обращений к ней больше нет).

При работе в тестере стратегий функция IndicatorRelease() не выполняется.

 

CopyBuffer

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

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

При копировании заранее неизвестного количества данных в качестве массива-приемника buffer[] желательно использовать динамический массив, так как функция CopyBuffer() старается распределить размер принимающего массива под размер копируемых данных. Если в качестве принимающего массива buffer[] выступает индикаторный буфер (массив, предварительно назначенный под хранение значений индикатора функцией SetIndexBufer()), то допускается частичное копирование. Пример можно посмотреть в пользовательском индикаторе Awesome_Oscillator.mq5 из стандартной поставки терминала.

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyBuffer(
 int indicator_handle, // handle индикатора
 int buffer_num, // номер буфера индикатора
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 double buffer[] // массив, куда будут скопированы данные
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyBuffer(
 int indicator_handle, // handle индикатора
 int buffer_num, // номер буфера индикатора
 datetime start_time, // с какой даты
 int count, // сколько копируем
 double buffer[] // массив, куда будут скопированы данные
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyBuffer(
 int indicator_handle, // handle индикатора
 int buffer_num, // номер буфера индикатора
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 double buffer[] // массив, куда будут скопированы данные
 );

Параметры

indicator_handle — [in] Хэндл индикатора, полученный соответствующей индикаторной функцией.

buffer_num — [in] Номер индикаторного буфера.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

buffer[] — [out] Массив типа double.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

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

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

Пример:

//+------------------------------------------------------------------+
//| TestCopyBuffer3.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
 
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot MA
#property indicator_label1 "MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input bool AsSeries=true;
input int period=15;
input ENUM_MA_METHOD smootMode=MODE_EMA;
input ENUM_APPLIED_PRICE price=PRICE_CLOSE;
input int shift=0;
//--- indicator buffers
double MABuffer[];
int ma_handle;

//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- indicator buffers mapping
   SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
   Print("Параметр AsSeries = ",AsSeries);
   Print("Индикаторный буфер после SetIndexBuffer() является таймсерией = ",
   ArrayGetAsSeries(MABuffer));

   //--- set short indicator name
   IndicatorSetString(INDICATOR_SHORTNAME,"MA("+period+")"+AsSeries);

   //--- set AsSeries (depends on input parameter)
   ArraySetAsSeries(MABuffer,AsSeries);
   Print("Индикаторный буфер после ArraySetAsSeries(MABuffer,true); является таймсерией = ",
   ArrayGetAsSeries(MABuffer));

   //---
   ma_handle=iMA(Symbol(),0,period,shift,smootMode,price);
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
 const int prev_calculated,
 const datetime &time[],
 const double &open[],
 const double &high[],
 const double &low[],
 const double &close[],
 const long &tick_volume[],
 const long &volume[],
 const int &spread[])
{
   //--- check if all data calculated
   if(BarsCalculated(ma_handle)<rates_total) 
      return(0);

   //--- we can copy not all data
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) to_copy=rates_total;
   else
   {
      to_copy=rates_total-prev_calculated;
      //--- last value is always copied
      to_copy++;
   }

   //--- try to copy
   if(CopyBuffer(ma_handle,0,0,to_copy,MABuffer)<=0) return(0);

   //--- return value of prev_calculated for next call
   return(rates_total);
}

В вышеприведенном примере продемонстрировано заполнение индикаторного буфера значениями другого индикаторного буфера от индикатора на том же символе/периоде.

 

CopyRates

Получает в массив rates_array исторические данные структуры MqlRates указанного символа-периода в указанном количестве. Отсчет элементов от стартовой позиции ведется от настоящего к прошлому, то есть стартовая позиция, равная 0, означает текущий бар.

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyRates(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 MqlRates rates_array[] // массив, куда будут скопированы данные
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyRates(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 MqlRates rates_array[] // массив, куда будут скопированы данные
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyRates(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 MqlRates rates_array[] // массив, куда будут скопированы данные
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_time — [in] Время бара, соответствующее первому элементу.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

stop_time — [in] Время бара, соответствующее последнему элементу.

rates_array[] — [out] Массив типа MqlRates.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Если интервал запрашиваемых данных полностью находится вне доступных данных на сервере, то функция возвращает -1. В случае если запрашиваются данные за пределами TERMINAL_MAXBARS (максимальное количество баров на графике), функция также вернет -1.

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

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

При запросе данных по начальной дате и количеству требуемых элементов возвращаются только данные, дата которых меньше (раньше) или равна указанной. При этом интервал задается и учитывается с точностью до секунды. То есть дата открытия любого бара, для которого возвращается значение (объем, спред, значение в индикаторном буфере, цена Open, High, Low, Close или время открытия Time), всегда равна или меньше указанной.

При запросе данных в заданном диапазоне дат возвращаются только данные, попадающие в запрашиваемый интервал, при этом интервал задается и учитывается с точностью до секунды. То есть время открытия любого бара, для которого возвращается значение (объем, спред, значение в индикаторном буфере, цена Open, High, Low, Close или время открытия Time), всегда находится в запрошенном интервале.

Таким образом, если текущий день недели Суббота, то при попытке скопировать данные на недельном таймфрейме с указанием start_time=Последний_Вторник и stop_time=Последняя_Пятница функция вернет 0, так как время открытия на недельном таймфрейме всегда приходится на воскресенье, но ни один недельный бар не попадает в указанный диапазон.

Если необходимо получить значение, соответствующее текущему незавершенному бару, то можно использовать первую форму вызова с указанием start_pos=0 и count=1.

Пример:

void OnStart()
{
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   int copied=CopyRates(Symbol(),0,0,100,rates);
   if(copied>0)
   {
      Print("Скопировано баров: "+copied);
      string format="open = %G, high = %G, low = %G, close = %G, volume = %d";
      string out;
      int size=fmin(copied,10);

      for(int i=0;i<size;i++)
      {
         out=i+":"+TimeToString(rates[i].time);
         out=out+" "+StringFormat(format,
         rates[i].open,
         rates[i].high,
         rates[i].low,
         rates[i].close,
         rates[i].tick_volume);
         Print(out);
      }
   }
   else Print("Не удалось получить исторические данные по символу ",Symbol());
}

 

CopyTime

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

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyTime(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 datetime time_array[] // массив для копирования времени открытия
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyTime(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 datetime time_array[] // массив для копирования времени открытия
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyTime(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 datetime time_array[] // массив для копирования времени открытия
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

time_array[] — [out] Массив типа datetime.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopyOpen

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

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

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

Неважно, какое свойство имеет приёмный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyOpen(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 double open_array[] // массив для копирования цен открытия
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyOpen(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 double open_array[] // массив для копирования цен открытия
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyOpen(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 double open_array[] // массив для копирования цен открытия
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

open_array[] — [out] Массив типа double.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopyHigh

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

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyHigh(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 double high_array[] // массив для копирования максимальных цен
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyHigh(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 double high_array[] // массив для копирования максимальных цен
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyHigh(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 double high_array[] // массив для копирования максимальных цен
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

high_array[] — [out] Массив типа double.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopyLow

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

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyLow(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 double low_array[] // массив для копирования минимальных цен
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyLow(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 double low_array[] // массив для копирования минимальных цен
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyLow(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 double low_array[] // массив для копирования минимальных цен
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

low_array[] — [out] Массив типа double.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopyClose

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

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyClose(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 double close_array[] // массив для копирования цен закрытия
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyClose(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 double close_array[] // массив для копирования цен закрытия
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyClose(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 double close_array[] // массив для копирования цен закрытия
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

close_array[] — [out] Массив типа double.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopyTickVolume

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

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyTickVolume(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 long volume_array[] // массив для копирования тиковых объемов
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyTickVolume(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 long volume_array[] // массив для копирования тиковых объемов
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyTickVolume(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 long volume_array[] // массив для копирования тиковых объемов
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

volume_array[] — [out] Массив типа long.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopyRealVolume

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

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopyRealVolume(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 long volume_array[] // массив для копирования объемов
 );

Обращение по начальной дате и количеству требуемых элементов

int CopyRealVolume(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 long volume_array[] // массив для копирования объемов
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopyRealVolume(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 long volume_array[] // массив для копирования объемов
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

volume_array[] — [out] Массив типа long.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopySpread

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

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

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

Неважно, какое свойство имеет приемный массив — as_series=true или as_series=false, данные будут скопированы таким образом, что самый старый по времени элемент будет в начале физической памяти, отведенной под массив. Существует 3 варианта функции.

Обращение по начальной позиции и количеству требуемых элементов

int CopySpread(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 int start_pos, // откуда начнем 
 int count, // сколько копируем
 int spread_array[] // массив для копирования спредов
 );

Обращение по начальной дате и количеству требуемых элементов

int CopySpread(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 int count, // сколько копируем
 int spread_array[] // массив для копирования спредов
 );

Обращение по начальной и конечной датам требуемого интервала времени

int CopySpread(
 string symbol_name, // имя символа
 ENUM_TIMEFRAMES timeframe, // период
 datetime start_time, // с какой даты
 datetime stop_time, // по какую дату
 int spread_array[] // массив для копирования спредов
 );

Параметры

symbol_name — [in] Символ.

timeframe — [in] Период.

start_pos — [in] Номер первого копируемого элемента.

count — [in] Количество копируемых элементов.

start_time — [in] Время бара, соответствующее первому элементу.

stop_time — [in] Время бара, соответствующее последнему элементу.

spread_array[] — [out] Массив типа int.

Возвращаемое значение

Количество скопированных элементов массива либо -1 в случае ошибки.

Примечание

Аналогично CopyRates().

 

CopyTicks

Функция получает в массив ticks_array тики в формате MqlTick, при этом индексация ведётся от прошлого к настоящему, то есть тик с индексом 0 является самым старым в массиве. Для анализа тика необходимо проверять поле flags, которое сообщает, что именно было изменено в данном тике.

int CopyTicks(
 string symbol_name, // имя символа
 MqlTick& ticks_array[], // массив для приёма тиков
 uint flags=COPY_TICKS_ALL, // флаг, определяющий тип получаемых тиков
 ulong from=0, // дата, начиная с которой запрашиваются тики
 uint count=0 // количество тиков, которые необходимо получить
 );

Параметры

symbol_name — [in] Символ.

ticks_array — [out] Массив типа MqlTick для приема тиков.

flags — [in] Флаг, определяющий тип запрашиваемых тиков. COPY_TICKS_INFO – тики, вызванные изменениями Bid и/или Ask, COPY_TICKS_TRADE – тики с изменения Last и Volume, COPY_TICKS_ALL – все тики. При любом типе запроса в оставшиеся поля структуры MqlTick дописываются значения предыдущего тика.

from — [in] Дата, начиная с которой запрашиваются тики. Указывается в миллисекундах с 01.01.1970. Если параметр from=0, то отдаются последние count тиков.

count — [in] Количество запрашиваемых тиков. Если параметры from и count не указаны, то в массив ticks_array[] будут записаны все доступные последние тики, но не более 2000.

Возвращаемое значение

Количество скопированных тиков либо -1 в случае ошибки.

Примечание

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

Если параметры from и count не указаны, то в массив ticks_array[] будут записаны все доступные тики, но не более 2000. Параметр flags позволяет задать тип требуемых тиков.

COPY_TICKS_INFO – отдаются тики, в которых есть изменения цены Bid и/или Ask. Но при этом будут также заполнены данные остальных полей, например, если изменилась только цена Bid, то в поля ask и volume будут записаны последние известные значения. Чтобы узнать точно, что именно изменилось, необходимо анализировать поле flags, которое будет иметь значение TICK_FLAG_BID и/или TICK_FLAG_ASK. Если тик имеет нулевые значения цен Bid и Ask, и при этом флаги показывают, что эти данные цены изменились (flags=TICK_FLAG_BID|TICK_FLAG_ASK), то это говорит об опустошении стакана заявок. Другими словами, в этот момент отсутствуют заявки на покупку и продажи.

COPY_TICKS_TRADE – отдаются тики, в которых есть изменения последней цены сделки и объема. Но при этом будут также заполнены данные остальных полей, то есть в поля Bid и Ask будут записаны последние известные значения. Чтобы узнать точно, что именно изменилось, необходимо анализировать поле flags, которое будет иметь значение TICK_FLAG_LAST и TICK_FLAG_VOLUME.

COPY_TICKS_ALL – отдаются все тики, в которых есть хоть какое-то изменение. При этом неизмененные поля также заполняются последними известными значениями.

Вызов CopyTicks() с флагом COPY_TICKS_ALL выдает сразу все тики из запрашиваемого диапазона, в то время как вызов в других режимах требует некоторого времени на предобработку и выборку тиков, и поэтому не даёт существенного выигрыша по скорости выполнения.

При запросе тиков (неважно, COPY_TICKS_INFO или COPY_TICKS_TRADE), в каждом тике содержится полная ценовая информация на момент тика (bid, ask, last и volume). Это сделано для удобства анализа торговой обстановки на момент каждого тика, чтобы не приходилось каждый раз запрашивать глубокую тиковую историю и искать в ней значения по другим полям.

В индикаторах функция CopyTicks() возвращает результат немедленно: При вызове из индикатора CopyTick() сразу же вернёт доступные по символу тики, а также запустит синхронизацию базы тиков, если данных не хватило. Все индикаторы на одном символе работают в одном общем потоке, поэтому индикатор не имеет права ждать завершения синхронизации. После окончания синхронизации при последующем вызове CopyTicks() вернёт все запрашиваемые тики. Функция OnCalculate() в индикаторах вызывается после поступления каждого тика.

В экспертах и скриптах функция CopyTicks() может дожидаться результата до 45 секунд: В отличие от индикатора каждый эксперт и скрипт работает в собственном потоке, и поэтому может дожидаться окончания синхронизации до 45 секунд. Если за это время тики так и не будут синхронизированы в необходимом объёме, то CopyTicks() по таймауту вернёт только имеющиеся в наличии тики, при этом синхронизация продолжится. Функция OnTick() в экспертах не является обработчиком каждого тика, она лишь уведомляет эксперта об изменениях на рынке. Изменения могут быть пакетными: в терминал может одновременно прийти несколько тиков, но функция OnTick() будет вызвана лишь один раз для уведомления эксперта о последнем состоянии рынка.

Скорость выдачи: терминал хранит по каждому символу 4096 последних тиков в кеше для быстрого доступа (для символов с запущенным стаканом – 65536 тиков), запросы к этим данным выполняются быстрее всего. При запросе тиков текущей торговой сессии за пределами кеша CopyTicks() обращается уже к тикам, которые хранятся в памяти терминала, эти запросы требуют большего времени на выполнение. Самыми медленными являются запросы тиков за другие дни, так как в этом случае данные читаются уже с диска.

 

CopyTicksRange

Функция получает в массив ticks_array тики в формате MqlTick в указанном диапазоне дат. При этом индексация ведётся от прошлого к настоящему, то есть тик с индексом 0 является самым старым в массиве. Для анализа тика необходимо проверять поле flags, которое сообщает о том, что именно изменилось.

int CopyTicksRange(
 const string symbol_name, // имя символа
 MqlTick& ticks_array[], // массив для приёма тиков
 uint flags=COPY_TICKS_ALL, // флаг, определяющий тип получаемых тиков
 ulong from_msc=0, // дата, начиная с которой запрашиваются тики
 ulong to_msc=0 // дата, по которую запрашиваются тики
 );

Параметры

symbol_name — [in] Символ.

ticks_array — [out] Cтатический или динамический массив MqlTick для приема тиков. Если в статический массив не вмещаются все тики из запрошенного интервала времени, то будет получено столько тиков, сколько помещается в массив. При этом функция сгенерирует ошибку ERR_HISTORY_SMALL_BUFFER (4407) .

flags — [in] Флаг, определяющий тип запрашиваемых тиков. COPY_TICKS_INFO – тики, вызванные изменениями Bid и/или Ask, COPY_TICKS_TRADE – тики с изменения Last и Volume, COPY_TICKS_ALL – все тики. При любом типе запроса в оставшиеся поля структуры MqlTick дописываются значения предыдущего тика.

from_msc — [in] Дата, начиная с которой запрашиваются тики. Указывается в миллисекундах с 01.01.1970. Если параметр from_msc не указан, то отдаются тики от самого начала истории. Отдаются тики со временем >= from_msc.

to_msc — [in] Дата, по которую запрашиваются тики. Указывается в миллисекундах с 01.01.1970. Отдаются тики со временем <= to_msc. Если параметр to_msc не указан, то отдаются все тики до конца истории.

Возвращаемое значение

Количество скопированных тиков либо -1 в случае ошибки. GetLastError() может возвращать следующие ошибки:

  • ERR_HISTORY_TIMEOUT – время ожидание синхронизации тиков вышло, функция отдала всё что было.
  • ERR_HISTORY_SMALL_BUFFER – статический буфер слишком маленький, отдано столько, сколько поместилось в массив.
  • ERR_NOT_ENOUGH_MEMORY – не хватает памяти для получения истории из указаного диапазона в динамический массив тиков. Не удалось выделить нужный объем памяти под массиве тиков.

Примечание

Функция CopyTicksRange() предназначена для запроса тиков из строго указанного диапазона, например, за конкретный день истории. В то время как CopyTicks() позволяет указать только начальную дату, например – получить все тики с начала месяца по текущий момент.