Русский

Справочник MQL4 Программы MQL4 Выполнение программ

Выполнение программ

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

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

Краткая сводка по программам на MQL4 приведена в таблице:

Программа

Выполнение

Примечание

Скрипт

В собственном потоке, сколько скриптов - столько потоков выполнения для них

Зацикленный скрипт не может нарушить работу других программ

Эксперт

В собственном потоке, сколько экспертов - столько потоков выполнения для них

Зацикленный эксперт не может нарушить работу других программ

Индикатор

В одном интерфейсном потоке терминала

Бесконечный цикл в одном индикаторе остановит работу терминала

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

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

Тип

Имя функции

Параметры

Применение

Примечание

int

OnInit

нет

эксперты, индикаторы и скрипты

Обработчик события Init. Допускается тип возвращаемого значения void.

void

OnDeinit

const int reason

эксперты, индикаторы и скрипты

Обработчик события Deinit.

void

OnStart

нет

скрипты

Обработчик события Start.

int

OnCalculate

const int rates_total,

const int prev_calculated,

const datetime &Time[],

const double &Open[],

const double &High[],

const double &Low[],

const double &Close[],

const long &TickVolume[],

const long &Volume[],

const int &Spread[]

индикаторы

Обработчик события Calculate на всех ценовых данных.

void

OnTick

нет

эксперты

Обработчик события NewTick. Пока идет обработка события прихода нового тика другие события этого типа не приходят.

void

OnTimer

нет

эксперты и индикаторы

Обработчик события Timer.

double

OnTester

нет

эксперты

Обработчики события Tester

void

OnChartEvent

const int id,

const long &lparam,

const double &dparam,

const string &sparam

эксперты и индикаторы

Обработчик события ChartEvent.

Клиентский терминал отсылает возникающие события в соответствующие открытые графики. Также события могут генерироваться графиками (события графика) либо mql4-программами (пользовательские события).  Генерацию событий создания и удаления графических объектов на графике можно включать и отключать заданием свойств графика CHART_EVENT_OBJECT_CREATE и CHART_EVENT_OBJECT_DELETE. Каждая mql4-программа и каждый график имеют свою собственную очередь событий, куда складываются все вновь поступающие события.

Программа получает события только от графика, на котором она запущена. Все события обрабатываются одно за другим в порядке поступления. Если в очереди уже есть событие NewTick либо это событие находится в состоянии обработки, то новое событие NewTick в очередь mql4-программы не ставится. Аналогично, если в очереди mql4-программы уже находится событие ChartEvent или такое событие обрабатывается, то новое событие такого типа не ставится в очередь. Обработка событий таймера производится по такой же схеме – если в очереди находится или уже обрабатывается событие Timer, то новое событие таймера не ставится в очередь.

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

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

Библиотеки не обрабатывают никаких событий.

 

Запрет на использование функций в индикаторах и экспертах

Индикаторы, скрипты и эксперты являются исполняемыми программами на MQL4 и предназначены для различных типов задач. Поэтому существует ограничение на использование определенных функций в зависимости от типа программы. В индикаторах запрещены следующие функции:

 

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

Библиотека не является самостоятельной программой и выполняется в контексте вызвавшей её MQL4-программы: скрипт, индикатор или эксперт. Соответственно, на вызванную библиотеку распространяются указанные выше ограничения.

 

Загрузка и выгрузка индикаторов

Индикаторы загружаются в следующих случаях:

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

Индикаторы выгружаются в следующих случаях:

  • при откреплении индикатора от графика;
  • закрытие терминала (если индикатор был прикреплен к графику);
  • загрузка шаблона, если к графику прикреплен индикатор;
  • закрытие графика, к которому был прикреплен индикатор;
  • смена профиля, если индикатор прикреплен к одному из графиков сменяемого профиля;
  • смена символа и/или периода графика, к которому прикреплен индикатор;
  • изменение входных параметров индикатора.

 

Загрузка и выгрузка экспертов

Загрузка эксперта производится в следующих случаях:

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

Выгрузка эксперта, прикрепленного к графику, производится в следующих случаях:

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

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

Для лучшего понимания работы эксперта рекомендуется скомпилировать код приведенного в примере эксперта и произвести действия по загрузке/выгрузке экспертов, смене шаблона, символа, таймфрейма и так далее:

Пример:

//+------------------------------------------------------------------+
//|                                                   TestExpert.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
class CTestClass
  {
public:  
   CTestClass() { Print("CTestClass constructor"); }
   ~CTestClass() { Print("CTestClass destructor"); }
  };
CTestClass global;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   Print("Initialization");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   Print("Deinitialization with reason ",reason);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
 
  }

 

Загрузка и выгрузка скриптов

Скрипты загружаются сразу после прикрепления к графику и выгружаются сразу после окончания своей работы.

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

Скрипты загружаются сразу после прикрепления к графику и выгружаются сразу после окончания своей работы.

//+------------------------------------------------------------------+
//|                                                   TestScript.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
class CTestClass
  {
public:  
   CTestClass() { Print("CTestClass constructor"); }
   ~CTestClass() { Print("CTestClass destructor"); }
  };
CTestClass global;
//+------------------------------------------------------------------+
//| Script program initialization function                           |
//+------------------------------------------------------------------+
void OnInit()
  {
   Print(__FUNCTION__);
  }
//+------------------------------------------------------------------+
//| Script program deinitialization function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Print(__FUNCTION__," reason=",reason);
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   Print(__FUNCTION__);
  }

Входные параметры и компиляция исходного кода программ

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

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

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

  • изменилось количество параметров;
  • изменился порядок следования параметров;
  • изменились наименования параметров;
  • изменился тип одного или более параметров.

Изменение значения по умолчанию любого из параметров не считается изменением состава входных параметров.

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

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

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

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

Смотри также

События клиентского терминала, Функции обработки событий