Русский

Учебник по MQL4  Программа на MQL4  Структура программы

Структура программы


Ранее мы ознакомились с основными понятиями, на которых базируется язык программирования MQL4. Теперь необходимо рассмотреть, как устроена программа в целом. Изучая этот вопрос, мы рассмотрим её структурную схему.

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

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

Правило программирования на языке MQL4 состоит в следующем:

Код программы должен быть расположен внутри функций.

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


Рассмотрим функциональную схему обычной прикладной программы-эксперта:


Рис. 31. Функциональная схема программы (эксперта).


Наиболее крупными функциональными блоками составленной на MQL4 программы являются:

1. Головная часть программы.

2. Специальная функция init().

3. Специальная функция start().

4. Специальная функция deinit().

5. Пользовательские функции.

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

Информационная среда клиентского терминала МТ4


Информационная среда клиентского терминала МТ4 не является составной частью программы. Информационная среда - это набор параметров, доступных для обработки программой. Например, это - пришедшая с новым тиком цена финансового инструмента, накапливающийся с каждым новым тиком объём, сведения о максимальных и минимальных ценах исторических баров, параметры, характеризующие предлагаемые дилинговым центром условия торговли и т.д. Информационная среда постоянно сохраняется и с каждым новым тиком обновляется клиентским терминалом, поддерживающим постоянную связь с сервером.

Структура программы


Головная часть


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

Специальные функции


Обычно после головной части следует описание специальных функций. Внешне описание специальной функции выглядят так же, как и описание обычной пользовательской функции, с той разницей, что специальные функции имеют предопределённые имена - init(), start() и deinit(). Специальные функции представляют собой собственно блок вычислений и находятся во взаимоотношениях с информационной средой клиентского терминала и пользовательскими функциями. Специальные функции подробно рассматриваются в разделе Специальные функции.

Пользовательские функции


Описания пользовательских функций обычно располагаются непосредственно после описания специальных функций. Количество пользовательских функций в программе не ограничено. На схеме представлены всего две пользовательские функции, в то время как в программе их может быть 10 или 500, или ни одной. Если в программе не применяются пользовательские функции, значит, программа будет иметь упрощённый вид: головную часть и описания специальных функций.

Стандартные функции


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

Порядок расположения в программе


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


Рис. 32. Обычный порядок расположения функциональных блоков в программе (рекомендуется).


Рис. 33. Возможные варианты расположения функциональных блоков в программе (произвольный порядок).

Особо нужно отметить:

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

Ниже представлены примеры неправильно расположенного описания функции.


Рис. 34. Примеры неправильного расположения описаний функций в программе.

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


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


Головная часть и специальные функции


С момента, когда программа запущена на исполнение в окне финансового инструмента, исполняются строки головной части программы.

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

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

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

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

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

Исполняющиеся специальные функции могут обращаться к информационному окружению (тонкие синие стрелки на схеме) и вызывать для исполнения пользовательские функции (тонкие жёлтые стрелки). Обратите внимание на то, что специальные функции выполняются в результате их вызова клиентским терминалом в порядке, предопределённом в свойствах этих функций: сначала init(), потом (многократно) start() и потом deinit(). Условия, при которых клиентский терминал вызывает специальные функции, описаны в разделе Специальные функции.

Пользовательские функции


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

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

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

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