CopyBuffer

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

copyBuffer

Отсчет элементов копируемых данных (индикаторный буфер с индексом 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);
  }
//+------------------------------------------------------------------+

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

Более полный пример запроса исторических данных смотрите в разделе Способы привязки объектов. В приведенном там скрипте показано, как получать значения индикатора iFractals на последних 1000 барах и как потом вывести  на график по десять последних фракталов вверх и вниз. Подобный прием можно использовать для всех индикаторов, которые имеют пропуски значений и обычно реализуются с помощью следующих стилей построения:

Смотри также

Свойства пользовательских индикаторов, SetIndexBuffer