Скачать MetaTrader 5

ArrayCopy

Производит копирование одного массива в другой.

int  ArrayCopy(
   void&        dst_array[],         // куда копируем
   const void&  src_array[],         // откуда копируем
   int          dst_start=0,         // с какого индекса пишем в приемник
   int          src_start=0,         // с какого индекса копируем из источника
   int          count=WHOLE_ARRAY    // сколько элементов
   );

Параметры

dst_array[]

[out]  Массив-приемник.

src_array[]

[in]  Массив-источник.

dst_start=0

[in]  Начальный индекс для приемного массива. По умолчанию, стартовый индекс - 0.

src_start=0

[in]  Начальный индекс для исходного массива. По умолчанию, стартовый индекс - 0.

count=WHOLE_ARRAY

[in]  Количество элементов, которые нужно скопировать. По умолчанию копируется весь массив (count=WHOLE_ARRAY).

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

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

Примечание

Если count<0 либо count>src_size-src_start, то копируется весь остаток массива. Массивы копируются слева направо. Для серийных массивов правильно переопределяется стартовая позиция с учетом копирования слева направо. Если копируется массив сам в себя, то результат неопределен.

Если массивы разных типов, то при копировании производится попытка преобразования каждого элемента исходного массива к типу приемного массива. Строковый массив можно скопировать только в строковый массив. Массивы классов и структур, содержащих объекты, требующие инициализации, не копируются. Массив структур можно скопировать только в массив того же самого типа.

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

Пример:

#property description "Индикатор выделяет цветом свечи, которые являются локальными"
#property description "максимумами и минимумами. Длину интервала для нахождения"
#property description "экстремумов можно задать при помощи входного параметра."
//--- настройки индикатора
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots   1
//---- plot
#property indicator_label1  "Extremums"
#property indicator_type1   DRAW_COLOR_CANDLES
#property indicator_color1  clrLightSteelBlue,clrRed,clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- предопределенная константа
#define INDICATOR_EMPTY_VALUE 0.0
//--- входные параметры
input int InpNum=4; // Длина полуинтервала
//--- индикаторные буферы
double ExtOpen[];
double ExtHigh[];
double ExtLow[];
double ExtClose[];
double ExtColor[];
//--- глобальные переменные
int    ExtStart=0; // индекс первой свечи, которая не является экстремумом
int    ExtCount=0; // количество свечей не экстремумов в данном интервале
//+------------------------------------------------------------------+
//| Закрашивание свечей не экстремумов                               |
//+------------------------------------------------------------------+
void FillCandles(const double &open[],const double &high[],
                 const double &low[],const double &close[])
  {
//--- закрашиваем свечи
   ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount);
   ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount);
  }
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtOpen);
   SetIndexBuffer(1,ExtHigh);
   SetIndexBuffer(2,ExtLow);
   SetIndexBuffer(3,ExtClose);
   SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX);
//--- зададим значение, которое не будет отображаться
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- зададим имена индикаторных буферов для отображения в окне данных
   PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
   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[])
  {
//--- установим прямое направление индексации в таймсериях
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(close,false);
//--- переменная начала для расчета баров
   int start=prev_calculated;
//--- для первых InpNum*2 баров расчет не проводим
   if(start==0)
     {
      start+=InpNum*2;
      ExtStart=0;
      ExtCount=0;
     }
//--- если только что сформировался бар, то проверим следующий потенциальный экстремум
   if(rates_total-start==1)
      start--;
//--- индекс бара, который будем проверять на экстремум
   int ext;
//--- цикл расчета значений индикатора
   for(int i=start;i<rates_total-1;i++)
     {
      //--- изначально на i-ом баре без отрисовки
      ExtOpen[i]=0;
      ExtHigh[i]=0;
      ExtLow[i]=0;
      ExtClose[i]=0;
      //--- индекс экстремума для проверки
      ext=i-InpNum;
      //--- проверка на локальный максимум
      if(IsMax(high,ext))
        {
         //--- пометим свечу экстремум
         ExtOpen[ext]=open[ext];
         ExtHigh[ext]=high[ext];
         ExtLow[ext]=low[ext];
         ExtClose[ext]=close[ext];
         ExtColor[ext]=1;
         //--- остальные свечи до экстремума пометим нейтральным цветом
         FillCandles(open,high,low,close);
         //--- изменяем значения переменных
         ExtStart=ext+1;
         ExtCount=0;
         //--- переходим к следующей итерации
         continue;
        }
      //--- проверка на локальный минимум
      if(IsMin(low,ext))
        {
         //--- пометим свечу экстремум
         ExtOpen[ext]=open[ext];
         ExtHigh[ext]=high[ext];
         ExtLow[ext]=low[ext];
         ExtClose[ext]=close[ext];
         ExtColor[ext]=2;
         //--- остальные свечи до экстремума пометим нейтральным цветом
         FillCandles(open,high,low,close);
         //--- изменяем значения переменных
         ExtStart=ext+1;
         ExtCount=0;
         //--- переходим к следующей итерации
         continue;
        }
      //--- увеличиваем количество не экстремумов в данном интервале
      ExtCount++;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Является ли текущий элемент массива локальным максимумом         |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
  {
//--- переменная начала интервала
   int i=ind-InpNum;
//--- переменная окончания интервала
   int finish=ind+InpNum+1;
//--- проверка для первой половины интервала
   for(;i<ind;i++)
     {
      if(price[ind]<=price[i])
         return(false);
     }
//--- проверка для второй половины интервала
   for(i=ind+1;i<finish;i++)
     {
      if(price[ind]<=price[i])
         return(false);
     }
//--- это экстремум
   return(true);
  }
//+------------------------------------------------------------------+
//| Является ли текущий элемент массива локальным минимумом          |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
  {
//--- переменная начала интервала
   int i=ind-InpNum;
//--- переменная окончания интервала
   int finish=ind+InpNum+1;
//--- проверка для первой половины интервала
   for(;i<ind;i++)
     {
      if(price[ind]>=price[i])
         return(false);
     }
//--- проверка для второй половины интервала
   for(i=ind+1;i<finish;i++)
     {
      if(price[ind]>=price[i])
         return(false);
     }
//--- это экстремум
   return(true);
  }


Обновлено: 2015.12.03