Как самому создать советника или индикатор

Как самому создать советника или индикатор

Для разработки торговых систем в платформу встроен собственный язык программирования MetaQuotes Language 5 (MQL5), среда разработки MetaEditor и инструменты тестирования стратегий.

Любую информацию о разработке торговых стратегий на языке MQL5 можно найти на официальном сайте MQL5.community. На этом же сайте в разделе Code Base могут быть найдены примеры готовых приложений.

Встроенный язык программирования торговых стратегий MQL5 #

В торговую платформу встроен язык программирования торговых стратегий MetaQuotes Language 5. Это — пятое поколение языков MQL. Он позволяет писать советники, автоматизирующие управление торговыми процессами, и реализовывать собственные торговые стратегии. Кроме того, на MQL5 можно создавать пользовательские индикаторы, скрипты и библиотеки функций.

Особенности языка MQL5:

  • Объектная ориентированность;
  • Синтаксис MQL5 похож на синтаксис языка C++;
  • Большое количество функций, необходимых для анализа котировок, управления позициями, вызова технических индикаторов и других;
  • Высокая производительность;
  • Высокий уровень защиты от декомпиляции: новые, сложные алгоритмы шифрования, проверка целостности файлов и сложность самого языка;
  • Поддержка OpenCL, что позволяет использовать видеокарты для выполнения вычисления в MQL5-программах;
  • Интегрированная среда разработки программ MetaEditor, включающая отладчик.

Подробное описание всех конструкций языка и функций приведено в справочнике MQL5. Также всю интересующую информацию о MQL5 можно найти на сайте сообщества разработчиков https://www.mql5.com.

Редактор для разработки торговых приложений MetaEditor #

MetaEditor — это интегрированная среда разработки на языке MQL5, он является составной частью торговой платформы. MetaEditor позволяет создавать, редактировать, компилировать и отлаживать исходные тексты программ, написанных на языке MQL5.

  • Мастер MQL5 для создания шаблонов и готовых торговых роботов
    В MetaEditor встроен Мастер MQL5, который помогает быстро создавать MQL5-программы. Благодаря Мастеру MQL5, трейдер может создать советники, не обладая знаниями в области программирования. Все что нужно сделать — это выбрать торговые сигналы, которые будет использовать советник, алгоритм мани-менеджмента и трейлинг стопа. Код советника будет сгенерирован автоматически на основе выбранных параметров.
    Помимо этого, Мастер MQL5 позволяет создавать шаблоны MQL5-программ, что облегчает работу программиста.
  • Помощь при работе с исходным кодом
    MetaEditor распознает различные конструкции языка: выдает подсказки по использованию функций и подсвечивает различные элементы кода программы. Таким образом, сам редактор облегчает ориентирование в коде торговых программ и ускоряет их разработку.
  • Отладка для поиска ошибок
    MetaEditor позволяет осуществлять отладку программ, что значительно облегчает поиск ошибок. Можно пошагово выполнять исходный код и следить за значениями переменных.
  • Профилирование для оптимизации кода
    В редакторе также доступна возможность профилирования. Вы сможете выявить наиболее медленные функции в исходном коде и максимально оптимизировать работу торговых программ.
  • Статьи о программировании и библиотека исходных кодов
    Прямо в редакторе вы можете найти множество обучающий статей о программировании на MQL5. Помимо этого имеется доступ к огромной библиотеке бесплатных программ для автотрейдинга в виде исходных кодов.
  • MQL5 Storage — онлайн хранилище с поддержкой версионности
    Хранилище предоставляет множество преимуществ: безопасное хранение файлов и возможность восстановления при выходе вашего компьютера из строя, доступ к своим кода с любого компьютера при помощи аккаунта MQL5.community, возможность совместной работы над проектами.

Детальное описание MetaEditor дано во встроенной справке по этой программе. Описание языка MQL5 может быть найдено во встроенном справочнике, а также на официальном сайте MQL5.community.

Статьи по разработке торговых приложений #

На сайте MQL5.community доступна обширная библиотека статей по программированию на MQL4/MQL5. Статьи являются отличным справочным материалом по созданию программ, в них рассматривается множество практических задач по алготрейдингу. Новые статьи выходят каждую неделю.

Список всех доступных статей отображается прямо в MetaEditor. Чтобы найти интересующий материал, воспользуйтесь онлайн-поиском.

Статьи по программированию на MQL4/MQL5

Какие бывают типы приложений на MQL5 #

Существует три основных типа торговых приложений.

Советники

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

Читать статью  Как выбрать лучшее время для трейдинга: 5 реально работающих советов

Все советники хранятся в папке /MQL5/Experts торговой платформы.

Пользовательские индикаторы

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

Все индикаторы хранятся в папке /MQL5/Indicators торговой платформы.

Скрипты

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

Все скрипты хранятся в папке /MQL5/Scripts торговой платформы.

Сервисы

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

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

Все сервисы хранятся в папке /MQL5/Services торговой платформы.

Внутри папок Experts, Indicators, Scripts и Services программы могут быть рассортированы по подпапкам, при этом в окне «Навигатор» будет отображаться структура их размещения.

Как создать и запустить торговое приложение #

Нажмите » Создать в редакторе» в контекстном меню окна «Навигатор» в разделе «Советники», «Индикаторы» или «Скрипты». Также для запуска MetaEditor можно нажать F4.

Приступить к созданию торгового приложения

После этого будет запущен MetaEditor, и в нем автоматически откроется «Мастер MQL5». Он позволит сгенерировать шаблон нужной программы, что быстро приступить к разработке. Для примера создадим простой скрипт, который будет выводить в журнал надпись «Hello world».

Мастер MQL5 сгенерирует шаблон приложения

В полученном шаблоне напишем код Print ( «Hello World» ); и произведем компиляцию клавишей F7, чтобы получить исполняемый файл. Исполняемый файл имеет расширение EX5, именно такой файл может быть запущен в торговой платформе.

Компиляция и ее результаты

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

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

Запуск скрипта в торговой платформе

Особенности работы с программами для автоматического трейдинга описаны в разделе «Торговые советники и собственные индикаторы».

Как изменить торговое приложение #

Чтобы приступить к редактированию торгового робота или пользовательского индикатора, нажмите » Изменить» в его контекстном меню в окне «Навигатор» или выделите его и нажмите «Enter». При этом будет открыт MetaEditor, в который уже будет загружен исходный код выбранного индикатора. После изменения индикатора скомпилируйте его повторно (F7), иначе в платформе будет использоваться предыдущая, неизмененная версия.

Как завершить работу торгового приложения #

Существует множество способов завершить работу торгового приложения в платформе.

Пользовательский технический индикатор

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

Как запустить скачанный файл исходного кода MQ5 #

Если у вас имеется только файл исходного кода (*.MQ5), поместить его в папку, соответствующую типу приложения:

  • Для советников — /MQL5/Experts
  • Для индикаторов — /MQL5/Indicators
  • Для скриптов — /MQL5/Scripts

Чтобы быстро перейти к папке хранения информации торговой платформы, нажмите » Открыть каталог данных» в меню «Файл».

Чтобы запустить файл в торговой платформе, скомпилируйте его в MetaEditor:

  • Откройте MetaEditor клавишей F4.
  • В MetaEditor в окне «Навигатор» откройте файл исходного кода двойным нажатием на нем левой кнопкой мыши.
  • Скомпилируйте его клавишей F7.

В результате вы получите исполняемый файл *.EX5, который уже можно запустить в торговой платформе.

Исходные файлы (*.MQ5) не отображаются в окне «Навигатор» торговой платформы.

MQL5 — Простой советник на индикаторах

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

Читать статью  Личный пример заработка денег в сети через интернет – на форекс и не только!

Предыдущие уроки

  • MQL5 Урок 1 – Редактор кода, События, Устройство mql-программ
  • MQL5 Урок 2 – Типы переменных
  • MQL5 Урок 3 – Операции и Выражения
  • MQL5 Урок 4 – Операторы
  • MQL5 Урок 5 – Математические функции и циклы
  • MQL5 Урок 6 – Массивы
  • MQL5 Урок 7 – Функции
  • MQL5 Урок 8 – Дата и время
  • MQL5 Урок 9 — Работа со строками
  • MQL5 Урок 10 — Перечисления
  • MQL5 Урок 11 — Торговые операции

Вместо ранее написанных функций MarketBuy и MarketSell мы напишем более универсальную:

//+------------------------------------------------------------------+ //| Покупка или продажа по рынку | //| int type: | //| ORDER_TYPE_BUY | //| ORDER_TYPE_SELL | //+------------------------------------------------------------------+ void openMarketOrder(ENUM_ORDER_TYPE type) < //--- сбросим код последней ошибки в ноль ResetLastError(); MqlTradeRequest trade_request = <>; // Инициализация структуры торгового запроса trade_request.action = TRADE_ACTION_DEAL; // Тип - по рынку trade_request.symbol = _Symbol; // Текущий инструмент trade_request.volume = lot; // Объем if (type == ORDER_TYPE_BUY) < trade_request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); // Цена открытия >else < trade_request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID); // Цена открытия >trade_request.type = type; // Тип ордера trade_request.type_filling = ORDER_FILLING_FOK; // Политика исполнения (немедленно или отмена) trade_request.deviation = deviation; // допустимое отклонение от цены trade_request.magic = magic_number; // MagicNumber ордера MqlTradeResult trade_result = <>; // Инициализация структуры результата MqlTradeCheckResult check_result = <>; // Инициализация структуры проверки запроса // Проверка структуры торгового запроса bool res_check = OrderCheck(trade_request, check_result); if (!res_check) < Print(__FUNCTION__, " - результат проверки отрицательный, код ответа: ", check_result.retcode); Print(__FUNCTION__, " - расшифровка кода ответа: ", resultRetcodeText(check_result.retcode)); Print(__FUNCTION__, " - код ошибки: ", GetLastError()); ResetLastError(); >// Отправка торгового запроса bool res_send = OrderSendAsync(trade_request, trade_result); if (!res_send) < uint answer = trade_result.retcode; Print(__FUNCTION__, " - результат отправки отрицательный, код ответа:", answer); Print(__FUNCTION__, " - расшифровка кода ответа:", resultRetcodeText(answer)); Print(__FUNCTION__, " - код ошибки: ", GetLastError()); ResetLastError(); >>

Торговая логика в методе OnTick

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

//+——————————————————————+ //| Expert deinitialization function | //+——————————————————————+ void OnDeinit(const int reason)

Метод OnTick будет выглядеть следующим образом:

//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() < if (Bars(_Symbol,_Period) < ma_period * 2) < // общее количество баров на графике Print("На графике меньше ", ma_period * 2, " баров, советник не будет работать!"); return; >bool is_new_bar = isNewBar(); //--- советник должен проверять условия совершения новой торговой операции только на новом баре if (is_new_bar == false) < return; >MqlTick latest_price; // Будет использоваться для текущих котировок MqlTradeRequest mrequest; // Будет использоваться для отсылки торговых запросов MqlTradeResult mresult; // Будет использоваться для получения результатов выполнения торговых запросов MqlRates rates[]; // Будет содержать цены, объемы и спред для каждого бара // Установим индексацию в массивах котировок и индикаторов, как в таймсериях ArraySetAsSeries(ma, true); ArraySetAsSeries(rates, true); //--- Получить текущее значение котировки в структуру типа MqlTick if (!SymbolInfoTick(_Symbol, latest_price)) < Alert("Ошибка получения последних котировок - ошибка: ",GetLastError()); return; >//--- Получить исторические данные последних 3-х баров if (CopyRates(_Symbol,_Period,0,3,rates) < 0) < Alert("Ошибка копирования исторических данных - ошибка: ", GetLastError()); return; >//--- Используя хэндлы индикаторов, копируем новые значения индикаторных буферов в массивы if (CopyBuffer(ma_handle, 0, 0, 3, ma) < 0) < Print("Ошибка копирования буферов индикатора MA - номер ошибки:",GetLastError()); return; >bool buy_condition = (ma[2] < ma[1] && rates[1].close >ma[1]); bool sell_condition = (ma[2] > ma[1] && rates[1].close < ma[1]); if (buy_condition) < openMarketOrder(ORDER_TYPE_BUY); >if (sell_condition) < openMarketOrder(ORDER_TYPE_SELL); >modifySlTp(); >

Как видите, проверку на открытие нового бара мы вынесли в отдельную функцию для удобства:

//+------------------------------------------------------------------+ //| Для сохранения значения времени бара мы используем | //| static-переменную Old_Time. | //| При каждом выполнении функции OnTick мы будем сравнивать время | //| текущего бара с сохраненным временем. | //| Если они не равны, это означает, что начал строиться новый бар. | //| Timer function | //+------------------------------------------------------------------+ bool isNewBar() < static datetime old_time; datetime new_time[1]; bool is_new_bar = false; // копируем время текущего бара в элемент new_time[0] int copied = CopyTime(_Symbol, _Period, 0, 1, new_time); if (copied >0) < // ok, успешно скопировано if (old_time != new_time[0]) < // если старое время не равно is_new_bar = true; // новый бар if (MQL5InfoInteger(MQL5_DEBUGGING)) < Print("Новый бар", new_time[0], "старый бар", old_time); >old_time = new_time[0]; // сохраняем время бара > > else < Alert("Ошибка копирования времени, номер ошибки =",GetLastError()); ResetLastError(); return is_new_bar; >return is_new_bar; >

Функция модификации стоп-лоссов и тейк-профитов

Как вы заметили, при открытии позиции стоп-лоссы и тейк-профиты не установлены. Поэтому нам нужна функция, которая модифицирует стоп-лоссы и тейк-профиты открытых позиций:

//+------------------------------------------------------------------+ //| Модификация значений Stop Loss и Take Profit у открытой позиции | //+------------------------------------------------------------------+ void modifySlTp() < //--- объявление запроса и результата MqlTradeRequest request; MqlTradeResult result; int total = PositionsTotal(); // количество открытых позиций //--- перебор всех открытых позиций for (int i = 0; i < total; i++) < //--- параметры ордера ulong position_ticket = PositionGetTicket(i);// тикет позиции string position_symbol = PositionGetString(POSITION_SYMBOL); // символ int digits = (int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // количество знаков после запятой ulong magic = PositionGetInteger(POSITION_MAGIC); // MagicNumber позиции double volume = PositionGetDouble(POSITION_VOLUME); // объем позиции double position_sl = PositionGetDouble(POSITION_SL); // Stop Loss позиции double position_tp = PositionGetDouble(POSITION_TP); // Take Profit позиции ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // тип позиции //--- если MagicNumber совпадает, Stop Loss и Take Profit не заданы if(magic == magic_number && position_sl == 0 && position_tp == 0 && position_symbol == _Symbol) < //--- вычисление текущих ценовых уровней double price = PositionGetDouble(POSITION_PRICE_OPEN); //--- вычисление и округление значений Stop Loss и Take Profit if (type == POSITION_TYPE_BUY) < position_sl = NormalizeDouble(price - price_level - sl * _Point, digits); position_tp = NormalizeDouble(price + price_level + tp * _Point, digits); >else < position_sl = NormalizeDouble(price + price_level + sl * _Point, digits); position_tp = NormalizeDouble(price - price_level - tp * _Point, digits); >//--- обнуление значений запроса и результата ZeroMemory(request); ZeroMemory(result); //--- установка параметров операции request.action = TRADE_ACTION_SLTP; // тип торговой операции request.position = position_ticket; // тикет позиции request.symbol = position_symbol; // символ request.sl = position_sl; // Stop Loss позиции request.tp = position_tp; // Take Profit позиции request.magic = magic_number; // MagicNumber позиции //--- вывод информации о модификации PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type)); //--- отправка запроса if (!OrderSend(request, result)) < uint answer = result.retcode; Print(__FUNCTION__, " - результат отправки отрицательный, код ответа:", answer); Print(__FUNCTION__, " - расшифровка кода ответа:", resultRetcodeText(answer)); Print(__FUNCTION__, " - код ошибки: ", GetLastError()); ResetLastError(); >//--- информация об операции PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order); > > >

Закрытие открытых позиций

И последняя функция в этом уроке – функция закрытия позиций встречными:

//+------------------------------------------------------------------+ //| Модификация значений Stop Loss и Take Profit у открытой позиции | //+------------------------------------------------------------------+ void closeAll() < //--- объявление запроса и результата MqlTradeRequest request; MqlTradeResult result; int total = PositionsTotal(); // количество открытых позиций //--- перебор всех открытых позиций for (int i = total-1; i >= 0; i--) < //--- параметры ордера ulong position_ticket = PositionGetTicket(i); // тикет позиции string position_symbol = PositionGetString(POSITION_SYMBOL); // символ int digits = (int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // количество знаков после запятой ulong magic = PositionGetInteger(POSITION_MAGIC); // MagicNumber позиции double volume = PositionGetDouble(POSITION_VOLUME); // объем позиции ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // тип позиции //--- если MagicNumber совпадает if (magic == magic_number && position_symbol == _Symbol) < //--- обнуление значений запроса и результата ZeroMemory(request); ZeroMemory(result); //--- установка параметров операции request.action = TRADE_ACTION_DEAL; // тип торговой операции request.position = position_ticket; // тикет позиции request.symbol = position_symbol; // символ request.volume = volume; // объем позиции request.deviation = deviation; // допустимое отклонение от цены request.magic = magic_number; // MagicNumber позиции //--- установка цены и типа ордера в зависимости от типа позиции if (type == POSITION_TYPE_BUY) < request.price = SymbolInfoDouble(position_symbol, SYMBOL_BID); request.type = ORDER_TYPE_SELL; >else < request.price = SymbolInfoDouble(position_symbol, SYMBOL_ASK); request.type = ORDER_TYPE_BUY; >//--- вывод информации о закрытии PrintFormat("Close #%I64d %s %s",position_ticket,position_symbol,EnumToString(type)); //--- отправка запроса if (!OrderSend(request, result)) < uint answer = result.retcode; Print(__FUNCTION__, " - результат отправки отрицательный, код ответа:", answer); Print(__FUNCTION__, " - расшифровка кода ответа:", resultRetcodeText(answer)); Print(__FUNCTION__, " - код ошибки: ", GetLastError()); ResetLastError(); >//--- информация об операции PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order); > > >

Заключение

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

Читать статью  Автоматическая торговля на Форекс

На этом все, всем пока!

Скачать советник из урока

С уважением, Дмитрий аkа Silentspec
Tlap.com

Источник https://www.metatrader5.com/ru/terminal/help/algotrading/autotrading

Источник https://tlap.com/mql5-prostoj-sovetnik-na-indikatorah/