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

Для того чтобы программа, написанная на языке программирования MQL5 могла работать, она должна быть скомпилирована (кнопка «Компилировать» или клавиша F7). Процесс компиляции должна пройти без ошибок (предупреждения(warnings) допускаются, однако их необходимо анализировать). При этом в соответствующей директории terminal_dir\MQL5\Experts, terminal_dir\MQL5\indicators или terminal_dir\MQL5\scripts будет создан выполняемый файл с тем же именем и расширением EX5. Именно этот файл может и будет выполнен.

Особенности работы mql5-программ по разделам:

  • Запуск программ – порядок вызова предопределенных функций-обработчиков событий;
  • Тестирование торговых стратегий – особенности работы программ в тестере стратегий;
  • События клиентского терминала – описание событий, которые можно обрабатывать в программах;
  • Вызов импортируемых функций – порядок описания, допустимые параметры, порядок поиска и соглашения о связях импортируемых функций;
  • Ошибки выполнения – получение информации об ошибках выполнения и критические ошибки.

Эксперты, пользовательские индикаторы и скрипты прикрепляются к одному из открытых графиков путем перетаскивания мышью из окна «Навигатор» клиентского терминала на соответствующий график (технология Drag’n’Drop). mql5-программы могут работать только при включенном клиентском терминале.

Для того чтобы эксперт прекратил свою работу, его необходимо удалить с графика. Для этого из контекстного меню графика следует выбрать «Список экспертов», далее выбрать сответник из списка и нажать кнопку «Удалить». На работу советника также влияет состояние кнопки «Авто-торговля».

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

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

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

На одном графике могут работать максимум по одному эксперту и скрипту и неограниченное количество индикаторов.

 

Запуск программ

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

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

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

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

Программа

Выполнение

Примечание

Скрипт

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

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

Эксперт

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

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

Индикатор

Один поток выполнения для всех индикаторов на одном символе. Сколько символов с индикаторами — столько потоков выполнения для них

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

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

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

Тип

Имя функции

Параметры

Применение

Примечание

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 на всех ценовых данных.

int

OnCalculate

const int rates_total,

const int prev_calculated,

const int begin,

const double &price[]

индикаторы

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

В индикаторе не может одновременно присутствовать 2 обработчика Calculate. В этом случае будет работать только обработчик события Calculate на одном массиве данных.

void

OnTick

нет

эксперты

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

void

OnTimer

нет

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

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

void

OnTrade

нет

эксперты

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

double

OnTester

нет

эксперты

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

void

OnChartEvent

const int id,

const long &lparam,

const double &dparam,

const string &sparam

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

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

void

OnBookEvent

const string &symbol_name

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

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

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

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

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

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

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

 

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

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

  • OrderCalcMargin();
  • OrderCalcProfit();
  • OrderCheck();
  • OrderSend();
  • SendFTP();
  • Sleep();
  • ExpertRemove();
  • MessageBox().

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

  • SetIndexBuffer();
  • IndicatorSetDouble();
  • IndicatorSetInteger();
  • IndicatorSetString();
  • PlotIndexSetDouble();
  • PlotIndexSetInteger();
  • PlotIndexSetString();
  • PlotIndexGetInteger.

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

 

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

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

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

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

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

 

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

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

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

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

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

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

 

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

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

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

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

Пример:

//+------------------------------------------------------------------+
//|                                                   TestExpert.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, 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()
{
 
}

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

 

Разрешение на торговлю

Автоматизация торговли

В языке MQL5 существует специальная группа торговых функций, с помощью которых можно создавать автоматизированные торговые системы. Программы для автоматической торговли без участия человека называются экспертами (Expert Advisor) или торговыми роботами. Для создания эксперта в редакторе MetaEditor запустите мастер создания советников MQL5 Wizard и выберите один из двух вариантов:

  • Expert Advisor (template) – позволяет создать шаблон с готовыми функциями обработки событий, который необходимо дополнить всем необходимым функционалом с помощью самостоятельного программирования.
  • Expert Advisor (generate) – дает возможность создать полностью готового для работы торгового робота, просто выбирая необходимые вам модули: модуль формирования торговых сигналов, модуль управления капиталом и модуль подтягивания защитного стопа для открытых позиций (Trailing Stop).

mql5 wizard

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

Проверка разрешения на автоматическую торговлю

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

Проверка на разрешение автоматической торговли в самом терминале

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

terminal trade allowed

Переключать опцию разрешения автоматической торговли также можно прямо из Стандартной панели терминала:  

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

Пример проверки:

if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) 
   Alert("Проверьте в настройках терминала разрешение на автоматическую торговлю!");

Проверка разрешения на торговлю для данного запущенного эксперта/скрипта

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

mql trade allowed

Пример проверки:

if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   Alert("Проверьте в настройках терминала разрешение на автоматическую торговлю!");
else
{
   if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
      Alert("Автоматическая торговля запрещена в свойствах программы для ",__FILE__);
}

Проверка разрешения на торговлю любым экспертам/скриптам для данного счета

Запрет на автоматическую торговлю может быть установлен на стороне торгового сервера. Пример проверки такой ситуации:

   if(!AccountInfoInteger(ACCOUNT_TRADE_EXPERT))
      Alert("Автоматическая торговля запрещена для счета ",AccountInfoInteger(ACCOUNT_LOGIN),
      " на стороне торгового сервера");

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

Проверка разрешения торговли для данного счета

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

   if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED))
      Comment("Торговля запрещена для счета ",AccountInfoInteger(ACCOUNT_LOGIN),
            ".\n Возможно, подключение к торговому счету произведено по инвест паролю.",
            "\n Проверьте журнал терминала, есть ли там такая запись:",
            "\n\'",AccountInfoInteger(ACCOUNT_LOGIN),"\': trading has been disabled - investor mode.");

AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) может возвращать false в следующих случаях:

  • нет соединения с торговым сервером. Можно проверить с помощью TerminalInfoInteger(TERMINAL_CONNECTED);
  • торговый счет переведен в режим read-only (отправлен в архив);
  • торговля на счете запрещена на стороне торгового сервера;
  • подключение к торговому счете произведено в режиме инвестора.

 

События клиентского терминала

Init

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

Deinit

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

Причину деинициализации можно получить из параметра, переданного в функцию OnDeinit(). Выполнение функции OnDeinit() ограничивается 2.5 секундами. Если за это время функция не закончила свою работу, то ее выполнение завершается принудительно. Для скриптов событие Deinit не генерируется.

Start

Событие Start – это специальное событие для активизации скрипта после его загрузки. Это событие обрабатывается функцией OnStart. Событие Start экспертам и пользовательским индикаторам не посылается.

NewTick

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

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

Событие NewTick генерируется независимо от того, запрещена или разрешена автоматическая торговля (кнопка «Разрешить/запретить Авто-торговлю»). Запрет автоматической торговли означает только запрет на отправку торговых запросов из эксперта, работа эксперта не прекращается.

Запрет автоматической торговли путем нажатия на указанную кнопку не прерывает текущее выполнение функции OnTick().

Calculate

Событие Calculate генерируется только для индикаторов сразу после посылки события Init и при любом изменении ценовых данных. Обрабатывается функцией OnCalculate.

Timer

Событие Timer периодически генерируется клиентским терминалом для эксперта, который активизировал таймер при помощи функции EventSetTimer. Обычно эта функция вызывается в функции OnInit. Обработка события Timer производится функцией OnTimer. При завершении работы эксперта необходимо уничтожить созданный таймер при помощи EventKillTimer, которую обычно вызывают в функции OnDeinit.

Trade

Событие Trade генерируется при завершении торговой операции на торговом сервере. Обработка события Trade производится функцией OnTrade() для следующих торговых операций:

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

TradeTransaction

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

  • Отсылка торгового запроса любым MQL5-приложением в клиентском терминале при помощи функций OrderSend и OrderSendAsync и его последующее исполнение;
  • Отсылка торгового запроса через графический интерфейс терминала и его последующее исполнение;
  • Срабатывание отложенных ордеров и стоп-ордеров на сервере;
  • Выполнение операций на стороне торгового сервера.

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

  • обработка торгового запроса;
  • изменение открытых ордеров;
  • изменение истории ордеров;
  • изменение истории сделок;
  • изменение позиций.

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

Tester

Событие Tester генерируется по окончании тестирования эксперта на исторических данных. Обработка события  Tester производится функцией OnTester().

TesterInit

Событие TesterInit генерируется при запуске оптимизации в тестере стратегий перед самым первым проходом. Обработка события TesterInit производится функцией OnTesterInit().

TesterPass

Событие TesterPass генерируется при поступлении нового фрейма данных. Обработка события TesterPass производится функцией OnTesterPass().

TesterDeinit

Событие TesterDeinit генерируется по окончании оптимизации эксперта в тестере стратегий. Обработка события TesterDeinit производится функцией OnTesterDeinit().

ChartEvent

Событие ChartEvent генерируется клиентским терминалом при работе пользователя с графиком:

  • нажатия клавиатуры, когда окно графика находится в фокусе;
  • создание графического объекта;
  • удаление графического объекта;
  • щелчок мыши на графическом объекте, принадлежащего графику;
  • перемещение графического объекта при помощи мыши;
  • окончание редактирования текста в поле ввода графического объекта LabelEdit.

Также существует пользовательское событие ChartEvent, которое может послать эксперту любая mql5-программа при помощи функции EventChartCustom. Событие обрабатывается  функцией OnChartEvent.

BookEvent

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

Для того чтобы отписаться от получения события BookEvent по символу, необходимо вызывать функцию MarketBookRelease. Событие BookEvent является широковещательным – это означает, что достаточно одному эксперту подписаться на получение события BookEvent с помощью функции MarketBookAdd, и все остальные эксперты, имеющие обработчик OnBookEvent, будут получать это событие. Поэтому необходимо анализировать имя символа, которое передается в обработчик в качестве параметра.

 

Вызов импортируемых функций

Для импорта функций во время выполнения mql5-программы используется раннее связывание. Это значит, что если в программе есть вызов импортируемой функции, то соответствующий модуль (ex5 или dll) загружается в процессе загрузки программы. Библиотеки MQL5 и DLL выполняются в потоке вызывающего модуля.

Не рекомендуется использовать полностью квалифицированное имя загружаемого модуля вида Drive:\Directory\FileName.Ext. Библиотеки MQL5 загружаются из папки terminal_dir\MQL5\Libraries. Если библиотека не была найдена, то производится попытка загрузить библиотеку из папки terminal_dir\experts.

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

  1. Директория из которой был запущен модуль, импортирующий dll. Под модулем понимается эксперт, скрипт, индикатор или библиотека EX5;
  2. Директория каталог_данных_терминала\MQL5\Libraries (TERMINAL_DATA_PATH\MQL5\Libraries);
  3. Директория, из которой был запущен клиентский терминал MetaTrader 5;
  4. Системная директория;
  5. Директория Windows;
  6. Текущая директория;
  7. Директории, перечисленные в системной переменной PATH.

Если библиотека DLL использует в своей работе другую DLL, то в случае отсутствия второй DLL первая не сможет загрузиться.

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

Поиск импортируемой библиотеки EX5 производится в следующей последовательности:

  1. Директория, путь к которой задается относительно директории импортирующего EX5 эксперта (скрипта, индикатора);
  2. Директория каталог_терминала\MQL5\Libraries;
  3. Директория MQL5\Libraries в общей директории всех клиентских терминалов MetaTrader 5 (Common\MQL5\Libraries).

Функции, импортируемые из DLL в mql5-программу, должны обеспечивать соглашение о связях, принятое для функций Windows API. Для обеспечения такого соглашения в исходном тексте программ, написанных на языках C или C++, используется ключевое слово __stdcall, которое является специфическим для компиляторов от фирмы Microsoft(r). Обсуждаемое соглашение о связях характеризуется следующим:

  • вызывающая функция (в нашем случае mq5-программа) должна «видеть» прототип вызываемой (импортируемой из DLL) функции, для того чтобы правильно сложить параметры на стек;
  • вызывающая функция (в нашем случае mql5-программа) складывает параметры на стек в обратном порядке, справа налево — именно в таком порядке импортируемая функция считывает переданные ей параметры;
  • параметры передаются по значению, за исключением тех, которые явно передаются по ссылке (в нашем случае строк);
  • импортируемая функция, считывая переданные ей параметры, сама очищает стек.

При описании прототипа импортируемой функции можно использовать параметры со значениями по умолчанию.

В случае если соответствующая библиотека не смогла загрузиться, либо установлен запрет на использование DLL, либо импортируемая функция не была найдена – эксперт останавливает свою работу с соответствующим сообщением «expert stopped» в журнале. При этом эксперт не будет запускаться, пока не будет заново проинициализирован. Эксперт может быть переинициализирован в результате перекомпиляции либо после открытия таблицы свойств эксперта и нажатия кнопки OK.

Передача параметров

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

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

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

 

Ошибки выполнения

В исполняющей подсистеме клиентского терминала существует возможность сохранения кода ошибки в случае ее возникновения при выполнении mql5-программы. Для каждой исполняемой mql5-программы предусмотрена предопределенная переменная _LastError.

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

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

  • деление на ноль;
  • выход за пределы массива;
  • использование некорректного указателя объекта;