English Español Deutsch 日本語
preview
Введение в MQL5 (Часть 6): Функции для работы с массивами для начинающих (II)

Введение в MQL5 (Часть 6): Функции для работы с массивами для начинающих (II)

MetaTrader 5Трейдинг | 26 августа 2024, 12:16
66 2
Israel Pelumi Abioye
Israel Pelumi Abioye

Введение

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

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

В этой статье мы рассмотрим следующие функции для работы с массивами:

  • ArrayPrint
  • ArrayInsert
  • ArraySize
  • ArrayRange
  • ArrarRemove
  • ArraySwap
  • ArrayReverse
  • ArraySort

1. ArrayPrint

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

Аналогия

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

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

Синтаксис:
ArrayPrint(array[], digit , Separator, Start, Count, Flags);

Параметры:

  • array[] — массив, который будет выведен. Это может быть массив различных типов данных или массив из простой структуры.
  • Digits — количество знаков после запятой в отображаемых значениях.
  • Separator — разделитель между элементами в массиве.
  • Start — индекс элемента, с которого нужно начать печать данных.
  • Count — количество элементов для печати.
  • Flags — флаги для изменения вывода. Необязательный параметр. ARRAYPRINT_HEADER — вывод заголовков для массива структур, ARRAYPRINT_INDEX — вывод индекса с левой стороны, ARRAYPRINT_LIMIT — вывести только первые 100 и последние 100 элементов массива. ARRAYPRINT_ALIGN — флаг включает выравнивание выводимых значений, ARRAYPRINT_DATE — печатает дату в формате дня, месяца и года.

Пример:

void OnStart()
  {

// Define an array of doubles
   double ThisArray[] = { 1.46647, 2.76628, 3.83367, 4.36636, 5.9393};

// Print the entire array using ArrayPrint with 2 decimal places and a single spacing between array elements
   ArrayPrint(Array,2," ",0,WHOLE_ARRAY);

  }

Объяснение:

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

Давайте разберем параметры, используемые в функции ArrayPrint():

  • "ThisArray" — массив, который нужно напечатать.
  • "2" — количество знаков после запятой в отображении элементов массива.
  • " " — одиночный пробел в качестве разделителя между элементами.
  • "0" — начинаем печать с начала массива.
  • “WHOLE_ARRAY” — печатаем весь массив.
Выводимая информация:

Рисунок 1. Вывод кода в MetaTrader 5

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

Пример:

void OnStart()
  {

// Define a structure for storing information about students
   struct StudentsDetails
     {
      string         name;
      int            age;
      string         address;
      datetime       time; // Add a time field
     };

// Create an array of Students structures
   StudentsDetails Students[3];

// Fill in details for each person
   Students[0].name = "Abioye";
   Students[0].age = 25;
   Students[0].address = "123 MQL5 St";
   Students[0].time = TimeCurrent();

   Students[1].name = "Israel";
   Students[1].age = 26;
   Students[1].address = "456 MQL4 St";
   Students[1].time = TimeCurrent();

   Students[2].name = "Pelumi";
   Students[2].age = 27;
   Students[2].address = "789 MetaQuotes St";
   Students[2].time = TimeCurrent();

// Print the details of each person using ArrayPrint
   ArrayPrint(Students, 0, " | ", 0, WHOLE_ARRAY);

  }

Объяснение:

struct StudentsDetails
{
   string         name;
   int            age;
   string         address;
   datetime       time; // Add a time field
};

  • Здесь определена структура под названием StudentsDetails для хранения данных о студентах.
  • В качестве элементов структуры добавляются имя, возраст, адрес, а также время и дата текущего дня.
StudentsDetails Students[3];

  • Создается массив с именем Students типа StudentsDetails размером 3, он позволяет хранить данные о трех студентах.

Students[0].name = "Abioye";
Students[0].age = 25;
Students[0].address = "123 MQL5 St";
Students[0].time = TimeCurrent();

Students[1].name = "Israel";
Students[1].age = 26;
Students[1].address = "456 MQL4 St";
Students[1].time = TimeCurrent();

Students[2].name = "Pelumi";
Students[2].age = 27;
Students[2].address = "789 MetaQuotes St";
Students[2].time = TimeCurrent();

  • Заполняются данные каждого студента. Например, полям имени, возраста, адреса и времени присваиваются значения, при этом Students[0] означает первого студента.
ArrayPrint(Students, 0, " | ", 0, WHOLE_ARRAY);
  • Для отображения всей информации о студенте в массиве используется функция ArrayPrint(). Массив выводится, при этом разделителем полей является « | ».
Выводимая информация:

Рисунок 2. Вывод кода в MetaTrader 5

Мы используем функцию ArrayPrint() для отображения информации о студенте после ввода всех необходимых данных о каждом студенте. На изображении выше показан вывод по умолчанию, на котором показано, как отображаются данные без дополнительных флагов форматирования. Благодаря специальному разделителю «|» имя каждого учащегося, его возраст, адрес, а также текущее время и дата отображаются в четком виде. Это первый вариант представления. Рассмотрим, как добавить дополнительные параметры форматирования для дальнейшей настройки вывода.  

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

Пример:

ArrayPrint(Students, 0, " | ", 0, WHOLE_ARRAY,ARRAYPRINT_HEADER);

Выводимая информация:

Рисунок 3. Вывод кода в MetaTrader 5


Чтобы было проще понять назначение каждого поля, мы добавили флаг для включения заголовков ([name] [age] [address] [time]) для массива структур. ARRAYPRINT_INDEX — один из флагов, которые намеренно опущены в данном случае, чтобы подчеркнуть, как каждый флаг функционирует сам по себе.

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

Важно отметить, что при работе с данными времени функция ArrayPrint обеспечивает еще большую универсальность. Для настройки формата времени можно использовать такие флаги, как ARRAYPRINT_MINUTES и ARRAYPRINT_SECONDS. Эти флаги дают вам возможность настроить уровень детализации отображаемого времени. Если выбрать флаг ARRAYPRINT_MINUTES, функция выведет только текущий час и минуты, опустив дату и секунды. С другой стороны, использование флага ARRAYPRINT_SECONDS еще больше уточняет вывод, отображая только часы, минуты и секунды. Используя флаги, вы можете выбрать нужный уровень детализации, а также не включать ненужные подробности.

Пример:

ArrayPrint(Students, 0, " | ", 0, WHOLE_ARRAY,ARRAYPRINT_MINUTES);

Выводимая информация:

Рисунок 4. Вывод кода в MetaTrader 5

Эти флаги не являются взаимоисключающими. Вы можете комбинировать их? чтобы настроить вывод нужной информации. Например, если применить флаги ARRAYPRINT_HEADER и ARRAYPRINT_MINUTES одновременно, функция включит заголовки столбцов и представит время в формате, который показывает только текущий час и минуты.

Пример:

ArrayPrint(Students,0," | ",0,WHOLE_ARRAY,ARRAYPRINT_HEADER | ARRAYPRINT_MINUTES);

Выводимая информация:

Рисунок 5. Вывод кода в MetaTrader 5

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


2. ArrayInsert

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

Разница между ArrayInsert и ArrayCopy:

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

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

Аналогия

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

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

Для статических наборов (массивов) существует важное правило. Если количество новых блоков слишком велико, функция ArrayInsert() их не добавит. А если вставлять элементы с самого начала набора (индекс 0), функция может заменить весь набор новыми блоками. Понимание этих концепций поможет вам стать мастером в программировании на MQL5.

Синтаксис:

ArrayInsert(DestinationArray[],SourceArray[],DestinationIndexStart,SourceIndexStart,count);

Параметры:

  • DestinationArray[] — массив-приемник, который будет получать элементы из исходного массива.
  • SourceArray[] — исходный массив, который необходимо вставить в целевой.
  • DestinationIndexStart — индекс, с которого начинается вставка в целевом массиве.
  • SourceIndexStart — индекс в исходном массиве для копирования элементов.
  • Count — количество добавляемых элементов из массива-источника.
Пример:
void OnStart()
  {

// Declare two dynamic arrays
   int SourceArray[];
   int DestinationArray[];

// Resizing the dynamic arrays to have 5 elements each
   ArrayResize(SourceArray, 5);
   ArrayResize(DestinationArray, 5);

// Assigning values to dynamic array elements
   SourceArray[0] = 1;
   SourceArray[1] = 3;
   SourceArray[2] = 5;
   SourceArray[3] = 7;
   SourceArray[4] = 9;

// Assigning different values to DestinationArray
   DestinationArray[0] = 15;
   DestinationArray[1] = 20;
   DestinationArray[2] = 25;
   DestinationArray[3] = 30;
   DestinationArray[4] = 35;

// Print the elements of SourceArray before ArrayInsert/ArrayCopy
   Print("Elements of SourceArray before ArrayInsert/ArrayCopy: ");
   ArrayPrint(SourceArray, 2, " ", 0, WHOLE_ARRAY);

// Print the elements of DestinationArray before ArrayInsert/ArrayCopy
   Print("Elements of DestinationArray before ArrayInsert/ArrayCopy: ");
   ArrayPrint(DestinationArray, 2, " ", 0, WHOLE_ARRAY);

// Using ArrayInsert to insert SourceArray into DestinationArray at index 2
   ArrayInsert(DestinationArray, SourceArray, 2, 0, WHOLE_ARRAY);

// Print the modified DestinationArray after ArrayInsert
   Print("Elements of DestinationArray after using ArrayInsert: ");
   ArrayPrint(DestinationArray, 2, " ", 0, WHOLE_ARRAY);

// Reset DestinationArray to demonstrate ArrayCopy
   ArrayFree(DestinationArray);
   ArrayResize(DestinationArray, 5);

   DestinationArray[0] = 15;
   DestinationArray[1] = 20;
   DestinationArray[2] = 25;
   DestinationArray[3] = 30;
   DestinationArray[4] = 35;

// Using ArrayCopy to copy elements from SourceArray to DestinationArray
   ArrayCopy(DestinationArray, SourceArray, 2, 0, WHOLE_ARRAY);

// Print the modified DestinationArray after ArrayCopy
   Print("Elements of DestinationArray after using ArrayCopy: ");
   ArrayPrint(DestinationArray, 2, " ", 0, WHOLE_ARRAY);

  }
Объяснение:

int SourceArray[];
int DestinationArray[];

  • Здесь объявляются два динамических массива SourceArray и DestinationArray. В этих массивах будут храниться значения типа integer.

ArrayResize(SourceArray, 5);
ArrayResize(DestinationArray, 5);

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

SourceArray[0] = 1;
SourceArray[1] = 3;
SourceArray[2] = 5;
SourceArray[3] = 7;
SourceArray[4] = 9;

  • Элементам в SourceArray присваиваются значения.
DestinationArray[0] = 15;
DestinationArray[1] = 20;
DestinationArray[2] = 25;
DestinationArray[3] = 30;
DestinationArray[4] = 35;
  • Элементам в DestinationArray присваиваются значения.
Print("Elements of SourceArray before ArrayInsert/ArrayCopy: ");
ArrayPrint(SourceArray, 2, " ", 0, WHOLE_ARRAY);
  • Здесь используется функция ArrayPrint(), которая выводит элементы массива SourceArray в консоль. В качестве разделителя используется пробел, а в формате отображаются два десятичных знака.
Print("Elements of DestinationArray before ArrayInsert/ArrayCopy: ");
ArrayPrint(DestinationArray, 2, " ", 0, WHOLE_ARRAY);
  • Здесь такое же сообщение выводится для DestinationArray.
ArrayInsert(DestinationArray, SourceArray, 2, 0, WHOLE_ARRAY);
  • В это строке элементы из SourceArray вставляются в DestinationArray, начиная с индекса 2, с помощью функции ArrayInsert().
Print("Elements of DestinationArray after using ArrayInsert: ");
ArrayPrint(DestinationArray, 2, " ", 0, WHOLE_ARRAY);
  • После операции ArrayInsert() выводится сообщение с новыми элементами DestinationArray.
ArrayFree(DestinationArray);
ArrayResize(DestinationArray, 5);
  • Здесь изменяем размер массива DestinationArray так, чтобы он снова содержал пять элементов после освобождения памяти.
DestinationArray[0] = 15;
DestinationArray[1] = 20;
DestinationArray[2] = 25;
DestinationArray[3] = 30;
DestinationArray[4] = 35;
  • Элементам массива DestinationArray снова присваиваем значения.
ArrayCopy(DestinationArray, SourceArray, 2, 0, WHOLE_ARRAY);
  • В этой строке используется функция ArrayCopy для копирования элементов из SourceArray в DestinationArray, начиная с индекса 2.
Print("Elements of DestinationArray after using ArrayCopy: ");
ArrayPrint(DestinationArray, 2, " ", 0, WHOLE_ARRAY);
  • Выводится сообщение с новыми элементами DestinationArray, полученными после операции ArrayCopy().

Выводимая информация:

Рисунок 6. Вывод кода в MetaTrader 5

Данный пример кода демонстрирует разницу между функциями ArrayInsert() и ArrayCopy(). Работа с элементами массива является общим для обеих функций, их результаты отличаются. В этом примере используются два динамических массива — SourceArray и DestinationArray. Перед выполнением каких-либо операций скрипт отображает элементы, содержащиеся в этих массивах. Затем для вставки элементов из SourceArray в указанные места внутри DestinationArray() используется функция ArrayInsert. После этого массивы сбрасываются, а элементы из SourceArray копируются в DestinationArray() с помощью функции ArrayCopy(). При вставке элементов в определенную позицию в целевой массив, ArrayInsert() перемещает существующие элементы, чтобы освободить место для новых элементов. Это полезно, если вам нужно разместить элементы по нужному индексу. С помощью ArrayCopy() элементы из исходного массива копируются и заменяют любые существующие элементы в целевом массиве. Эффективно копирует элементы между массивами, не затрагивая уже установленные значения.


3. ArraySize

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

Аналогия

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

Синтаксис:
ArraySize( array[]);

Параметры:

  • array[] — массив, размер которого нужно узнать.
Пример:

void OnStart()
  {

// Declare an array
   int array[5];

// Get the size of the array using ArraySize
   int arraySize = ArraySize(array);

// Print the array size
   Print("The size of array is: ", arraySize); // Output will be 5

  }

Объяснение:

“int array[5];”

  • В этой строке объявлен целочисленный массив с именем «array» и размером «5».

“int arraySize = ArraySize(array);”

  • Здесь создается новая целочисленная переменная с именем arraySize, ее значение устанавливается равным результату ArraySize (array) с помощью оператора присваивания "=". Поскольку размер массива всегда является целым числом, используется тип int. Функция называется ArraySize (первая буква в верхнем регистре), а переменная, которую мы объявили для хранения результата, называется arraySize (начинается с нижнего регистра). Необходимо учитывать отношение к регистру у языков программирования. ArraySize в верхнем регистре обозначает встроенный массив, а arraySize нашу конкретную переменную.

“Print("The size of array is: ", arraySize);”:

  • Здесь используется функция Print для вывода сообщения на консоль. Она показывает размер массива, который выводится из переменной arraySize.

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


4. ArrayRange

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

Разница между ArrayRange и ArraySize

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

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

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

Аналогия

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

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

Синтаксис:

ArrayRange(array[], dimensionIndex);

Параметры:

  • array[] — массив, в котором проверяем диапазон.
  • dimensionIndex — индекс размерности начиная с 0, для которого необходимо определить диапазон.
Пример:

void OnStart()
  {

// Declare a three-dimensional array
   double my3DArray[][2][4];

// Get the range of the first dimension (index 0)
   int dimension1Index = ArrayRange(my3DArray, 0);

// Get the range of the second dimension (index 1)
   int dimension2Index = ArrayRange(my3DArray, 1);

// Get the range of the third dimension (index 2)
   int dimension3Index = ArrayRange(my3DArray, 2);

   Print("Number of elements in dimension 1: ", dimension1Index);
   Print("Number of elements in dimension 2: ", dimension2Index);
   Print("Number of elements in dimension 3: ", dimension3Index);

  }

Объяснение:

double my3DArray[][2][4];
  • В этой строке объявлен трехмерный массив с именем my3DArray.

int dimension1Index = ArrayRange(my3DArray, 0);
  • В этом случае диапазон (количество элементов) в первом измерении my3DArray (индекс 0) определяется с помощью функции ArrayRange(). Результат сохраняется в переменной dimension1Index.
int dimension2Index = ArrayRange(my3DArray, 1);
  • Аналогично эта строка получает и сохраняет в переменной dimension2Index диапазон второго измерения (индекс 1) my3DArray.

int dimension3Index = ArrayRange(my3DArray, 2);

  • Здесь присваиваем значение переменной dimension3Index равной диапазону третьего измерения (индекс 2) в my3DArray.

Print("Number of elements in dimension 1: ", dimension1Index);
Print("Number of elements in dimension 2: ", dimension2Index);
Print("Number of elements in dimension 3: ", dimension3Index);

  • Наконец, показываем результаты и количество элементов в каждом измерении с помощью функции Print. В выводимую информацию включены первое, второе и третье измерения размеров трехмерного массива.
Выводимая информация:

Рисунок 7. Вывод кода в MetaTrader 5



5. ArrayRemove

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

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

Аналогия

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

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

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

 

Синтаксис:
ArrayRemove(array[],start_index,count);
Параметры:

  • array[] — массив, в котором нужно удалить элементы. Зона хранения или книжная полка, где нужно внести изменения.
  • start_index — начальный индекс, с которого начнется удаление элементов. Например, индекс 3.
  • count — количество элементов, которые необходимо удалить. Если вы хотите удалить три книги, установите значение 3.
Пример:
void OnStart()
  {

// Declare fixed-size array
   int fixedSizeArray[5] = {11, 13, 17, 21, 42};

// Declare dynamic array
   int dynamicArray[];
   ArrayResize(dynamicArray, 5);
   dynamicArray[0] = 11;
   dynamicArray[1] = 13;
   dynamicArray[2] = 17;
   dynamicArray[3] = 21;
   dynamicArray[4] = 42;

// Print initial arrays
   Print("Initial fixedSizeArray: ");
   ArrayPrint(fixedSizeArray, 0, " ", 0, WHOLE_ARRAY);

   Print("Initial dynamicArray: ");
   ArrayPrint(dynamicArray, 0, " ", 0, WHOLE_ARRAY);

// Remove two elements at index 2 from both arrays
   ArrayRemove(fixedSizeArray, 2, 2);
   ArrayRemove(dynamicArray, 2, 2);

// Print arrays after removal
   Print("After removing 3 elements at index 2 - fixedSizeArray: ");
   ArrayPrint(fixedSizeArray, 0, " ", 0, WHOLE_ARRAY);

   Print("After removing 3 elements at index 2 - dynamicArray: ");
   ArrayPrint(dynamicArray, 0, " ", 0, WHOLE_ARRAY);

  }
Объяснение:

// Declare fixed-size array
   int fixedSizeArray[5] = {11, 13, 17, 21, 42};

// Declare dynamic array
   int dynamicArray[];
   ArrayResize(dynamicArray, 5);
   dynamicArray[0] = 11;
   dynamicArray[1] = 13;
   dynamicArray[2] = 17;
   dynamicArray[3] = 21;
   dynamicArray[4] = 42;

  • Объявляет целочисленный статический массив с фиксированным размером 5 fixedSizeArray. Использует значения 11, 13, 17, 21 и 42 для инициализации массива.
  • Объявляет целочисленный динамический массив с именем dynamicArray без указания начального размера. Изменяет размер dynamicArray до 5 с помощью функции ArrayResize.

Print("Initial fixedSizeArray: ");
ArrayPrint(fixedSizeArray, 0, " ", 0, WHOLE_ARRAY);

Print("Initial dynamicArray: ");
ArrayPrint(dynamicArray, 0, " ", 0, WHOLE_ARRAY);

  • Выводит начальные элементы fixedSizeArray и dynamicArray с использованием функции ArrayPrint.
ArrayRemove(fixedSizeArray, 2, 2);
ArrayRemove(dynamicArray, 2, 2);
  • С помощью ArrayRemove удаляются два элемента из fixedSizeArray и dynamicArray, начиная с индекса 2.
Print("After removing 3 elements at index 2 - fixedSizeArray: ");
ArrayPrint(fixedSizeArray, 0, " ", 0, WHOLE_ARRAY);

Print("After removing 3 elements at index 2 - dynamicArray: ");
ArrayPrint(dynamicArray, 0, " ", 0, WHOLE_ARRAY);
  • После удаления используется функция ArrayPrint для вывода элементов fixedSizeArray и dynamicArray.
Выводимая информация:

 

Рисунок 8. Вывод кода в MetaTrader 5

Результат работы этого кода показан на рисунке выше. Там показано, как функция ArrayRemove() ведет себя со статическими и с динамическими массивами. Что касается динамического массива, процедура очень проста: она заключается в удалении элементов, указанных в указанном индексе. Чтобы заполнить пустые места, образовавшиеся в результате удаления, функция для статического массива дублирует элементы, которые появляются после конца массива. Это поведение демонстрирует, как функция ArrayRemove() подстраивается под различные типы массивов.

Концепции ArrayRemove() станут более понятными по мере изучения этих статей и рассмотрения реальных примеров. Если что-то осталось непонятным, задавайте больше вопросов; вместе мы продолжим изучать и понимать эти концепции.


6. ArraySwap

Назначение функции ArraySwap() в MQL5 — менять местами содержимое двух динамических массивов. С помощью этой функции можно обменивать все элементы между двумя массивами. Функция позволяет поменять весь сет в массивах.

Аналогия

Предположим, у вас есть два книжных шкафа, заполненных книгами. Функция ArraySwap() позволяет заменить каждую книгу на одной полке на каждую другую книгу. Чтобы переместить все книги с Полки A на Полку B, а все книги с Полки B на Полку A, вы можете использовать функцию ArraySwap(), если у вас Полка A заполнена одними книгами, а Полка B заполнена другими книгами. Это простой способ обменяться книгами на двух полках.

Синтаксис:
ArraySwap(dynamic_array1, dynamic_array2);

Параметры:

Предположим, у вас есть два книжных шкафа, заполненных книгами. Функция ArraySwap() позволяет заменить каждую книгу на одной полке на каждую другую книгу. Чтобы переместить все книги с Полки A на Полку B, а все книги с Полки B на Полку A, вы можете использовать функцию ArraySwap(), если у вас Полка A заполнена одними книгами, а Полка B заполнена другими книгами. Это простой способ обменяться книгами на двух полках.

Пример:

void OnStart()
  {

// Declare dynamic arrays
   int dynamic_array1[];
   int dynamic_array2[];

// Resize dynamic arrays to have 5 elements each
   ArrayResize(dynamic_array1, 5);
   ArrayResize(dynamic_array2, 5);

// Assign values to dynamic arrays
   dynamic_array1[0] = 1;
   dynamic_array1[1] = 3;
   dynamic_array1[2] = 5;
   dynamic_array1[3] = 7;
   dynamic_array1[4] = 9;

   dynamic_array2[0] = 11;
   dynamic_array2[1] = 13;
   dynamic_array2[2] = 15;
   dynamic_array2[3] = 17;
   dynamic_array2[4] = 19;

// Print initial dynamic arrays
   Print("Initial dynamic_array1: ");
   ArrayPrint(dynamic_array1, 0, " ", 0, WHOLE_ARRAY);

   Print("Initial dynamic_array2: ");
   ArrayPrint(dynamic_array2, 0, " ", 0, WHOLE_ARRAY);

// Swap the contents of dynamic_array1 and dynamic_array2
   ArraySwap(dynamic_array1, dynamic_array2);

// Print dynamic arrays after swapping
   Print("After swapping - dynamic_array1: ");
   ArrayPrint(dynamic_array1, 0, " ", 0, WHOLE_ARRAY);

   Print("After swapping - dynamic_array2: ");
   ArrayPrint(dynamic_array2, 0, " ", 0, WHOLE_ARRAY);
  }

Объяснение:

// Declare dynamic arrays
   int dynamic_array1[];
   int dynamic_array2[];

// Resize dynamic arrays to have 5 elements each
   ArrayResize(dynamic_array1, 5);
   ArrayResize(dynamic_array2, 5);

  • В этих строках объявлены динамические целочисленные массивы "dynamic_array1" и "dynamic_array2". Размер каждого динамического массива устанавливается равным 5 с помощью функции ArrayResize.

// Assign values to dynamic arrays
   dynamic_array1[0] = 1;
   dynamic_array1[1] = 3;
   dynamic_array1[2] = 5;
   dynamic_array1[3] = 7;
   dynamic_array1[4] = 9;

   dynamic_array2[0] = 11;
   dynamic_array2[1] = 13;
   dynamic_array2[2] = 15;
   dynamic_array2[3] = 17;
   dynamic_array2[4] = 19;

  • Эти строки присваивают каждому элементу в dynamic_array1 и dynamic_array2 определенное значение.
// Print initial dynamic arrays
   Print("Initial dynamic_array1: ");
   ArrayPrint(dynamic_array1, 0, " ", 0, WHOLE_ARRAY);

   Print("Initial dynamic_array2: ");
   ArrayPrint(dynamic_array2, 0, " ", 0, WHOLE_ARRAY);
  • Здесь выводятся в консоль начальные значения dynamic_array1 и dynamic_array2.
// Swap the contents of dynamic_array1 and dynamic_array2
   ArraySwap(dynamic_array1, dynamic_array2);
  • Чтобы заменить все содержимое dynamic_array1 на содержимое из dynamic_array2, используйте функцию ArraySwap().
// Print dynamic arrays after swapping
   Print("After swapping - dynamic_array1: ");
   ArrayPrint(dynamic_array1, 0, " ", 0, WHOLE_ARRAY);

   Print("After swapping - dynamic_array2: ");
   ArrayPrint(dynamic_array2, 0, " ", 0, WHOLE_ARRAY);
  • После процесса замены здесь в консоль выводятся обновленные значения dynamic_array1 и dynamic_array2.
Выводимая информация:

Рисунок 9. Вывод кода в MetaTrader 5



7. ArrayReverse

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

Аналогия

Представьте себе полку, на которой стоят ряды книг, на каждой из которых указан номер. Порядок этих книг можно поменять с помощью функции ArrayReverse(): самая правая книга теперь стала самой левой, и наоборот. Это простой способ изменить порядок книг на полке. С помощью ArrayReverse() можно изменить порядок элементов в списке или массиве. То есть вы разворачиваете массив: последний элемент становится первым, а первый — последним.

Синтаксис:
ArrayReverse(array[], start, count);

Параметры: 

  • array[] — массив, который нужно развернуть.
  • start — индекс внутри массива, с которого начать разворот.
  • count — количество элементов, которые нужно развернуть.

Примеры:
void OnStart()
  {

// Declare and initialize a 10-element array
   int array[10] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};

// Print the original array
   Print("Original Array: ");
   ArrayPrint(array, 0, " ", 0, WHOLE_ARRAY);

// Reverse the array starting from index 4
   ArrayReverse(array, 4, WHOLE_ARRAY);

// Print the array after reversal
   Print("Array after reversal from index 4: ");
   ArrayPrint(array, 0, " ", 0, WHOLE_ARRAY);

  }

Код инициализирует массив указанными элементами, выводит исходный массив, разворачивает его, начиная с индекса 4, а затем выводит результат.


Выводимая информация:

Рисунок 10. Вывод кода в MetaTrader 5



8. ArraySort

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

Аналогия

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

Синтаксис:

ArraySort(array[]); // array[] is the array you want to sort in ascending order

Пример:
void OnStart()
  {

// Declare an array of numbers
   double array[5] = {9.5, 2.1, 7.8, 1.3, 5.6};

// Print the array before sorting
   Print("Array before sorting: ");
   ArrayPrint(array, 1, " ", 0, WHOLE_ARRAY);

// Use ArraySort to arrange the array in ascending order
   ArraySort(array);

// Print the array after sorting
   Print("Array after sorting: ");
   ArrayPrint(array, 1, " ", 0, WHOLE_ARRAY);

  }
Результат:

Рисунок 11. Вывод кода в MetaTrader 5


Заключение

Мы рассмотрели ключевые функции для работы с массивами в MQL5: ArrayPrint, ArrayInsert, ArraySize, ArrayRange, ArrarRemove, ArraySwap, ArrayReverse и ArraySort. Цель этой серии статей — описать основные функции, которые служат основой для автоматизации торговых стратегий. Крайне важно понимать эти функции массива, особенно при работе с историческими данными для создания советников. Эти фундаментальные концепции закладывают основу для освоения программирования на MQL5 и алгоритмической торговли. 

Я призываю всех подходить к каждой идее с терпением и любопытством, поскольку эти основные элементы будут важны в будущих статьях. Обязательно задавайте вопросы в комментариях или обращайтесь ко мне напрямую, если вам нужна помощь или разъяснения по какой-либо части этой статьи. Важно понять все аспекты функций массивов, обсуждавшихся в частях 5 и 6.

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/14407

Последние комментарии | Перейти к обсуждению на форуме трейдеров (2)
Oscar Hayman
Oscar Hayman | 27 мая 2024 в 10:35
Пожалуйста, проверьте пример функции #5 ArrayRemove для `статического массива`. Функция "count" равна 2, а в объяснении вы показываете, что удаляется 3 элемента. Похоже, что это ошибка.
Israel Pelumi Abioye
Israel Pelumi Abioye | 27 мая 2024 в 12:30
Oscar Hayman #:
Пожалуйста, проверьте пример функции #5 ArrayRemove для `статического массива`. Функция "count" равна 2, а в объяснении вы показываете, что удалено 3 элемента. Похоже, здесь ошибка.
Здравствуйте, Оскар, мы рассмотрим этот вопрос. Спасибо.
Разработка MQTT-клиента для MetaTrader 5: методология TDD (финал) Разработка MQTT-клиента для MetaTrader 5: методология TDD (финал)
Статья является последней частью серии, описывающей этапы разработки нативного MQL5-клиента для протокола MQTT 5.0. Хотя библиотека еще не готова к использованию, в этой части мы будем использовать наш клиент для обновления пользовательского символа с помощью тиков (или цен), полученных от другого брокера. В конце статьи вы найдете дополнительную информацию о текущем состоянии библиотеки и узнаете о том, чего не хватает для ее полного соответствия протоколу MQTT 5.0, о возможном плане действий и о том, как следить за развитием библиотеки и вносить в нее свой вклад.
Факторизация матриц: основы Факторизация матриц: основы
Поскольку цель здесь дидактическая, мы будем действовать максимально просто. То есть мы будем реализовывать только то, что нам необходимо: умножение матриц. Вы сегодня увидите, что этого достаточно для симуляции умножения матрицы на скаляр. Самая существенная трудность, с которой многие сталкиваются при реализации кода с использованием матричной факторизации, заключается в следующем: в отличие от скалярной факторизации, где почти во всех случаях порядок факторов не меняет результат, при использовании матриц это не так.
Особенности написания экспертов Особенности написания экспертов
Написание и тестирование экспертов в торговой системе MetaTrader 4.
Нейросети в трейдинге: Иерархический векторный Transformer (HiVT) Нейросети в трейдинге: Иерархический векторный Transformer (HiVT)
Предлагаем познакомиться с методом Иерархический Векторный Transformer (HiVT), который был разработан для быстрого и точного прогнозирования мультимодальных временных рядов.