Работа с массивами

Допускаются не более чем четырехмерные массивы. Индексация каждого измерения производится от 0 до размер_измерения-1. В частном случае одномерного массива из 50 элементов обращение к первому элементу будет выглядеть как array[0], к последнему элементу — array[49].

Функция

Действие

ArrayBsearch

Возвращает индекс первого найденного элемента в первом измерении массива

ArrayCopy

Копирует один массив в другой

ArrayCompare

Возвращает результат сравнения двух массивов простых типов или пользовательских структур, не имеющих сложных объектов

ArrayFree

Освобождает буфер любого динамического массива и устанавливает размер нулевого измерения в 0 (ноль)

ArrayGetAsSeries

Проверяет направление индексации массива

ArrayInitialize

Устанавливает все элементы числового массива в одну величину

ArrayFill

Заполняет числовой массив указанным значением

ArrayIsSeries

Проверяет, является ли массив таймсерией

ArrayIsDynamic

Проверяет, является ли массив динамическим

ArrayMaximum

Поиск элемента с максимальным значением

ArrayMinimum

Поиск элемента с минимальным значением

ArrayPrint

Выводит в журнал массив простого типа или простой структуры

ArrayRange

Возвращает число элементов в указанном измерении массива

ArrayResize

Устанавливает новый размер в первом измерении массива

ArraySetAsSeries

Устанавливает направление индексирования в массиве

ArraySize

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

ArraySort

Сортировка числовых массивов по первому измерению

 

ArrayBsearch

Функция ArrayBsearch ищет указанное значение в отсортированном по возрастанию многомерном числовом массиве. Поиск производится по элементам первого измерения.

Для поиска в массиве типа double

int ArrayBsearch(
 const double& array[], // массив для поиска
 double value // значение для поиска
 );

Для поиска в массиве типа float

int ArrayBsearch(
 const float& array[], // массив для поиска
 float value // значение для поиска
 );

Для поиска в массиве типа long

int ArrayBsearch(
 const long& array[], // массив для поиска
 long value // значение для поиска
 );

Для поиска в массиве типа int

int ArrayBsearch(
 const int& array[], // массив для поиска
 int value // значение для поиска
 );

Для поиска в массиве типа short

int ArrayBsearch(
 const short& array[], // массив для поиска
 short value // значение для поиска
 );

Для поиска в массиве типа char

int ArrayBsearch(
 const char& array[], // массив для поиска
 char value // значение для поиска
 );

Параметры

array[] — [in] Числовой массив для поиска.

value — [in] Значение для поиска.

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

Возвращает индекс найденного элемента. Если искомое значение не найдено, то возвращает индекс ближайшего по значению элемента.

Примечание

Двоичный поиск обрабатывает только сортированные массивы. Для сортировки числового массива используется функция ArraySort().

Пример:

#property description "Скрипт на основе данных индикатора RSI выводит в окне графика"
#property description "данные о том, как часто рынок находился в зонах перекупленности"
#property description "и перепроданности в указанном промежутке времени."
//--- покажем окно входных параметров при запуске скрипта
#property script_show_inputs
//--- входные параметры
input int                InpMAPeriod=14;                    // Период скользящей средней
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;       // Тип цены
input double             InpOversoldValue=30.0;             // Уровень перепроданности
input double             InpOverboughtValue=70.0;           // Уровень перекупленности
input datetime           InpDateStart=D'2016.01.01 00:00';  // Дата начала анализа
input datetime           InpDateFinish=D'2017.01.01 00:00'; // Дата конца анализа
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
double rBuffer[]; // массив значений индикатора
int    size=0;     // размер массива
//--- получим хэндл индикатора RSI
ResetLastError();
int rHndl=iRSI(Symbol(),Period(),InpMAPeriod,InpAppliedPrice);
if(rHndl==INVALID_HANDLE)
{
//--- не удалось получить хэндл индикатора
PrintFormat("Ошибка получения хэндла индикатора. Код ошибки = %d",GetLastError());
return;
}
//--- находимся в цикле, пока индикатор не рассчитает все свои значения
while(BarsCalculated(rHndl)==-1)
{
//--- выходим, если пользователь принудительно завершил работу скрипта
if(IsStopped())
return;
//--- задержка, чтобы индикатор успел вычислить свои значения
Sleep(10);
}
//--- скопируем значения индикатора за определенный период
ResetLastError();
if(CopyBuffer(rHndl,0,InpDateStart,InpDateFinish,rBuffer)==-1)
{
PrintFormat("Не удалось скопировать значения индикатора. Код ошибки = %d",GetLastError());
return;
}
//--- получим размер массива
size=ArraySize(rBuffer);
//--- отсортируем массив
ArraySort(rBuffer);
//--- узнаем какой процент времени рынок находился в зоне перепроданности
double ovs=(double)ArrayBsearch(rBuffer,InpOversoldValue)*100/(double)size;
//--- узнаем какой процент времени рынок находился в зоне перекупленности
double ovb=(double)(size-ArrayBsearch(rBuffer,InpOverboughtValue))*100/(double)size;
//--- сформируем строки для вывода данных
string str="С "+TimeToString(InpDateStart,TIME_DATE)+" по "
+TimeToString(InpDateFinish,TIME_DATE)+" рынок находился:";
string sOverbought="в зоне перекупленности "+DoubleToString(ovb,2)+"% времени";
string sOversold="в зоне перепроданности "+DoubleToString(ovs,2)+"% времени";
//--- отобразим данные на графике
CreateLabel("top",5,60,str,clrDodgerBlue);
CreateLabel("overbought",5,35,sOverbought,clrDodgerBlue);
CreateLabel("oversold",5,10,sOversold,clrDodgerBlue);
//--- перерисуем график
ChartRedraw(0);
//--- задержка
Sleep(10000);
}
//+------------------------------------------------------------------+
//| Вывод комментария в левый нижний угол графика                    |
//+------------------------------------------------------------------+
void CreateLabel(const string name,const int x,const int y,
const string str,const color clr)
{
//--- создание метки
ObjectCreate(0,name,OBJ_LABEL,0,0,0);
//--- привязка метки к левому нижнему углу
ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_LOWER);
//--- изменим положение точки привязки
ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
//--- расстояние по оси X от точки привязки
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
//--- расстояние по оси Y от точки привязки
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
//--- текст метки
ObjectSetString(0,name,OBJPROP_TEXT,str);
//--- цвет текста
ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
//--- размер текста
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,12);
}

 

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);
}

 

ArrayCompare

Возвращает результат сравнения двух массивов одинакового типа. Может использоваться для сравнения массивов простых типов или пользовательских структур, не имеющих сложных объектов — то есть не содержащих строк, динамических массивов, классов или других структур содержащих сложные объекты.

int ArrayCompare(
const void& array1[], // первый массив
const void& array2[], // второй массив
int start1=0,         // начальное смещение в первом массиве
int start2=0,         // начальное смещение во втором массиве
int count=WHOLE_ARRAY // количество элементов для сравнения
);

Параметры

array1[] — [in] Первый массив.

array2[] — [in] Второй массив.

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

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

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

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

-1, если array1[] меньше array2[]
0, если array1[] и array2[] равны
1, если array1[] больше array2[]
-2, при возникновении ошибки из-за несовместимости типов сравниваемых массивов, или при значениях start1, start2 или count, приводящих к выходу за пределы массива.

Примечание

При разных размерах сравниваемых массивов и с указанным значением count=WHOLE_ARRAY для случая, когда один массив является точным подмножеством другого, функция не вернёт 0 (массивы не будут считаться равными). В этом случае будет возвращен результат сравнения размеров этих массивов: -1, если размер array1[] меньше размера array2[] или 1 в противном случае.

 

ArrayFree

Освобождает буфер любого динамического массива и устанавливает размер нулевого измерения в 0.

void  ArrayFree(
   void&  array[]      // массив
   );

Параметры

array[] — [in]  Динамический массив.

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

Нет возвращаемого значения.

Примечание

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

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

 

ArrayGetAsSeries

Проверяет направление индексации массива.

bool ArrayGetAsSeries(
const void& array[] // массив для проверки
);

Параметры

array[] — [in] Проверяемый массив.

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

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

Примечание

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

 

ArrayInitialize

Инициализирует числовой массив указанным значением.

Для инициализации массива типа char

int ArrayInitialize(
char array[], // инициализируемый массив
char value // значение, которое будет установлено
);

Для инициализации массива типа short

int ArrayInitialize(
short array[], // инициализируемый массив
short value // значение, которое будет установлено
);

Для инициализации массива типа int

int ArrayInitialize(
int array[], // инициализируемый массив
int value // значение, которое будет установлено
);

Для инициализации массива типа long

int ArrayInitialize(
long array[], // инициализируемый массив
long value // значение, которое будет установлено
);

Для инициализации массива типа float

int ArrayInitialize(
float array[], // инициализируемый массив
float value // значение, которое будет установлено
);

Для инициализации массива типа double

int ArrayInitialize(
double array[], // инициализируемый массив
double value // значение, которое будет установлено
);

Для инициализации массива типа bool

int ArrayInitialize(
bool array[], // инициализируемый массив
bool value // значение, которое будет установлено
);

Для инициализации массива типа uint

int ArrayInitialize(
uint array[], // инициализируемый массив
uint value // значение, которое будет установлено
);

Параметры

array[] — [out] Числовой массив, который нужно инициализировать.

value — [in] Новое значение, которое нужно установить всем элементам массива.

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

Количество инициализированных элементов.

Примечание

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

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

Пример:

void OnStart()
{
//--- динамический массив
   double array[];
//--- зададим размер массива для 100 элементов и зарезервируем еще буфер в 10 элементов
   ArrayResize(array,100,10);
//--- инициализируем элементы массива значением EMPTY_VALUE=DBL_MAX
   ArrayInitialize(array,EMPTY_VALUE);
   Print("Значения последних 10 элементов массива после инициализации");
   for(int i=90;i<100;i++)
 printf("array[%d] = %G",i,array[i]);
//--- увеличим размер массива на 5 элементов
   ArrayResize(array,105);
   Print("Значения последних 10 элементов массива после ArrayResize(array,105)");
//--- значения последних 5 элементов были получены из буфера резерва
   for(int i=95;i<105;i++)
 printf("array[%d] = %G",i,array[i]);
}

 

ArrayFill

Заполняет числовой массив указанным значением.

void ArrayFill(
void& array[], // массив
int start, // индекс начального элемента
int count, // количество элементов
void value // значение, которым заполняется массив
);

Параметры

array[] — [out] Массив простого типа (char, uchar, short, ushort, int, uint, long, ulong, bool, color, datetime, float, double).

start — [in] Индекс начального элемента (с какого элемента заполнять). При этом не учитывается установленный флаг серийности.

count — [in] Количество элементов, которое следует заполнить.

value — [in] Значение, которым заполняется массив.

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

Нет возвращаемого значения.

Примечание

При вызове функции ArrayFill() всегда подразумевается обычное направление индексации – слева направо, то есть изменение порядка доступа к элементам массива с помощью функции ArraySetAsSeries() не принимается во внимание.

Многомерный массив при обработке функцией ArrayFill() представляется одномерным, например, массив array[2][4] обрабатывается как array[8], поэтому при работе с этим массивом допустимо указать индекс начального элемента равным 5. Таким образом, вызов ArrayFill(array, 5, 2, 3.14) для массива array[2][4] заполнит значением 3.14 элементы массива array[1][1] и array[1][2].

Пример:

void OnStart()
{
//--- объявляем динамический массив
   int a[];
//--- устанавливаем размер
   ArrayResize(a,10);
//--- заполняем начальные 5 элементов значением 123
   ArrayFill(a,0,5,123);
//--- заполняем 5 элементов (начиная с 5-го) значением 456
   ArrayFill(a,5,5,456);
//--- выводим значения всех элементов
   for(int i=0;i<ArraySize(a);i++) printf("a[%d] = %d",i,a[i]);
}

 

ArrayIsDynamic

Проверяет, является ли массив динамическим.

bool ArrayIsDynamic(
const void& array[] // проверяемый массив
);

Параметры

array[] — [in] Проверяемый массив.

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

Возвращает true, если указанный массив является динамическим, иначе возвращается false.

Пример:

 

#property description "Этот индикатор не вычисляет значений, а один раз пытается применить"
#property description "вызов функции ArrayFree() к трем массивам: динамическому, статическому и"
#property description "индикаторному буферу. Результаты выводятся в журнал экспертов."
//--- настройки индикатора
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- глобальные переменные
double ExtDynamic[];   // динамический массив
double ExtStatic[100]; // статический массив
bool   ExtFlag=true;   // флаг
double ExtBuff[];      // индикаторный буфер
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- выделим память для массива
   ArrayResize(ExtDynamic,100);
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtBuff);
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
//--- проведем анализ один раз
   if(ExtFlag)
   {
      //--- попробуем освободить память для массивов
      //--- 1. Динамический массив
      Print("+============================+");
      Print("1. Проверка динамического массива:");
      Print("Размер до освобождения памяти = ",ArraySize(ExtDynamic));
      Print("Это динамический массив = ",ArrayIsDynamic(ExtDynamic) ? "Да" : "Нет");
      //--- пытаемся освободить память массива
      ArrayFree(ExtDynamic);
      Print("Размер после освобождения памяти = ",ArraySize(ExtDynamic));
      //--- 2. Статический массив
      Print("2. Проверка статического массива:");
      Print("Размер до освобождения памяти = ",ArraySize(ExtStatic));
      Print("Это динамический массив = ",ArrayIsDynamic(ExtStatic) ? "Да" : "Нет");
      //--- пытаемся освободить память массива
      ArrayFree(ExtStatic);
      Print("Размер после освобождения памяти = ",ArraySize(ExtStatic));
      //--- 3. Индикаторный буфер
      Print("3. Проверка индикаторного буфера:");
      Print("Размер до освобождения памяти = ",ArraySize(ExtBuff));
      Print("Это динамический массив = ",ArrayIsDynamic(ExtBuff) ? "Да" : "Нет");
      //--- пытаемся освободить память массива
      ArrayFree(ExtBuff);
      Print("Размер после освобождения памяти = ",ArraySize(ExtBuff));
      //--- изменим значение флага
      ExtFlag=false;
   }
//--- return value of prev_calculated for next call
   return(rates_total);
}

 

ArrayIsSeries

Проверяет, является ли массив таймсерией.

bool ArrayIsSeries(
const void& array[] // проверяемый массив
);

Параметры

array[] — [in] Проверяемый массив.

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

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

Пример:

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double         Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
}
//+------------------------------------------------------------------+
//| 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[])
{
   if(ArrayIsSeries(open))
      Print("open[] is timeseries");
   else
      Print("open[] is not timeseries!!!");
//--- return value of prev_calculated for next call
   return(rates_total);
}

 

ArrayMaximum

Ищет максимальный элемент в первом измерении многомерного числового массива.

int ArrayMaximum(
const void& array[], // массив для поиска
int start=0, // с какого индекса начинаем поиск
int count=WHOLE_ARRAY // количество проверяемых
);

Параметры

array[] — [in] Числовой массив, в котором производится поиск.

start=0 — [in] Начальный индекс для поиска.

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

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

Возвращает индекс найденного элемента без учета серийности массива. В случае неудачи функция возвращает -1.

Примечание

Поиск максимального элемента производится с учетом значения флага AS_SERIES.

Функции ArrayMaximum и ArrayMinimum принимают в качестве параметра массив любой размерности, при этом поиск происходит только по первому (нулевому) измерению.

 

ArrayMinimum

Ищет минимальный элемент в первом измерении многомерного числового массива.

int ArrayMinimum(
const void& array[], // массив для поиска
int start=0, // с какого индекса начинаем поиск
int count=WHOLE_ARRAY // количество проверяемых
);

Параметры

array[] — [in] Числовой массив, в котором производится поиск.

start=0 — [in] Начальный индекс для поиска.

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

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

Функция возвращает индекс найденного элемента с учетом серийности массива. В случае неудачи функция возвращает -1.

Примечание

Поиск минимального элемента производится с учетом значения флага AS_SERIES.

Функции ArrayMaximum и ArrayMinimum принимают в качестве параметра массив любой размерности, при этом поиск происходит только по первому (нулевому) измерению.

 

ArrayPrint

Выводит в журнал массив простого типа или простой структуры.

void ArrayPrint(
const void& array[],           // выводимый массив
uint digits=_Digits,           // количество десятичных знаков после запятой
const string separator=NULL,   // разделитель между значениями полей структуры
ulong start=0,                 // индекс первого выводимого элемента
ulong count=WHOLE_ARRAY,       // количество выводимых элементов
ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN 
);

Параметры

array[] — [in] Массив простого типа или простой структуры.

digits=_Digits — [in] Количество знаков после запятой для вещественных типов. По умолчанию равно _Digits.

separator=NULL — [in] Разделитель между значениями полей элемента структуры. Значение по умолчанию NULL означает пустую строку, в этом случае разделителем является пробел.

start=0 — [in] Индекс первого выводимого элемента массива. По умолчанию выводится с нулевого индекса.

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

flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN — [in] Комбинация флагов, задающая режим вывода. По умолчанию включены все флаги:

ARRAYPRINT_HEADER – вывод заголовков для массива структур
ARRAYPRINT_INDEX – вывод слева номера индекса
ARRAYPRINT_LIMIT – вывод только 100 первых и 100 последних элементов массива. Используется, если нужно вывести только часть большого массива.
ARRAYPRINT_ALIGN – включить выравнивание выводимых значений – числа будут выравниваться вправо, строки влево.
ARRAYPRINT_DATE – при выводе datetime выводить дату в формате dd.mm.yyyy
ARRAYPRINT_MINUTES – при выводе datetime выводить время в формате HH:MM
ARRAYPRINT_SECONDS – при выводе datetime выводить время в формате HH:MM:SS

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

Нет

Примечание

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

 

ArrayRange

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

int ArrayRange(
const void& array[], // массив для проверки
int rank_index // номер измерения
);

Параметры

array[] — [in] Проверяемый массив.

rank_index — [in] Индекс измерения.

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

Число элементов в указанном измерении массива

Примечание

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

Пример:

void OnStart()
{
//--- создадим четырехмерный массив
double array[][5][2][4];
//--- зададим размер нулевого измерения
ArrayResize(array,10,10);
//--- распечатаем размерности измерений
int temp;
for(int i=0;i<4;i++)
{
//--- получим размер i-ого измерения
temp=ArrayRange(array,i);
//--- распечатаем
PrintFormat("dim = %d, range = %d",i,temp);
}
//--- Результат
// dim = 0, range = 10
// dim = 1, range = 5
// dim = 2, range = 2
// dim = 3, range = 4
}

 

ArrayResize

Устанавливает новый размер в первом измерении массива

int ArrayResize(
void& array[], // массив, переданный по ссылке
int new_size, // новый размер массива
int reserve_size=0 // резервное значение размера (избыточное)
);

Параметры

array[] — [out] Массив для изменения размеров.

new_size — [in] Новый размер для первого измерения.

reserve_size=0 — [in] Размер для дополнительного резерва.

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

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

Если ArrayResize() применена к статическому массиву, таймсерии или индикаторному буферу, то размер массива остается прежним – такие массивы не могут быть перераспределены. В этом случае если new_size<=ArraySize(array), то функция просто вернет new_size; в противном случае будет возвращено -1.

Примечание

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

Общее число элементов в массиве не может превышать 2147483647.

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

ArrayResize(arr,1000,1000);
for(int i=1;i<3000;i++)
ArrayResize(arr,i,1000);

В данном случае произойдёт 2 перераспределения памяти, один раз до входа в цикл на 2000 элементов, при этом размерность массива будет установлена в 1000 и второй при i равной 2000. Если третий параметр опустить, то произойдёт 2000 физических перераспределения памяти и это замедлит выполнение программы.

 

ArraySetAsSeries

Устанавливает флаг AS_SERIES указанному объекту динамического массива, индексация элементов массива будет производиться как в таймсериях.

bool ArraySetAsSeries(
const void& array[], // массив по ссылке
bool flag // true означает обратный порядок индексации
);

Параметры

array[] — [in][out] Числовой массив для установки.

flag — [in] Направление индексирования массива.

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

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

Примечание

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

 

ArraySize

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

int ArraySize(
const void& array[] // проверяемый массив
);

Параметры

array[] — [in] Массив любого типа.

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

Значение типа int.

Примечание

Для одномерного массива значение, возвращаемое функцией ArraySize, равно значению ArrayRange(array,0).

Пример:

void OnStart()
{
//--- создание массивов
double one_dim[];
double four_dim[][10][5][2];
//--- размеры
int one_dim_size=25;
int reserve=20;
int four_dim_size=5;
//--- вспомогательная переменная
int size;
//--- выделим память без резервирования
ArrayResize(one_dim,one_dim_size);
ArrayResize(four_dim,four_dim_size);
//--- 1. одномерный массив
Print("+==========================================================+");
Print("Размеры массивов:");
Print("1. Одномерный массив");
size=ArraySize(one_dim);
PrintFormat("Размер нулевого измерения = %d, Размер массива = %d",one_dim_size,size);
//--- 2. многомерный массив
Print("2. Многомерный массив");
size=ArraySize(four_dim);
PrintFormat("Размер нулевого измерения = %d, Размер массива = %d",four_dim_size,size);
//--- размеры измерений
int d_1=ArrayRange(four_dim,1);
int d_2=ArrayRange(four_dim,2);
int d_3=ArrayRange(four_dim,3);
Print("Проверка:");
Print("Нулевое измерение = Размер массива / (Первое измерение * Второе измерение * Третье измерение)");
PrintFormat("%d = %d / (%d * %d * %d)",size/(d_1*d_2*d_3),size,d_1,d_2,d_3);
//--- 3. одномерный массив с резервированием памяти
Print("3. Одномерный массив с резервированием памяти");
//--- увеличим значение в 2 раза
one_dim_size*=2;
//--- выделим память с резервированием
ArrayResize(one_dim,one_dim_size,reserve);
//--- распечатаем размер
size=ArraySize(one_dim);
PrintFormat("Размер с резервированием = %d, Реальный размер массива = %d",one_dim_size+reserve,size);
}

 

ArraySort

Сортирует многомерный числовой массив по возрастанию значений в первом измерении.

bool ArraySort(
void& array[] // массив для сортировки
);

Параметры

array[] — [in][out] Числовой массив для сортировки.

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

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

Примечание

Массив всегда сортируется по возрастанию, независимо от значения флага AS_SERIES.

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