Список значений в одном входном параметре

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

input string Lots = "0.01, 0.02, 0.04, 0.07, 0.1"; // Последовательность лотов
Настройка для установки последовательности размера лотов

Мы задаем входной параметр Lots, в котором и будет указываться список значений. Параметр Lots имеет тип string - строка, в которой по сути можно написать что угодно. Поэтому нужно заранее предупреждать пользователей вашей mql программы для Metatrader, о том как правильно указывать значения в этом параметре.

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

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

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

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

double lots_array[];
Динамический массив для хранения размеров лотов

Далее создадим функцию, которая будет конвертировать список лотов из строки параметра Lots, в массив lots_array.

//+------------------------------------------------------------------+
//| Устанавливает последовательность лотов в массив lots_array       |
//+------------------------------------------------------------------+
bool InitLots(void)
  {
   // Очищаем массив лотов от предыдущих значений
   ArrayFree(lots_array);
//---
   // Получаем символьный код разделителя
   ushort u_sep = StringGetCharacter(",", 0);
   
   // Создаем массив для хранения строк, 
   // полученных после разделения исходной строки Lots             
   string result[];
   
   // Разделяем строку Lots на отдельные строки
   int k = StringSplit(Lots, u_sep, result);
   
   // Получаем размер массива с результатами разделения строки Lots
   int total = ArraySize(result);
   
   // Делаем проверку на количество полученных строк после разделения строки Lots
   if(total == 0)
     {
      // Если значения в Lots не были указаны, либо использовался другой разделитель,
      // то сообщим об этом пользователю и прервем инициализацию программы.
      Alert("Необходимо указать хотя бы один лот");
      return false;
     }
   
   // Перебираем все строки, получившиеся после разделения  
   for(int i=0; i<total; i++)
     {
      // Сохраняем строку из массива во временную переменную
      string s_tmp = result[i];

      // Очищаем строку от пробелов 
      #ifdef __MQL4__ 
         s_tmp = StringTrimLeft(s_tmp);
         s_tmp = StringTrimRight(s_tmp);
      #endif
      
      #ifdef __MQL5__
         StringTrimLeft(s_tmp);
         StringTrimRight(s_tmp);
      #endif
     
      // Преобразуем строку в число типа double
      double lot = StringToDouble(s_tmp);
      
      // Добавляем готовый к использованию лот в массив лотов
      ArrayAdd(lots_array, lot); // кастомная функция, код в статье не приводится
     }
//--- 
   return true; 
  }
Функция InitLots

Первое, что мы делаем - это разделяем строку Lots на подстроки, которые сохраняются в массив result. Строка Lots имеет такое значение: "0.01, 0.02, 0.04, 0.07, 0.1", после её разделения по символу разделителю - запятой в данном случае, содержимое массива result будет выглядеть так: ["0.01", " 0.02", " 0.04", " 0.07", " 0.1"].

Так как это всё еще строки, то пробелы также сохранились.

Затем мы проходимся в цикле по всем строкам массива result, очищаем каждую строку от пробелов слева и справа, преобразуем строку в число double и добавляем его в массив lots_array.

Обратите внимание, что встроенные в язык программирования mql функции StringTrimLeft и StringTrimRight, работают по разному в mql4 и в mql5. В mql4 они принимают строку, очищают и возвращают её. Тогда как в mql5 они принимают строку по ссылке и очищают её, но не возвращают, а просто преобразуют.

Знаете ли вы, что: директивы #ifdef __MQL4__ ... #endif и #ifdef __MQL5__ ... #endif используются, чтобы разделить код mql4 и mql5 в одной программе. Выше мы создали функцию InitLots, которая может работать как в МТ4, так и в МТ5, но при этом она содержит код зависимый от версии торгового терминала и от версии языка программирования mql.

Так, при компилировании программы для МТ4, код написанный внутри #ifdef __MQL5__ ... #endif будет просто пропущен компилятором и исключен из программы. Также и наоборот: код внутри #ifdef __MQL4__ ... #endif будет удален для программы работающей в Metatrader 5 версии.

Функция InitLots готова, как мы будем её использовать? Чтобы иметь всегда актуальный список лотов, мы вызываем функцию InitLots в функции OnInit форекс робота или индикатора. Благодаря этому, при каждом изменении входных параметров программы, мы будем иметь актуальный список лотов.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!InitLots())
      return INIT_FAILED;
//---
  }
Создание списка лотов во время инициализации входных параметров mql программы

А если пользователь неправильно укажет размеры лотов, то функция InitLots вернет false и инициализация советника прервется, что защитит от ошибок работы программы в дальнейшем.

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

//+------------------------------------------------------------------+
//| Открывает сделку после закрытия предыдущих сделок в убыток       |
//+------------------------------------------------------------------+
void OpenAfterLoss(void)
  {
   // Получаем количество предыдущих сделок, закрытых подряд в убыток
   int num_loss = NumLossDeals(); // Вымышленная функция, приведена для примера
   
   // Получаем размер массива с лотами
   int lots_total = ArraySize(lots_array);
   
   // Если размер массива с лотами меньше, чем количество убыточных сделок,
   // то берем последнее значение лота из массива, 
   // иначе произойдет ошибка и программа прекратит работу.
   int lot_index = MathMin(lots_total-1, num_loss);
   
   // Получаем размер лота из списка
   double lot = lots_array[lot_index];
   
   // Открываем сделку с полученным лотом
   OpenBuy(lot, ...);  // Вымышленная функция, приведена для примера
  }
Пример получения нужного лота из массива lots_array

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

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

Комментарии

Комментариев пока нет. Будьте первым!

Добавить комментарий

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