Ввод данных

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

Вместе с тем, описание входного параметра имеет несколько существенных отличий:

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

Как правило, входные параметры рекомендуется располагать в начале исходного кода.

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

input int GreetingHour = 0;

Такая запись означает, несколько вещей.

  • Во-первых, в скрипте появилась переменная GreetingHour, доступная из любого места исходного кода, в том числе внутри любой функции. Подобное определение называют определением на глобальном уровне, причем оно становится таковым благодаря выполнению пункта 1 из вышеприведенного списка.
  • Во-вторых, использование ключевого слова input делает такую переменную видимой не только внутри программы, но и в пользовательском интерфейсе, в диалоге настройки свойств MQL-программы, который открывается при её запуске. Таким образом, при старте программы пользователь задает необходимое значение параметров (в нашем случае, один параметр GreetingHour), и они становятся значениями соответствующих переменных во время выполнения программы.

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

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

К сожалению, для скриптов (как для отдельного типа MQL-программ) описание входного параметра еще не гарантирует вызов диалога настроек при запуске скрипта. Чтобы это произошло, необходимо добавить в код еще одну директиву #property, специфическую для скриптов:

#property script_show_inputs

Как мы увидим далее, для других типов MQL-программ эта директива не нужна.

Входной параметр GreetingHour требовался нам для передачи его значения в функцию Greeting. Для этого достаточно вставить его в вызов функции Greeting, вместо 0:

void OnStart()
{
  Print(Greeting(GreetingHour), ", "Symbol());
}

С учетом изменений, которые мы внесли для описания входного параметра, сохраним новую версию скрипта в файл GoodTime1.mq5. Если его откомпилировать и запустить, мы увидим диалог ввода данных:

Диалог ввода параметров скрипта GoodTime1.mq5

Диалог ввода параметров скрипта GoodTime1.mq5

Например, если мы отредактируем значение GreetingHour, сделав его 10, то скрипт выдаст следующее приветствие:

GoodTime1 (EURUSD,H1)        Good day, EURUSD

Это правильный, ожидаемый результат.

Ради интереса запустим скрипт еще раз и введем теперь значение 100. Вместо какого-либо вразумительного ответа мы получим:

GoodTime1 (EURUSD,H1)        array out of range in 'GoodTime1.mq5' (19,18)

Мы столкнулись с новым для себя явлением — ошибкой времени исполнения. В данном случае терминал сообщает, что в строке 19, в позиции 18 наш скрипт попытался прочитать значение элемента массива с несуществующим индексом (за пределами размера массива).

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