Введение в программирование на MQL5

Основы терминала MetaTrader5

В терминале MetaTrader5 может работать 4-е типа пользовательских приложений, написанных на языке MQL5:

  • cкрипты;
  • индикаторы;
  • эксперты (другое название – советники);
  • сервисы.

Скрипты

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

Индикаторы

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

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

Следовательно, индикаторы не должны выполнять длительные расчеты. Из- за этой особенности в индикаторах недоступны некоторые возможности языка MQL5, например, создание паузы функцией Sleep(), выполнение интернет запросов функцией WebRequest(), выполнение торговых действий функцией OrderSend() и т.п. Но за то в индикаторах обеспечивается очень быстрый и легкий доступ к данным графика, на котором работает этот индикатор.

Эксперты

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

Сервисы

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

Запуск всех этих приложений выполняется из панели «Навигатор» терминала MetaTrader5 (рис. 1). Эта панель обычно располагается в левой части окна терминала. Если по какой-то причине панель оказалась скрытой, ее отображение выполняется через главное меню терминала: Вид – Навигатор или через сочетание клавиш Ctrl+N.

Панели: Обзор рынка и Навигатор

Рис. 1. Панели: Обзор рынка и Навигатор

Для запуска всех приложений (кроме сервисов) необходим открытый график финансового инструмента (символа). Открытие графиков выполняется через панель «Обзор рынка». Отображение и скрытие панели «Обзор рынка», также как и панели «Навигатор», выполняется через главное меню: Вид – Обзор Рынка или сочетанием клавиш Ctrl+M. Обратите внимание и на другие команды, расположенные во вкладке меню: Инструменты, Тестер стратегий, Окно данных – они обязательно пригодятся в дальнейшем. Справа от каждой команды указано сочетаний клавиш для их выполнения с клавиатуры.

Для открытия графика финансового инструмента, в окне «Обзор рынка» щелкните правой кнопкой мыши на строке соответствующего символ и в открывшемся контекстном меню выберите команду «Окно графика». Внешний вид графиков можно настраивать в очень широких пределах. Если вы новичок в терминале, изучите справку к терминалу, раздел «Графики котировок, технический и фундаментальный анализ», статью «Просмотр и настройка графиков».

Для совсем новичков, будет интересно запустить что-нибудь на графике. Раскройте список индикаторов, для этого в окне «Навигатор» щелкните мышью на значке с крестиком, расположенном слева от надписи «Индикаторы» (также можно сделать двойной щелчок непосредственно на надписи). В раскрывшемся списке, точно таким же способом разверните список «Трендовые» и сделайте двойной щелчок на строке с названием какого-нибудь индикатора, например на строке «Bollinger Bands» (Полосы Боллинджера). При этом откроется окно свойств индикатора (рис. 2). В нижней части окна находится кнопка «OK», при щелчке на ней окно закроется, а на графике появятся три линии индикатора.

Окно свойств индикатора «Bollinger Bands»

Рис. 2. Окно свойств индикатора «Bollinger Bands»

Конечно, маловероятно, что кто-то, читающий данную книгу, еще не умеет запускать индикаторы или другие пользовательские приложения, но если это так, вам надо знать, что терминал MetaTrader5 имеет очень хорошее и подробное справочное руководство. Будет не лишним, если вы уделите некоторое внимание и потратите немного времени на его изучение. Справочное руководство к терминалу можно открыть из главного меню терминала: Справка – Вызов справки или нажать клавишу F1 при активном окне терминала.

Основы редактора MetaEditor

Создание всех пользовательских приложений на языке MQL5 выполняется в специально предназначенном для этого редакторе MetaEditor. Редактор автоматически инсталлируется вместе с терминалом MetaTrader5. То есть для того, чтобы начать программировать на MQL5, не надо искать и инсталлировать никакого дополнительно программное обеспечение. Если у вас инсталлирован терминал, значит, инсталлирован и редактор. Запуск редактора можно выполнить через меню кнопки «Пуск», ярлык для его запуска расположен рядом с ярлыком запуска терминала. Другой способ запуска редактора – через кнопку на панели инструментов терминала. Эта кнопка находится на панели инструментов «Стандартная» (рис. 3).

Панель инструментов «Стандартная» в терминале

Рис. 3. Панель инструментов «Стандартная» в терминале. Кнопка запуска редактора 4-я слева

Видимостью панелей инструментов можно управлять через главное меню: Вид – Панели инструментов. Кроме того, можно управлять и набором кнопок, расположенных на всех панелях инструментов, для этого надо на нужной панели щелкнуть правой кнопкой мыши и выбрать команду «Настроить», после этого откроется окно «Настройка панели инструментов». Окно достаточно простое, и его использование не должно вызвать затруднений (к тому же, чуть позже будет подробно рассмотрено аналогичное окно в редакторе). Еще один способ запуска редактора из терминала – клавиша F4.

В верхней части окна редактора (рис. 4), как обычно в приложениях Windows, находится главное меню с командами «Файл», «Правка» и пр.

Главное окно редактора MetaEditor

Рис. 4. Главное окно редактора MetaEditor

Чуть ниже главного меню расположена панель инструментов с кнопками. В левой части окна расположена панель «Навигатор», через эту панель осуществляется доступ к файлам *.mq5 – к индикаторам, советникам, скриптам и т.п. В правой части расположено рабочее поле, в котором и будет происходить написание кода. В нижней части располагается панель «Инструменты», это очень важная панель, в ней будут выводиться сообщения об ошибках в коде при его компиляции.

Компиляция – это процесс преобразования кода, написанного на языке программирования, понятном человеку, в машинный код – в код исполняемый процессором. В самом низу окна расположена статусная строка с подсказкой в левой части и данными о положении курсора справа (Ln – номер строки, Col – порядковый номер символа в строке). В правом нижнем углу находится индикатор клавиши Insert (режим вставки или перезаписи). Надпись INS означает режим вставки – это обычный режим ввода текста. В этом режиме текст, распложенный правее курсора, сдвигается правее вновь вводимого текста. Если нажать на клавишу Insert, надпись измениться на OVR (Over – сверху), при этом курсор примет форму прямоугольника. В этом режиме новый текст заменяет существующий текст.

Так же как в терминале, в редакторе тоже можно управлять видимостью всех панелей, делается это через главное меню: Вид. Также можно управлять набором кнопок панели инструментов. Что интересно, по умолчанию на панели инструментов отсутствуют кнопки Undo и Redo (отмена и повтор). Наибольший объем работы при программировании выполняется с клавиатуры, поэтому кому-то будет удобнее использовать клавиатурные комбинации (для отмены используются клавиши Ctrl+Z, для повтора Ctrl+Y), к тому же эти команды есть в главном меню: Правка (две верхние строки).

Однако у разных людей стиль работы может отличаться, и кому-то будет удобней использовать кнопки на панели инструментов, включим их. Щелкните правой кнопкой мыши по панели инструментов и выберите команду «Настроить». В открывшемся окне «Настройка панели инструментов» (рис. 5) в списке «Доступные кнопки» найдите кнопку «Отменить», выделите ее и нажмите кнопку «Добавить» (находится в центре окна).

Окно настройки панели инструментов

Рис. 5. Окно настройки панели инструментов

Выполните то же самое для кнопки «Повторить». Затем найдите эти кнопки в списке «Выбранные кнопки» и, пользуясь кнопками «Вверх» и «Вниз» (находятся у правого края окна), переместите их в удобное для себя место. Кнопка «Сброс» приводит панель инструментов в состояние по умолчанию (как при первом запуске редактора).

Из всего обилия кнопок на панели инструментов в первую очередь необходимо знать только три кнопки: Создать, Сохранить, Компилировать. Кнопка «Создать» (первая кнопка слева), при нажатии на кнопку открывается окно «Мастер MQL», в этом окне выполняется выбор типа создаваемого приложения (эксперт, индикатор и т.п.), эта кнопка дублирует команду главного меню: Файл – Создать (клавиатурное сочетание Ctrl+N).

Кнопка «Сохранить», точнее – «Сохранение активного документа» (четвертая кнопка слева), нажатие на кнопку сохраняет в файл активный документ, кнопка дублирует команду главного меню – Файл – Сохранить (клавиатурное сочетание Ctrl+S).

Кнопка – «Компилировать» (большая кнопка в центре панели инструментов с надписью «Компилировать»), нажатие на кнопку выполняет компиляцию файла. Перед компиляцией выполняется проверка синтаксиса кода и вывод сообщений об ошибках, если же ошибок нет, создается файл *.ex5 и он становится доступным в терминале в окне «Навигатор», то есть его можно запускать (прикреплять к графику).

На этом знакомство с редактором закончим и перейдем к более интересной, практической работе. Остальные возможности редактора будут рассматриваться по мере необходимости. Если кому-то интересно сразу более подробно разобраться с редактором, обратитесь к справочному руководству (главное меню редактора – Справка – Вызов справки).

Файловый архив

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

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

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

Первый скрипт

Не будет отходить от традиции, принятой в программировании, начнем с написания скрипта, выводящего текст «Здравствуй Мир!».

В редакторе MetaEditor выполните команду главного меню: Файл – Создать. В открывшемся окне «Мастер MQL» выберите вариант «Скрипт» и нажмите кнопку «Далее» (рис. 6). На втором шаге (рис. 7) достаточно заполнить только поле «Имя».

Все остальное, для чего предназначены другие поля, можно будет сделать непосредственно в файле, и это тоже будет скоро рассмотрено. В поле «Имя» введите «MyFirstScript» и нажмите кнопку «Готово», при этом окно «Мастер MQL» закроется, а в рабочем поле редактора откроется файл скрипта (рис. 4).

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

Окно «Мастер MQL».

Рис. 6. Окно «Мастер MQL». Шаг 1

Окно «Мастер MQL». Шаг 2

Рис. 7. Окно «Мастер MQL». Шаг 2

Комментарий нужен только для удобства программиста, чтобы в дальнейшем ему было легче вспомнить, что он делал, и разобраться с кодом. Еще бывают многострочные комментарии. Такой комментарий начинается с сочетания из двух знаков «/*», и заканчиваются сочетанием из двух знаков «*\».

Чуть ниже можно увидеть несколько строк кода начинающихся с «#property», возможно, пока они вам непонятны, хотя можно заметить их связь с некоторыми полями из окна «Мастер MQL».

Директива «#property» позволяет задавать некоторые специфические свойства программы. Слово, идущее после этой директивы через пробел, определяет имя этого свойства: «copyright» – соответствует полю «Автор» из окна «Мастер MQL», «link» – соответствует полю «Ссылка». После имени свойства стоит пробел, а после него между двойных кавычек располагается текст, как раз тот самый текст, который вы видели в окне «Мастер MQL». Теперь это текст можно произвольно изменить, но пока вы его не сможете нигде увидеть, кроме как в самом файле.

Следующее свойство «version» – версия. Это свойство необходимо только продавцам маркета на сайте mql5. com. При публикации на маркете новой версии своего приложения, имя файла нужно оставить без изменений, а изменить только номер версии.

Наконец подошли к самому интересному. В нижней части файла можно увидеть такой код:

void OnStart()
{
//---
}

Это функция OnStart(), она выполняется при запуске скрипта, в ней мы и будем писать свой код. Здесь еще может возникнуть большое количество вопросов, но пока не будем отвлекаться, сейчас главное для нас то, что свой код мы должны писать между двух фигурных скобок, там, где сейчас стоит однострочный комментарий «//—», его даже можно удалить.

Нашей задачей сейчас является вывод текста «Здравствуй Мир!». Есть несколько способов вывода текста. Можно сделать вывод непосредственно на график, в левый верхний угол, для этого используется функция Comment(). Можно сделать вывод в окно «Инструменты» во вкладку «Эксперты», для этого используется функция Print(). Можно сделать вывод в специальное окно для сообщений, для этого используется функция Alert().

Интересней всего функция Alert(), при ее вызове открывается отдельное окно и при этом играет звук. В функцию старт добавляем следующий код:

Alert(“Здравствуй Мир!”);

В итоге функция OnStart() должна иметь такой вид:

void OnStart(){ Alert(“Здравствуй Мир!”);
}

Все готово для проверки своей первой работы. Жмем кнопку «Компилировать» и смотрим сообщения в панели «Инструменты» во вкладке «Ошибки». Если компиляция прошла успешно, будет сообщение: «0 errors, 0 warnings…» (рис. 8).

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

Сообщение об успешной компиляции

Рис. 8. Сообщение об успешной компиляции

Кроме того, можно умудриться написать код не между фигурных скобок, а перед открывающей фигурной скобкой, или между круглых скобок после «OnStart». Все даже не перечислить. Если в коде есть ошибка, то при компиляции будет выведено сообщение заметным красным цветом с указание количества ошибок, например: «2 errors, 0 warnings» (рис. 9). А в строке перед сообщением о количестве ошибок будет выведена подсказка о типах ошибок, иногда подсказки очень ценны, иногда не очень.

Сообщение об ошибках компиляции

Рис. 9. Сообщение об ошибках компиляции

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

Значит, если компиляция прошла успешно, получившийся скрипт можно проверить в терминале. Открываем терминал, в навигаторе раскрываем список «Скрипты» и находим строку «MyFirstScript» (рис. 10).

Скрипт «MyFirstScript» в навигаторе терминала

Рис. 10. Скрипт «MyFirstScript» в навигаторе терминала

Щелкаем по имени скрипта левой кнопкой мыши (в терминале должен быть открыть хотя бы один график), в результате должно открыться окно с сообщением (рис. 11).

Также попробуйте запустить скрипт путем перетаскивания – прижать левую кнопку мыши на строке с именем скрипта, перетащить указатель на график и отпустить мышь.

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

Результат работы скрипта «MyFirstScript»

Рис. 11. Результат работы скрипта «MyFirstScript»

В терминале или редакторе выполните команду главного меню: Файл – Открыть каталог данных (или нажмите сочетание клавиш Ctrl+Shift+D), в открывшейся папке зайдите в папку MQL5, затем в папку Scripts, создайте в ней папку «MyFirstScript» и переместите в нее два файла:

«MyFirstScript.mq5» и «MyFirstScript.ex5». После этого в терминале, в панели «Навигатор» щелкните правой кнопкой мыши и выполните команду «Обновить». Теперь, чтобы запустить скрипт «MyFirstScript», сначала надо развернуть папку «MyFirstScript». Также надо выполнить команду обновления в навигаторе редактора.

В редакторе сохраните копию файла «MyFirstScript.mq5» с именем «MyFirstScriptPrint», для этого выполните команду главного меню: Файл – Сохранить как, при сохранении убедитесь, что сохранение выполняется в папку «Scripts/ MyFirstScript». В файле замените вызов функции Alert(), на вызов функции Print(), выполните компиляцию. Теперь функция OnStart() должна выглядеть следующим образом:

void OnStart(){ Print(“Здравствуй Мир!”);
}

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

«Инструменты», во вкладке «Эксперты» должна появиться строка с текстом (рис. 12).

Вывод сообщения функцией Print()

Рис. 12. Вывод сообщения функцией Print()

Сделайте копию скрипта с именем «MyFirstScriptComment» и замените функцию Print() на функцию Comment(). Функция OnStart()должна выглядеть так:

void OnStart(){ Comment(“Здравствуй Мир!”);
}

Теперь скрипт делает вывод текста в левый верхний угол графика (Рис. 13).

Рис. 13. Вывод сообщения функцией Comment()

Cкрипт с параметрами

Пока что все создаваемые нами скрипты исполнялись сразу при их запуске. Иногда, прежде чем скрипт начнет свою работу, надо указать ему некоторые параметры. Например, скрипт выполняет удаление отложенных ордеров, будет неплохо, если пользователь сможет выбирать тип удаляемых ордеров, например: BuyStop, SellStop, BuyLimit, SellLimit. Но пока сделаем кое-что попроще – усовершенствуем наш первый скрипт так, чтобы при его запуске открывалось окно свойств с одной строковой переменной, в которую надо будет ввести свое имя. В итоге скрипт будет выполнять приветствие, обращаясь к вам по имени.

Чтобы у скрипта появилось окно свойств, ему нужно добавить свойство script_show_inputs. Откройте в редакторе скрипт «MyFirstScript». Для открытия файла удобно воспользоваться панелью «Навигатор» редактора, собственно для этого она и предназначена – для удобного и быстрого доступа к файлам *.mq5. Сохраните файл с именем «MyFirstScriptInput».

После всех строк со свойствами добавьте еще одну:

#property script_show_inputs

Точно такая строка добавляется в скрипт, если при его создании в окне «Мастер MQL» добавить переменную в таблицу «Параметры» (рис. 7). Чтобы не ошибиться при ручном вводе столь длинного свойства, будет проще скопировать его со справочного руководства. За одно, познакомимся с удивительными возможностями справочного руководства по языку MQL5. В редакторе установите курсор в любое место внутри слова «property» и нажмите клавишу F1, в результате откроется справочное руководство с описанием директивы «property», оказывается, существует очень много различных свойств. Найдите свойство «script_show_inputs», выделите его мышкой и скопируйте через контекстное меню (правая кнопка мыши) или сочетанием клавиш Ctrl+C.

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

Чуть ниже последней строки со свойством добавляем строку для объявления переменной:

input string name=””;

Первое слово – модификатор «input» указывает, что это не просто переменная в скрипте, а внешняя, то есть доступная через окно свойств. Второй слово «string» определяет тип переменной – текстовый (строковый). Слово «name» – это имя переменной, через которое будем обращаться к ее содержимому (значению). Знак «=» означает, что при объявлении выполняется инициализация переменной, то есть присвоение ей некоторого значения, в данном случае пустой строки ””.

Теперь в окне свойств появится вкладка «Входные параметры» с переменной «name».

Сформируем текст сообщения с ее использованием. Соединение строк выполняется оператором

«+». В функции OnStart() получается такой код:

Alert("Здравствуй, "+name+"!");

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

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property version "1.00" #property script_show_inputs
input string name=""; void OnStart(){
Alert("Здравствуй, "+name+"!");
}

Выполняем компиляцию и проверяем скрипт в терминале. На запуске скрипта видим окно свойств с двумя вкладками: «Общие» и «Входные параметры». Если переключиться на вкладку «Общие» (рис. 14), то, наконец, можно увидеть, где применяются свойства «copyright» и «link» – из них сформирована ссылка (в верхней части вкладки), там же используется и свойство «version».

Окно свойств скрипта

Рис. 14. Окно свойств скрипта, вкладка «Общие»

Обратите внимание на изображение в левом верхнем углу вкладки «Общие», его можно изменить через свойство «icon». Если интересно, самостоятельно ознакомьтесь с этим свойством в руководстве по языку, в основном в этой книге планируется углубляться исключительно в прагматичные аспекты языка MQL5.

Обратите внимание на два чекбокса в нижней части вкладки, особенно на нижний – «Разрешить автоматическую торговлю». Если скрипт должен выполнять торговые действия (открытие и закрытие позиций, установку и удаление ордеров, модификацию позиций и ордеров), то эта галка должна быть установлена. Чтобы она была установлена по умолчанию,необходимо сделать соответствующие настройки в терминале: Главное меню – Сервис – Настройки (или Ctrl+O), затем, во вкладке «Советники» установить галку «Разрешить автоматическую торговлю». За более подробной информацией обратитесь к справке терминала: Алгоритмический трейдинг, торговые роботы – Торговые советники и собственные индикаторы.

При запуске скрипта во вкладке «Входные параметры» можно увидеть созданный ранее параметр «name» (рис. 15).

Окно свойств скрипта

Рис. 15. Окно свойств скрипта, вкладка «Параметры»

Щелкните по полю в колонке «Значение» и введлите своем имя, (пусть будет «Вася»), и нажмите кнопку «OK». В результате работы скрипта откроется окно (рис. 16).

Результат работы скрипта «MyFirstScriptInput»

Рис. 16. Результат работы скрипта «MyFirstScriptInput»

При работе над этим скриптом мы познакомились с очень полезной возможностью редактора – контекстной справкой (когда устанавливали курсор на слово «property» и использовали клавишу F1). Если какое-то слово в коде выделено цветом, то, скорее всего, в справочном руководстве будет отдельная статья, посвященная ему. Откройте в редакторе все скрипты, которые создали ранее, обратите внимание, какие слова выделены цветом и почитайте справку по ним. Если что-то будет не понятно, не беспокойтесь, вы пока находитесь только в начале книги, со временем все будет рассмотрено более подробно.

Cкрипт с проверкой

Если запустить скрипт «MyFirstScriptInput», можно нажать кнопку «OK» не вводя имя в окне свойств, при этом скрипт выдаст приветствие «Здравствуй, !» – вовсе не тот результат, который был запланирован. Поэтому надо или как-то обязать пользователя ввести имя, или не выполнять скрипт, если имя не введено. В данном случае нет возможности как-то обязать пользователя к вводу данных, поэтому сделаем только проверку. Если имя не введено, скрипт выдаст сообщение «Вы не ввели имя!» и отсоединится от графика.

Сохраните копию скрипта «MyFirstScriptInput» с именем «MyFirstScriptInput2». Первая мысль – сделать проверку на неравенство переменной name пустой строке “”. Однако пользователь может ввести пробел, такая строка не будет считаться пустой, но и требуемый результат работы скрипта не будет достигнут. Значит, сначала надо обрезать пробелы по краям переменной name, но здесь сталкиваемся с другой проблемой – мы не имеем возможности присваивать какие-либо значения внешним переменным. Необходимо объявить еще одну переменную, присвоить ей значение из переменной name и все последующие действия выполнять с ней.

После строки с внешней переменной добавьте объявление еще одной переменной, но без модификатора input и без инициализации:

string _name;

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

В самое начало функции OnStart() добавьте присвоение переменной _name значение переменной

name:
_name=name;

В строке ниже замените переменную name на _name:

Alert("Здравствуй, "+_name+"!");

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

Теперь надо обработать переменную _name – обрезать пробелы. Для этого существуют функции StringTrimLeft() и StringTrimRight(), по их названиям понятно (зная немного английский), что первая обрезает пробелы слева, а вторая – справа. Если вы знакомы с какими-нибудь языками программирования высокого уровня, то, возможно, ожидаете, что надо написать что-то такое:

_name=StringTrimLeft(_name); // это неправильный код

Но нет! Здесь функции StringTrimLeft() и StringTrimRight() возвращают не обработанные строки, а количество отрезанных символов, тем не менее, после вызова функции, в переменной _name окажется обработанная переменная. Дело в том, что здесь используется так называемая передача параметра по ссылке – переменная _name передается в функцию как параметр, обрабатывается в функции, и все сделанные в ней изменения отражаются на этой переменной. В дальнейшем об этом будет более подробно, пока же, если не понятно, просто повторите пример. Значит, перед вызовом функции Alert() добавляем две строки:

StringTrimLeft(_name); StringTrimRight(_name);

После этих строк выполним проверку переменной _name. Для этого используем условный оператор if («if» в переводе с английского означает «если»). После оператора if в круглых скобках записывается логическое выражение, если оно истинно, то выполняется код, который располагается в следующей строке или в составной операторе. Составной оператор, это несколько строк когда, окруженных фигурными скобками. Если выражение ложно, то следующая строка или составной оператор пропускается. Значит, если переменная _name будет равна “”, то откроем окно с сообщением «Вы не ввели имя!» и завершим работу функции OnStart(). Для проверки двух значений на равенство используется два знака равно «==», один знак «=» – это знак присвоения.

Для завершения работы функции используется оператор return. Ниже приведен весь код скрипта «MyFirstScriptInput2»:

#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property version "1.00" #property script_show_inputs
input string name=""; string _name;
void OnStart()
{
_name=name; StringTrimLeft(_name); StringTrimRight(_name);
if(_name==""){
Alert("Вы не ввели имя!"); return;
}
Alert("Здравствуй, "+_name+"!");
}

Выполните компиляцию и проверьте работу скрипта в терминале. Один раз попробуйте не вводить имя, в этом случай должно открыть окно с сообщением «Вы не ввели имя!». При вводе имении скрипт сработает как же, как и скрипт «MyFirstScriptInput» (рис. 16). Конечно, пользователь сможет легко обмануть такую проверку, достаточно вместо настоящего имени ввести набор каких-нибудь знаков, например, решетку, восклицательный знак и т.п. Надо понимать, что данная проверка сделана не для защиты от сознательных злоумышленников, а для удобства разумному пользователю, чтобы предотвратить грубые ошибки ввода данных, которые могут совершаться от невнимательности, и, конечно же, для приобретения вами первых навыков в программировании.

Поиск ошибок

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

Поэкспериментируем со скриптом «MyFirstScriptInput2». Сделайте его копию с именем

«MyFirstScriptInput3», все эксперименты будем производить в нем. Сделаем в коде несколько ошибок:

1. В строку «_name=name;» добавьте еще один знак равенства:

_name==name;

2. В строке «StringTrimLeft(_name);» удалите передачу параметра:

StringTrimLeft();

3. В строке «if(_name==»»){» замените двойной знак равенства на одинарный.

if(_name=""){

В итоге в функция OnStart() должна выглядеть следующим образом:

void OnStart(){
_name==name; StringTrimLeft(); StringTrimRight(_name); if(_name=""){
Alert("Вы не ввели имя!"); return;
}
Alert("Здравствуй, "+_name+"!");
}

Теперь при компиляции получаем сообщение о двух ошибках – errors и одном предупреждении – warnings (рис. 17).

Ошибка – это нерешаемая компилятором проблема, он сообщает, что не может выполнить компиляцию, потому что не «понимает», что надо делать. Предупреждение же говорит о том, что компилятор не совсем «понимает», зачем так сделано. Компиляция выполняется, но программа может работать не совсем так, как ожидает программист.

Предупреждением «expression has no effect» переводится с английского как «выражение не имеет эффекта». К сожалению, компилятор может давать такие сообщения только на английском языке, поэтому, если ваши знания английского пока не достаточны для их понимания, воспользуйтесь электронным переводчиком, например translate.google.ru или translate.yandex.ru – они отлично справляются со столь простыми фразами.

Щелкните на строке с предупреждением – курсор встанет как раз перед первыми знаками «==». Использование двух знаков равенства превратило присвоение значения переменной в логическое выражение, но его результат не используется, то есть для программы, что есть эта строка кода, что нет ее, поэтому и такое сообщение об отсутствии эффекта. Для устранений этого предупреждения остается только нажать клавишу «Delete» и удалить лишний знак «=».

Сообщение об ошибках и предупреждениях

Рис. 17. Сообщение об ошибках и предупреждениях

Следующее сообщение об ошибке «’StringTrimLeft’ – wrong parameters count» означает, что функции StringTrimLeft() передано неправильное количество параметров. Щелкните на сообщении, и курсор окажется в начале строки – теперь не так точно, но достаточно, чтобы найти ошибку.

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

Подсказка по параметрам функции

Рис. 18. Подсказка по параметрам функции

Исправьте ошибку – введите между круглых скобок имя переменной _name.

Третье сообщение «cannot implicitly convert type ‘string’ to ‘bool’» означает, что компилятор не может конвертировать строковый тип (стринг) в логический тип (bool). Пока может быть не совсем понятно, причем тут эта конвертация, ведь нам нужно не присвоение, а логическое выражение.

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

Щелкните на третьем сообщении, и курсор снова встанет точно на место с ошибкой, теперь достаточно нажать клавишу «=» и ошибка будет исправлена. Выполните компиляцию, чтобы убедиться, что вы исправили все ошибки.

Познакомимся с более сложной ошибкой. Сделайте копию скрипта «MyFirstScriptInput2» с именем скриптом «MyFirstScriptInput4». В строке «if(_name==»»){» удалите фигурную скобку:

if(_name=="")

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

Четыре сообщения при одной ошибке

Рис. 19. Четыре сообщения при одной ошибке

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

На рис. 19 показано 4 сообщения об ошибках, но на практике их может быть гораздо больше, в этом случае строка с сообщением о количестве ошибок и предупреждений может сдвинуться вниз, за пределы панели, это может кому-то показаться неудобным. Действительно, лучше сначала увидеть сообщение о наличие ошибок, а потом уже разбираться с каждой из них. Щелкните правой кнопкой на вкладке «Ошибки» и выберите пункт «Автопрокрутка», теперь, после компиляции, список с ошибками будет сразу автоматически прокручивать вниз, и строка с количеством ошибок и предупреждений будет видна.