Главная / Советники для торговли / Пошаговое руководство по написанию MQL5-советников для начинающих
Опубликовано: 30 сентября 2021

Пошаговое руководство по написанию MQL5-советников для начинающих

Содержание

Пошаговое руководство по написанию MQL5-советников для начинающих

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

1. Торговая стратегия

Что будет делать наш советник:

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

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

  1. Мы будем использовать индикатор Moving Average (скользящие средние) с периодом 8 (вы можете выбрать любой период, но в данной стратегии мы будем использовать период 8).
  2. Мы хотим, чтобы наш советник покупал, если 8-периодная скользящая средняя (далее для удобства будем называть ее MA-8) возрастает и текущая цена закрытия находится выше ее; советник должен продавать , когда MA-8 падает и цена закрытия находится ниже MA-8 .
  3. Также мы собираемся использовать другой индикатор, называемый Average Directional Movement (ADX) с периодом 8 для определения факта наличия тренда на рынке. Это нужно для того, чтобы входить в рынок, когда он находится в состоянии тренда. Для того, чтобы это реализовать, мы будем помещать торговый запрос (на покупку или продажу) при наступлении условий, указанных выше, а также при значениях ADX, больших 22. Если ADX>22, но уменьшается или ADX<22, мы не будем помещать торговые запросы даже при наступлении условий, изложенных в пункте 2.
  4. Мы хотим защитить себя установкой ордеров Stop Loss в 30 пунктов, Take Proft установим на уровне 100 пунктов.
  5. Также мы хотим, чтобы советник проверял возможности для продажи/покупки только при формировании нового бара, при этом советник должен помещать ордер на покупку только в случае сигнала на покупку и отсутствия открытых длинных позиций. Аналогично в случае продажи — условия на продажу и отсутствие открытых коротких позиций.

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

2. Пишем советник

2.1 Мастер MQL5

Начнем с запуска редактора MetaQuotes Language Editor 5. Затем нажимаем Ctrl-N или на кнопку «Создать» в панели инструментов.

Рисунок 1. Создание нового документа MQL5

Рисунок 1. Создание нового документа MQL5

В окне Мастера MQL5 выбираем «Советник» и нажимаем «Далее», как показано на рис. 2:

Рисунок 2. Выбор типа создаваемой программы

Рисунок 2. Выбор типа создаваемой программы

В следующем окне в поле «Имя» напишите имя, которое вы хотите дать вашему советнику, я написал «My_First_EA«. Вы можете указать свое имя в поле «Автор» и адрес в виде ссылки на ваш сайт или e-mail (если есть).

Рисунок 3. Общие свойства советника

Рисунок 3. Общие параметры советника

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

Рисунок 4. Входные параметры советника

Рисунок 4. Входные параметры советника

В нашем советнике нам нужно иметь возможность изменять Stop Loss, Take Profit, ADX Period and Moving Average Period, так что укажем их здесь.

Дважды кликнем мышкой по колонке «Имя» в параметрах и напишем наименование параметра, аналогично в колонках «Тип» и «Начальное значение» укажем тип данных параметра и начальные значения.

После этого, результат будет примерно следующий:

Рисунок 5. Типы данных входных параметров советника

Рисунок 5. Типы данных входных параметров советника

Как видно, мы выбрали тип integer (int) для всех параметров. Рассмотрим подробнее типы данных.

  • char: Целый тип char занимает в памяти 1 байт (8 бит) и позволяет выразить в двоичной системе счисления 2^8 значений=256. Тип char может содержать как положительные, так и отрицательные значения. Диапазон изменения значений составляет от -128 до 127.
  • uchar: Целый тип uchar также занимает в памяти 1 байт, как и тип char, но в отличие от него, uchar предназначен только для положительных значений. Минимальное значение равно нулю, максимальное значение равно 255. Первая буква u в названии типа uchar является сокращением слова unsigned (беззнаковый).
  • short: Целый тип short имеет размер 2 байта(16 бит) и, соответственно, позволяет выразить множество значений равное 2 в степени 16: 2^16=65 536. Так как тип short является знаковым и содержит как положительные, так и отрицательные значения, то диапазон значений находится между -32 768 и 32 767.
  • ushort: Беззнаковым типом short является тип ushort, который также имеет размер 2 байта. Минимальное значение равно 0, максимальное значение 65 535.
  • int: Целый тип int имеет размер 4 байта (32 бита). Минимальное значение -2 147 483 648, максимальное значение 2 147 483 647.
  • uint: Беззнаковый целый тип uint занимает в памяти 4 байта и позволяет выражать целочисленные значения от 0 до 4 294 967 295.
  • long: Целый тип long имеет размер 8 байт (64 бита). Минимальное значение -9 223 372 036 854 775 808, максимальное значение 9 223 372 036 854 775 807.
  • ulong: Целый тип ulong также занимает 8 байт и позволяет хранить значения от 0 до 18 446 744 073 709 551 615.

Как видно из описания различных типов данных, беззнаковые целые (uint) не предназначены для хранения отрицательных значений, любые попытки установить отрицательные значения могут привести к непредсказуемым результатам. Например, если вы хотите хранить отрицательные значения, нельзя для них использовать переменные типа uchar, uint, ushort, ulong.

Вернемся к нашему советнику. Для значений, меньших 127 или 255, для экономии памяти можно использовать значения типа char or uchar, соответственно, однако для удобства мы зададим их значения как тип int.

После того, как закончено определение необходимых входных параметров индикатора, нажмем на кнопку «Finish» и MetaQuotes Editor5 создаст шаблон кода, представленный ниже:

Для лучшего понимания, рассмотрим отдельно различные секции кода.

В верхней части кода (заголовок) определяются свойства советника. Как видно, это значения, которые были установлены в Мастере MQL5 на рис. 3.

В этой части кода также можно задать дополнительные параметры, например description (текст с кратким описанием советника), определить константы, включить дополнительные файлы или импортируемые функции.

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

  • #define
    Директива #define используется для определения констант. Записывается в виде:
  • #defineidentifiertoken_string
    Это означает, что компилятор заменит в коде переменные identifier численным значением, равным token_string.

#define ABC 100
#define COMPANY_NAME «MetaQuotes Software Corp.»

В данном случае COMPANY_NAME будет означать строку «MetaQuotes Software Corp.», вместо ABC будет подразумеваться число, равное 100.

Более подробнее о директивах препроцессора можно прочитать в руководстве по MQL5. Идем далее.

Вторая часть заголовка в нашем коде — это секция входных параметров.

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

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

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

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

Например, можно проверить, достаточно ли баров на графике для работы нашего советника и т.п.

Также это лучшее место для получения хэндлов технических индикаторов, которые будут использоваться (в нашем случае это индикаторы ADX и Moving Average ).

Функция OnDeinit вызывается при удалении советника с графика.

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

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

Большая часть кода, отвечающего за реализацию нашей торговой стратегии будет содержаться в данной функции.

Отметим, что советник не сможет производить торговые операции, если в авто-трейдинг не разрешен в клиентском терминале:

Рисунок 6. Авто-торговля включена

Рисунок 6. Торговля советником разрешена

Теперь, когда мы рассмотрели разделы кода нашего советника, начнем добавления кода в шаблон.

2.2. Раздел входных параметров

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

Это однострочный комментарий.

Это многострочный комментарий

Это многострочный комментарий. Многострочные комментарии начинаются с пары символов «/*» и заканчиваются «*/» .

При компиляции кода комментарии игнорируются компилятором.

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

Рисунок 7. Входные параметры советника

Рисунок 7. Входные параметры советника

Вернемся к нашему коду.

Мы решили добавить дополнительные параметры в наш советник. Параметр EA_Magic (Magic Number) будет использован для всех ордеров нашего советника. Минимальное значение ADX задано как переменная типа double. Значения типа double используются для констант, которые, наряду с целой частью, также могут содержать и дробную часть.

double mysum = 123.5678 ;

double b7 = 0.09876 ;

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

Далее мы также объявили дополнительные переменные, которые будут использованы следующим образом: переменная adxHandle будет использоваться для хранения хэндла индикатора ADX, переменная maHandle для хэндла индикатора Moving Average. Динамические массивы plsDI[], minDI[], adxVal[] are будут использованы для хранения значений +DI, -DI и самого значения ADX для каждого бара графика. Численные значения индикатора Moving Average для каждого бара графика будут храниться в динамическом массиве maVal[].

Кстати, что представляют собой динамические массивы? Динамический массив — это массив, объявленный без указания размера. Другими словами, в квадратных скобках при его описании нет конкретного числа, указывающего его размер.

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

double allbars[ 20 ]; // этот массив содержит 20 элементов — от 0 до 19

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

Переменные STP и TKP нужны для установки значений Stop Loss и Take Profit ордеров нашего советника.

2.3. Секция инициализации советника

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

Хэндл индикатора ADX получаем при помощи функции iADX. В качестве аргументов ей передается символ графика symbol ( NULL также означает символ текущего графика), период/таймфрейм ( 0 означает таймфрейм текущего графика ), период индикатора ADX, который будет использоваться для вычисления индикатора (ADX_Period мы определили в разделе входных параметров индикатора):

Хэндл индикатора Moving Average получаем при помощи функции iMA. Аргументы этой функции следующие:

  • symbol — Символьное имя инструмента, на данных которого будет вычисляться индикатор (можно использовать _symbol, symbol() или NULL для текущего символа).
  • period — Значение периода может быть одним из значений перечисления ENUM_TIMEFRAMES, (можно использовать _period, period() или 0 для таймфрейма текущего графика).
  • ma_period — Период усреднения для вычисления скользящего среднего (который мы определили ранее в разделе входных параметров индикатора).
  • ma_shift — Сдвиг индикатора относительно ценового графика (мы используем 0).
  • ma_method — Метод усреднения. Может быть любым из значений MODE_SMA, MODE_EMA, MODE_SMMA или MODE_LWMA.
  • applied_price — Используемая цена. Может быть любой из ценовых констант ENUM_APPLIED_PRICE или хендлом другого индикатора.

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

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

Мы решили хранить значения Stop Loss и Take Profit в определенных ранее переменных STP и TKP. Почему мы это сделали?

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

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

Предопределенной переменной _Digits или функцией Digits() . Для 3-х и 5-ти значных котировок мы умножаем значения Stop Loss и Take Profit на 10.

2.4. Раздел деинициализации советника


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

Для их удаления мы используем функцию IndicatorRelease(). Эта функция имеет лишь один параметр ( хэндл индикатора ).

bool IndicatorRelease (
int indicator_handle , // хэндл индикатора
);

Функция удаляет хэндл индикатора и освобождает расчетную часть индикатора, если ею больше никто не пользуется.

2.5 Раздел OnTick советника

Первое, что мы здесь делаем — проверяем достаточно ли баров на текущем графике. Количество баров на любом графике можно узнать при помощи функции Bars. У нее есть два входных параметра, первый — symbol, (символ текущего графика можно получить используя предопределенную переменную _Symbol или функцию Symbol() ) и period или timeframe текущего графика (для текущего графика — предопределенная переменная _Period или функция Period() ).

При количестве баров на графике менее 60, наш советник не будет работать и выйдет из функции OnTick. Функция Alert показывает сообщение в отдельном окне. Эта функция выводит значения аргументов/параметров, разделенных запятыми. В нашем случае выводится только одно значение в виде строки и завершается работа функции OnTick.

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

Мы начнем с объявления статической переменной Old_Time, в которой будем хранить время бара. Мы определили ее статической, поскольку нам нужно, чтобы ее значение сохранялось при новом вызове функции. Тогда у нас будет возможность проверять ее значение с переменной New_Time, которая также объявлена типа datetime, но в виде массива из одного элемента, она будет использоваться для хранения времени текущего бара. Также мы объявляем переменную IsNewBar типа boolean, и устанавливаем ее значение в false. Ее значение будет установлено в true только в случае определения факта появления нового бара.

Для получения времени бара используется функция CopyTime. Она копирует время бара в массив New_Time, состоящий из одного элемента. В случае успеха, мы сравниваем значение времени бара с сохраненным ранее временем предыдущего бара. Если они различны, это означает, что появился новый бар и переменная IsNewBar устанавливается в true, а значение текущего времени бара сохраняется в переменной Old_Time.

Таким образом, переменная IsNewBar будет указывать на факт появления нового бара. Если ее значение равно false, мы завершаем выполнение функции OnTick.

Обратите внимание на строчку:

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

Следующее, что мы собираемся cделать — проверить наличие достаточного количества баров для работы. Зачем делать это снова?

Мы хотим быть уверены в том, что наш советник работает корректно.

Следует отметить, что функция OnInit вызывается только один раз при присоединении советника к графику, а функция OnTick вызывается каждый раз при поступлении нового тика (ценовой котировки).

Как можно видеть, мы это делаем по-другому. Мы сохраняем общее количество баров в истории в новой переменной Mybars, определенной внутри функции OnTick:

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

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

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

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

struct MqlTick
<
datetime time ; // Время последнего обновления цен
double bid ; // Текущая цена Bid
double ask ; // Текущая цена Ask
double last ; // Текущая цена последней сделки (Last)
ulong volume ; // Объем для текущей цены Last
>;

Любая переменная, объявленная типа может быть легко использована для получения текущих значений цен Ask, Bid, Last и Volume, достаточно вызвать функцию SymbolInfoTick.

Мы объявили переменную latest_price как структуру MqlTick, так что мы можем использовать ее для получения цен Bid и Ask.

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

struct MqlTradeRequest
<
ENUM_TRADE_REQUEST_ACTIONS action ; // Тип выполняемого действия
ulong magic ; // Идентификатор magic number эксперта
ulong order ; // Тикет ордера
string symbol ; // Имя торгового инструмента
double volume ; // Запрашиваемый объем сделки в лотах
double price ; // Цена
double stoplimit ; // Уровень StopLimit ордера
double sl ; // Уровень Stop Loss ордера
double tp ; // Уровень Take Profit ордера
ulong deviation ; // Максимально приемлемое отклонение от запрашиваемой цены
ENUM_ORDER_TYPE type ; // Тип ордера
ENUM_ORDER_TYPE_FILLING type_filling ; // Тип ордера по исполнению
ENUM_ORDER_TYPE_TIME type_time ; // Тип ордера по времени действия
datetime expiration ; // Срок истечения ордера (для ордеров типа ORDER_TIME_SPECIFIED)
string comment ; // Комментарий к ордеру
>;

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

Результат выполнения торговой операции возвращается в специальную предопределенную структуру типа MqlTradeResult. Любая переменная типа MqlTradeResult может быть использована для доступа к результату выполнения торгового запроса.

struct MqlTradeResult
<
uint retcode ; // Код результата операции
ulong deal ; // Тикет сделки, если она совершена
ulong order ; // Тикет ордера, если он выставлен
double volume ; // Объем сделки, подтверждённый брокером
double price ; // Цена в сделке, подтверждённая брокером
double bid ; // Текущая рыночная цена Bid
double ask ; // Текущая рыночная цена Ask
string comment ; // Комментарий брокера к операции (по умолчанию заполняется расшифровкой)
>;

В нашем случае переменная mresult объявлена как структура тип MqlTradeResult.

Цены (Open, Close, High, Low), время, объем каждого бара, и спред символа хранятся в этой структуре. Любой массив, определенный как массив типа MqlRates может быть использован для хранения значений цен, объемов и спредов по символу.

struct MqlRates
<
datetime time ; // Время начала периода
double open ; // Цена открытия
double high ; // Наивысшая цена за период
double low ; // Наименьшая цена за период
double close ; // Цена закрытия
long tick_volume ; // Тиковый объем
int spread ; // С пред
long real_volume ; // Биржевой объем
>;

Для наших целей мы определили массив mrate[] , который будет использоваться для хранения этой информации .

Здесь мы устанавливаем индексацию как в таймсериях для всех массивов, которые будут использоваться нами. Это позволит нам быть уверенными в том, что скопированные массивы будут иметь нумерацию как в таймсериях (справа налево т.е. 0, 1, 2, 3 и т.д.). Это производится при помощи функции ArraySetAsSeries().

bool ArraySetAsSeries(
void array[] , // массив по ссылке
bool set // true означает обратный порядок индексации
);

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

Мы используем функцию SymbolInfoTick для получения текущих котировок. Эта функция имеет два аргумента — символ графика и структура типа MqlTick ( latest_price ). Снова, проверяем корректность выполнения функции и выводим сообщение в случае ошибки.

Затем, при помощи функции CopyRates мы копируем информацию последних трех баров в массив типа MqlRates. Функция CopyRates используется для получения исторических данных по указанному символу, периоду и запрашиваемому количеству данных, которые затем помещаются в массив типа MqlRates.

int CopyRates (
string symbol_name , // имя символа
ENUM_TIMEFRAMES timeframe , // период
int start_pos , // откуда начнем
int count , // количество данных для копирования
MqlRates rates_array[] // массив, куда будут скопированы данные
);

Имя символа и текущий таймфрей получаем используя предопределенные переменные _Symbol и _Period . Начиная с текущего бара Bar 0 , имеющего индекс 0, мы возьмем только три бара: Bars 0, 1, и 2. Результат будет помещен в наш массив mrate[].

Массив mrate[] теперь содержит все данные по ценам, времени, объемам и спредам для баров 0, 1 и 2. Поэтому для того, чтобы получить нужное свойство любого бара, мы используем выражение типа:

например, для каждого из этих баров:

mrate[1].time // время начала бара 1
mrate[1].open // цена открытия бара 1
mrate[0].high // наибольшая цена бара 0 (текущий бар), и т.д.

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

Далее, используя функцию CopyBuffer, мы копируем значения индикаторов в динамические массивы:

В качестве хэндла индикатора указывается хэндл, полученный в функции OnInit. Что касается номеров буферов индикатора, то индикатор ADX имеет 3 (три) буфера:

  • 0 — MAIN_LINE,
  • 1 — PLUSDI_LINE,
  • 2 — MINUSDI_LINE.

Индикатор The Moving Average имеет только 1 (один) буфер:

  • 0 – MAIN_LINE.

Начиная с текущего бара (0), мы копируем также еще два бара. Таким образом, полное количество баров равно 3 (бары 0-й,1-й и 2-й). Массив buffer[] в параметре функции CopyBuffer, это массив, куда будут помещены данные. В нашем случае это динамические массивы adxVal, plsDI, minDI и maVal.

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

Важно отметить, что функции CopyBuffer() and the CopyRates() возвращают общее количество скопированных данных или -1 в случае ошибки. Вот почему мы проверяем возвращаемые значения, они будут меньше 0 в случае ошибки.

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

Для того, чтобы реализовать это, сначала объявим две переменные типа boolean (Buy_opened и Sell_opened), которые будут установлены в TRUE в случае наличия соответствующих открытых позиций.

Для того, чтобы узнать наличие открытой позиции, мы использовали функцию PositionSelect, которая возвращает TRUE в случае наличия открытой позиции по указанному символу и FALSE при отсутствии открытой позиции.

В качестве основного аргумента функции передается наименование символа, наличие позиции по которому следует проверить. Здесь для имени символа мы использовали предопределенную переменную _Symbol.

В случае, если функция вернула TRUE (позиция существует), мы хотим проверить ее тип (покупка или продажа). Для этого мы используем функцию PositionGetInteger, она возвращает тип открытой позиции, в случае, если в качестве параметра задан запрос свойства POSITION_TYPE. В результате возвращается одно из значений перечисления ENUM_POSITION_PROPERTY_INTEGER: POSITION_TYPE_BUY или POSITION_TYPE_SELL.

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

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

После того, как это сделано, перейдем к следующему шагу.

Рассмотрим условия покупки.

Отметим, что выражения, приведенные выше, соответствуют стратегии, которая обсуждалась ранее. Мы объявили переменные типа bool для каждого из условий, которые должны быть выполнены перед установкой ордера. Переменные типа bool могут принимать только одно из значений: TRUE или FALSE.

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

Здесь мы проверяем значение скользящей средней MA-8 на барах 0, 1 и 2. Если значение MA-8 на текущем баре больше, чем на предыдущем (бар 1), и при этом значение MA-8 на баре 1 больше, чем на баре 2, это означает, что скользящая средняя MA-8 возрастает. Это одно из условий покупки.

Это выражение — проверка факта, является ли цена закрытия бара 1 (предыдущий завершенный бар) больше, чем значение скользящей средней MA-8 того же периода (периода бара 1). Если цена закрытия выше, значит второе наше условие выполняется. Если оба этих условий не выполнены, в принципе не имеет смысла проверять следующие.

Теперь мы хотим проверить, является ли значение ADX (ADX для бара 0), больше, чем минимальное значение, указанное во входных параметрах советника. Если это условие выполнено, это означает, что текущее значение ADX больше минимального необходимого, также нам нужно убедиться в том, что значение plusDI больше, чем minusDI. Это производится следующим выражением:

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

  • Поле action, являющееся типом торговой операции задается как TRADE_ACTION_DEAL, поскольку мы помещаем ордер в режиме немедленного исполнения. Для модификации ранее установленного отложенного ордера нужно указать TRADE_ACTION_MODIFY, для его удаления — TRADE_ACTION_REMOVE. Для цены открытия ордера мы используем значение поля Ask структуры latest_price. Значение цены Stop Loss получается вычистанием из цены Ask заданного значения StopLoss в пунктах. Цена Take Profit вычисляется прибавлением заданного значения TakeProfit в пунктах. Как видно, при указании цен мы использовали функцию NormalizeDouble, которая округляет числа до заданной точности — при отправке запроса на торговый сервер следует указывать нормализованные цены.
  • В поле symbol указывается текущий символ (_Symbol или Symbol()),
  • В поле type — тип ордера, здесь ORDER_TYPE_BUY. Для ордера на продажу нужно указать тип ORDER_TYPE_SELL.
  • В поле type_filling — тип исполнения ордера, значение ORDER_FILLING_FOK означает что сделка должна быть выполнена в указанном объеме по указанной (или лучше) цене. Если на рынке отсутствует возможность исполнить указанный объем, ордер не будет выполнен.

У функции OrderSend() два аргумента — переменные типа MqlTradeRequest и MqlTradeResult.

bool OrderSend (
MqlTradeRequest& request // структура запроса
MqlTradeResult& result // структура ответа
);

Как видно, мы использовали наши переменные mrequest и mresult в качестве аргументов функции OrderSend() .

После отправки ордера, мы теперь используем значение переменной mresult для проверки результата. Если наш ордер был успешно выполнен, нужно дать об этом знать, также в случае ошибки также нужно информировать о результате. Доступ к коду ошибки и номеру ордера можно получить, используя поля mresult.retcode и mresult,order соответственно.

Код возврата торгового сервера 10009 означает, что запрос OrderSend был успешно выполнен, а код 10008 показывает, что ордер помещен в очередь на исполнение. Поэтому мы должны проверить любой из этих вариантов — в таком случае мы уверены в том, что ордер был выполнен или помещен в очередь на исполнение.

Для проверки условий для продажи, мы производим проверку, противоположную той, которая была для покупки, за исключением того, что DI- должен быть больше, чем DI+ .

Точно так же, в разделе выше, мы объявили переменные типа bool для каждого из условий, которые должны удовлетворяться для помещения ордера на продажу. Поэтому торговая стратегия для продажи также состоит из четырех условий. Если условие выполняется, соответствующая переменная устанавливается в TRUE, иначе FALSE. Как и для случая с покупкой, рассмотрим их подробней.

Здесь мы проверяем значения MA-8 для баров 0, 1 и 2. Если значение MA-8 текущего бара (0) меньше, чем значение предыдущего бара 1, а также MA-8 для бара 1 меньше, чем значение для бара 2, это значит, что MA-8 падает. В этом случае одно условий для продажи удовлетворяется.

В этом выражении проверяется условие того, что цена закрытия меньше чем значение MA-8 соответствующего бара (бара 1). Если цена закрытия меньше значения скользящей средней, это значит второе условие удовлетворяется. Затем проверяются следующие условия.

Здесь проверяется условие того, что текущее значение ADX (бара 0) больше чем значение, указанное во входных параметрах советника. Также нужно проверить условие того, что значение MinusDI больше, чем plusDI. Это делается следующим образом:

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

Главное отличие в способе вычисления цен Stop Loss и Take Profit. Поскольку производится продажа, используется Bid цена, которая была получена ранее в структуру latest_price. Также здесь указан другой тип ордера — ORDER_TYPE_SELL.

Аналогично, мы используем функцию NormalizedDouble для цены ордера и цен StopLoss и TakeProfit — всегда нужно использовать нормализованные цены при отсылке запроса на торговый сервер.

Так же, как и для ордеров Buy, мы должны проверить результат торгового запроса. Мы используем тот же код, как и для случая покупки.

3. Отладка и тестирование советника

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

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

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

Рисунок 8. Настройка параметров отладки

Рисунок 8. Настройка параметров отладки

После появления окна «Параметры», выберите валютную пару, нужный период/таймфрейм и нажмите кнопку OK:

Рисунок 9. Установка параметров отладки

Рисунок 9. Установка параметров отладки

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

Для того, чтобы добавить точку останова, нужно перейти к строке, на которой нужно остановиться. В левой части редактора, рядом с границей редактора кода, нужно дважды кликнуть мышкой, при этом появится маленький голубой круг с белым квадратом внутри (рис. 10). Альтернативным вариант добавления точки останова — перейти на строку и нажать клавишу F9. Для того, чтобы убрать точку останова следует повторно нажать F9, либо дважды кликнуть по кругу.

Рисунок 10. Ставим точку останова

Рисунок 10. Ставим точку останова

В нашем коде мы собираемся установить точки останова на 5 различных строк кода.

Для удобства описания, они пронумерованы от 1 до 5.

Установим эти 5 точек останова на строки, указанные на рис. 11. Точку останова 1 мы установили ранее.

Рисунок 11. Установка дополнительных точек останова

Рисунок 11. Установка дополнительных точек останова

Мы закончили установку точек останова, теперь время начать отладку нашего кода.

Для начала запуска режима отладки, нажмите клавишу F5 или зеленкую кнопку в панели инструментов редактора MetaEditor:

Рисунок 12. Запуск отладчика

Рисунок 12. Запуск отладчика

Сначала редактор откомпилирует код, если при компиляции не возникло ошибок, он покажет их в отчете во вкладке «Ошибки»:

Рисунок 13. Отчет компиляции

Рисунок 13. Отчет компиляции

Имейте ввиду, что факт успешной компиляции не означает отсутствия ошибок в коде. В зависимости от того, как написан ваш код, могут возникать ошибки времени выполнения (runtime errors). Например, некоторые выражения могут компилироваться правильно, но работать неверно. Давайте лучше посмотрим режим отладки в работе.

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

Рисунок 14. Установка входных параметров советника для отладки

Рисунок 14. Установка входных параметров советника для отладки

В левом верхнем углу графика видно, что советник присоеден к графику.

При запуске функции OnTick(), произойдет остановка работы советника, он остановится в точку останова 1.

Рисунок 15. Режим отладки: остановка работы советника в первой точке останова

Рисунок 15. Режим отладки: остановка работы советника в первой точке останова

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

Перед тем, как продолжить, имеет смысл познакомиться с командами отладчика. Если посмотреть на панель инструментов редактора MetaEditor, можно увидеть, что теперь стали доступны три кнопки, которые ранее были серого цвета. Причина этого в том, что теперь мы находимся в режиме отладки. Эти три команды используются для исполнения в режиме отладки (Step into, Step over, Step out)»

Рисунок 16. Режим отладки: команда "Step into"

Рисунок 16. Режим отладки: команда «Step into» (Шаг с заходом)

Команда Step Into (Шаг с заходом) переходит к следующему шагу, при этом производится заход внутрь любой вызываемой функции в коде. Для исполнения данной команды, нажмите эту кнопку или клавишу F11. Далее мы будем использовать данную команду при пошаговой отладке нашего кода.

Рисунок 17. Режим отладки: команда "Step over"

Рисунок 17. Режим отладки: команда «Step over» (Шаг с обходом)

Команда Step over (Шаг с обходом), в свою очередь, не производит заход отладчика в функции, которые вызываются в коде. Для исполнения данной команды нужно нажать эту кнопку или клавишу F10.

Рисунок 18. Режим отладки: команда "Step out"

Рисунок 18. Режим отладки: команда «Step out» (Шаг наружу)

Для перехода к выполнению одного шага программы на один уровень выше есть команда Step Out (Шаг наружу), которая вызывается нажатием на соответствующую кнопку или комбинацией клавиш Shift+F11.

В нижней части редактора, вы видите окно «Инструменты»(Toolbox). Вкладка «Отладка» содержит следующие колонки:

  • Файл : Имя файла, с которым производится работа.
  • Функция : Имя функции, которая вызывается в настоящий момент.
  • Строка : Номер строки кода.
  • Выражение : В этой колонке вы можете указать любое выражение или переменную, за значениями которых вы желаете наблюдать в процессе выполнения программы.
  • Значение : В этой колонке показываются текущие значения указанных выражений/переменных.
  • Тип : В данной колонке показан тип данных, для которых установлен режим наблюдения.

Вернемся к процессу отладки.

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

  • Old_Time (старое время бара)
  • New_Time[0] (время текущего бара)
  • copied (количество скопированных данных времени)
  • IsNewBar (флаг, показывающий появление нового бара)
  • Mybars (полное количество баров в истории) – наш советник использует это значение

Также можно добавить в мониторинг и другие переменные, например значения технических индикаторов ADX, MA-8 и т.д.

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

Рисунок 19. Монитор выражений

Рисунок 19. Монитор выражений

Укажите переменные/выражения для наблюдения:

Рисунок 20. Добавление выражений или переменных для наблюдения

Рисунок 20. Добавление выражений или переменных для наблюдения

Рисунок 21. Конманда "Step into" (Шаг с заходом) в действии

Рисунок 21. Конманда «Step into» (Шаг с заходом) в действии

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

Рисунок 22. Наблюдение за выражениями или переменными

Рисунок 22. Наблюдение за выражениями или переменными

Рисунок 23. Наблюдение за выражениями или переменными

Рисунок 23. Наблюдение за выражениями или переменными

Рисунок 24. Наблюдение за выражениями или переменными

Рисунок 24. Наблюдение за выражениями или переменными

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

Рисунок 25. Значения переменных при новом вызове функции OnTick

Рисунок 25. Значения переменных при новом вызове функции OnTick

Теперь запустим программу снова, на этот раз без точек останова.

Рисунок 26. В режиме отладки при новом баре советник выводит сообщение

Рисунок 26. В режиме отладки при новом баре советник выводит сообщение

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

Рисунок 27. Торговля советника

Рисунок 27. Торговля советника

Я думаю, можно оставить советник поработать еще несколько минут и попить кофе. Вернувшись обратно и сделав немного денег (шутка), нажмите красную кнопку Stop в MetaEditor для остановки процесса отладки.

Рисунок 25. Остановка режима отладки

Рисунок 28. Остановка режима отладки

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

3.2 Тестируем стратегию нашего советника

Теперь мы хотим проверить нашего советника используя встроенный Тестер стратегий клиентского терминала. Для запуска Тестера Стратегий нажмите клавишу Ctrl-R или выберите пункт «Тестер стратегий» в меню «Вид» главного меню, как показано на рисунке 26:

Рисунок 25. Запуск Тестера стратегий

Рисунок 29. Запуск Тестера стратегий

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

Рисунок 27. Окно Тестера стратегий

Рисунок 30. Окно Тестера стратегий

Указатель мыши изменит свой вид, превратившись в двойные стрелки, удерживая мышь, нужно увеличить окно Тестера до высоты, при которой все его настройки видны.

Рисунок 28. Вкладка "Настройки" Тестера

Рисунок 31. Вкладка «Настройки» Тестера

  1. Выберите советника, который нужно протестировать.
  2. Выбор валютной пары для тестирования.
  3. Выбор периода/таймфрейма для тестирования (выберем H2).
  4. Выберите «Select Custom» чтобы производить тестирование на указанном историческом интервале.
  5. Выбор дат начала и окончания тестирования.
  6. Выберем режим торговли «Обычный».
  7. Выбор начального депозита для тестирования.
  8. Не будем использовать оптимизицию параметров советника (Отключена)
  9. Нажмите кнопку «Старт», когда будете готовы начать тестирование.

Перед тем, как нажать кнопку «Старт», посмотрим на другие вкладки Тестера.

Вкладка «Агенты»

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

Рисунок 29. Вкладка "Агенты" Тестера стратегий.

Рисунок 32. Вкладка «Агенты» Тестера стратегий

Для одного агента в процессе тестирования вкладка «Агенты» имеет вид:

Рисунок 30. Агенты Тестера стратегий в процессе тестирования

Рисунок 33. Агенты Тестера стратегий в процессе тестирования

Вкладка «Журнал»

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

Рисунок 31. Вкладка "Журнал" Тестера стратегий показывает активность советника при тестировании

Рисунок 34. Вкладка «Журнал» Тестера стратегий показывает активность советника при тестировании

Вкладка «Входные параметры»

Здесь можно указать входные параметры советника.

Рисунок 32. Вкладка "Входные параметры" советника в Тестере стратегий

Рисунок 35. Вкладка «Входные параметры» советника в Тестере стратегий

Если используется оптимизация параметров при тестировании, нужно указать значения переменных, выделенных на рис. 31.

  • Старт — начальное значение параметра
  • Шаг — шаг изменения параметра
  • Стоп — конечное значение параметра для тестера.

Тем не менее, в нашем советнике мы не будем производить поиск оптимальных параметров, поэтому нам они не нужны.

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

Вкладка «График»

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

Рисунок 33. График результатов тестирования

Рисунок 36. График результатов тестирования

После завершения тестирования появится другая вкладка, называемая «Результаты» тестирования. Переключившись во вкладку результаты, вы увидите отчет о проведенном тестировании.

Рисунок 34. Отчет результатов Тестера стратегий

Рисунок 37. Отчет результатов Тестера стратегий

Видны чистая прибыль, общая прибыль, общее количество сделок, кол-во убыточных сделок и другие.

Нажав правую кнопку мыши во вкладке «Результаты», вы увидите контектное меню. Выберите пункт «Сохранить как отчет«:

Рисунок 35. Сохранение результатов тестирования

Рисунок 38. Сохранение результатов тестирования

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

Для того, чтобы увидеть результаты торговли на графике, выберите пункт «Открыть график» и увидите график вида:

Рисунок 36. График с результатами тестирования на истории

Рисунок 39. График с результатами тестирования на истории

Мы успешно написали и протестировали наш советник на истории и теперь имеем заготовку для дальнейшей работы. Можно опять вернуться во вкладку «Настройки» Тестера стратегий и протестировать его на другом временном интервале.

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

Выводы

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

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

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

Как правильно написать советник (индикатор) на MQL4? А также как отладить и протестировать его своими руками?

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

MQL4 индикатор

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

ЛУЧШИЕ БРОКЕРЫ ОПЦИОНОВ КОТОРЫХ ВЫБРАЛИ ВЫ!

Нет верификации. Работаю с ними в + с 2019 года. Рекомендую также ознакомиться с => ЭТОЙ СТРАТЕГИЕЙ, по ней я вывожу хорошие $$ деньги. | СТАРТ С 500 ₽ | обзор | отзывы Мой любимый брокер! Тут 5 видов контрактов! | обзор | отзывы | => НАЧАТЬ С 1 USD

FOREX БРОКЕРЫ С ЛУЧШИМИ ТОРГОВЫМИ УСЛОВИЯМИ:

Советы опытных программистов: как написать собственный индикатор на MQL4?

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

создать индикатор

Новичкам проще всего будет выбрать один из двух путей:

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

Опытные программисты при написании советника или индикатора, советуют новичкам обратить внимание на следующие моменты:

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

собственный советник MQL4

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

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

Как отладить и протестировать советник на MQL4 созданный своими руками?

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

Следом за ним идет продолжительный процесс отладки и тестирование на предмет наличия всевозможных ошибок. Осложняется все тем, что платформа MetaTrader4 не содержит встроенный отладчик.

советы по созданию MQL4

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

ЛУЧШИЕ ФОРЕКС БРОКЕРЫ ПО ДАННЫМ «ИНТЕРФАКС»

Топовый ECN брокер, работает более 20 лет! Сейчас дополнительно получаю доход от их акции кэшбэка ==>>> CASHBASK ОТ АЛЬПАРИ | обзор / отзывы 2010 год. Сертифицирован ЦРОФР! | МАКСИМАЛЬНЫЙ БОНУС | обзор / отзывы Проверенный забугорный брокер | НАЧАТЬ С 10USD | обзор / отзывы Входит в ТОП 3 ведущих рейтингов Форекс брокеров. Отлично подходит для России | МАКСИМАЛЬНЫЙ 1500$ БОНУС | обзор / отзывы

А ТАКЖЕ ЛУЧШИЕ БРОКЕРЫ БИНАРНЫХ ОПЦИОНОВ В 2021:

У этого брокера опционов лучшая репутация в сети! | СТАРТ С 10$ | обзор / отзывы Новые фиксированные опционы. Такие одни! | СТАРТ С 1$ | обзор / отзывы

2 способа: как легко создать советник на MQL4 по зигзагу или на основе других индикаторов?

Есть два способа облегчить задачу по созданию автоматических советников, которые можно использовать совместно:

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

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

создание советника на MQL4

Во-вторых, к созданию советников можно привлечь сторонние приложения, являющиеся аналогами “мастеров настройки” в операционных системах Windows и MacOS.

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

Как облегчить задачу начинающему трейдеру по написанию собственных индикаторов на MQL4?

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

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

Создание простого советника на MQL4

ТОП БРОКЕРОВ ОПЦИОНОВ, ПРИЗНАННЫХ НЕЗАВИСИМЫМИ РЕЙТИНГАМИ

Стабильные АВТОМАТИЧЕСКИЕ выплаты! | обзор | отзывы | НАЧАТЬ С 500 Р. Старт с 10$. Тут полностью авторская платформа | обзор | отзывы | САЙТ БРОКЕРА Фиксированные опционы от ПАО Alpari | обзор | отзывы | НАЧАТЬ С 1 USD

ТОП ФОРЕКС БРОКЕРОВ РОССИЙСКОГО РЕЙТИНГА НА 2021 ГОД:

Что говорят трейдеры об АМаркетс? КОПИРОВАТЬ СДЕЛКИ | обзор/отзывы ForexCopy/ПАММ/Криптовалюты/Опционы =>СТРАТЕГИИ КОПИРОВАТЬ СДЕЛКИ | обзор/отзывы Имею тут счет в 1050$. Платит с 1998 года! | ВСЕ АКЦИИ И КОНКУРСЫ | обзор/отзывы

Как написать торгового робота: инструкция для новичков

Владислав Миронов

Торговый робот (или бот) – это специальный алгоритм, который может сделать вашу торговлю на Форекс или других финансовых рынках проще.

Торговые советники на Форекс имеют массу преимуществ:

дисциплина и отсутствие эмоций;

точное выполнение торгового плана;

не устает, готов работать 24/7;

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

он может быть оптимизирован по результатам торговли на истории (бэктестинг);

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

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

Capital.com

Что такое торговый робот?

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

в каком случае открывать позицию (покупать / продавать);

в каком случае корректировать / закрывать позицию;

какого размера позиция.

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

сигналы индикаторов и осцилляторов (объемы, RSI, MACD)

уровни поддержки и сопротивления

данные о позициях трейдеров

статистика другого рода

Ниже – фрагмент торгового робота, код написан на языке С#.

Пример кода торгового робота

Пример кода торгового робота

Этот робот открывает позицию лонг, если быстрая SMA пересекает медленную SMA вверх. Когда быстрая SMA пересекает медленную SMA вниз, робот закрывает лонг и открывает позицию шорт.

Как создать торгового робота для биржи

Следует начать с поиска идей. Например:

вы заметили, что рынок часто совершает ложные пробои круглых уровней;

вы обнаружили зависимости во взаимодействии цены и объемов торгов;

вы прочитали в книге описание торговой стратегии.

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

Как написать код для торгового робота

Выбор простой – доступно 3 варианта:

Вариант 1. Обратиться к специалисту

Программистов, готовых написать торгового робота, можно найти на MQL5, сайтах фрилансеров.

идея будет реализована быстро,

вы можете выбрать исполнителя.

Вариант 2. Написать код самому

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

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

Вам не нужно делиться ни с кем своей идеей.

Вы будете точно знать устройство робота, и сможете понять, почему он работает так, а не иначе.

Вариант 3. Сгенерировать код

Например, терминал Metatrader 4 настолько популярен, что в интернете есть специальные сайты, где можно сгенерировать простых торговых роботов в формате ex4 специально под MT4.

Вот, например, несколько находок из топа Гугла (мы не несем ответственности за содержание сторонних сайтов):

Создание торгового робота онлайн бесплатно

Создание торгового робота онлайн бесплатно

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

Добавить стратегию управления капиталом

Экспортировать торгового робота в файл

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

бесплатно, если иное не предусмотрено в конструкторе

Тестирование на истории и оптимизация

Хорошо, вы получили робота по одному из 3 вариантов описанных выше, что дальше?

Далее нужно провести тестирование (backtesting) и оптимизацию параметров.

Тестирование – это прогон робота на истории. То есть вы берете данные за, скажем, 2017-2019 год и смотрите, какие сделки бы совершил бы робот по заложенным в него правилам в этом периоде из прошлого. Далее данные по сделкам обрабатываются и предоставляются в форме отчета, где видно:

сколько совершено сделок;

сколько робот заработал / потерял;

какие отношения заработка к потерям;

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

Вот ↓ как это выглядит в форекс терминале Metatrader 4.

Панель тестирования в МТ4

Панель тестирования в МТ4

Чтобы открыть панель Тестирования, нажмите Ctrl+T.

Выбираете робота, которого собираетесь тестировать. Файл робота в формате ex4 должен находиться в папке MQL4Experts. В примере мы выбрали робота, торгующего по скользящим средним. Он идет в комплекте с терминалом МТ4.

Выбираете торговую пару, по которой будете производить тестирование. Например, EURUSD.

Выбираете точность тестирования (чем точнее, тем дольше по времени будет длиться тестирование).

Период тестирования. Чем больше исторических данных будет обработано, тем достоверней будет результат.

Задаете величину спреда (разница между ценой покупки и продажи). Current значит, что значение спреда подгрузится автоматически.

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

На вкладке Results будут показываться сделки, которые заключает робот во время тестирования.

В результате, если вы все сделаете правильно, с большой вероятностью вы получите такую ↓ картину на вкладке Graph:

Пример тестирования торгового робота

Пример тестирования торгового робота

Она означает, что торговый робот медленно сливает депозит, потому что:

математическая вероятность получения прибыли = 50/50;

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

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

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

Результаты робота

На вкладке Report вы получите больше детальной информации.

информация о тестировании

информация о тестировании

На примере выше отчет гласит, что:

Точность тестирования = 99,9%, а ошибок тестирования = 0. Это высокая достоверность, её можно добиться за счет качественной базы данных по ценам.

Совершив 9395 сделок, роботу удалось разогнать начальные 20 тысяч долларов до 1,1 миллиона в срок с февраля 2019 года по сентябрь 2022 года.

Относительная просадка = 40% конечно высока. И в реальных условиях она серьезно потрепала бы вам нервы.

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

Совет. Проводите оптимизацию так, чтобы находить параметры на одном периоде (например, на данных за 2015-2018 года), а тестировать их на другом (на 2019-2022). Это называется forward testing.

Мнение эксперта. Какие бы вы не проводили тестирования, на них нельзя полагаться на 100%. Дело в том, что вы не сможете смоделировать реальные условия полностью и учесть проскальзывания, изменяющиеся спреды. Большой проблемой является детализация данных внутри одной минуты, это самый маленький таймфрейм в среде Metatrader. Но от того, как меняется цена внутри минуты, может зависеть, закроется ли сделка по тейку или по стопу. На самом деле МТ4 упрощает то, что происходит внутри минуты, чтобы оптимизировать базу данных и терминал работал быстрее.

Таймфрейм тестирования

Но для профессионала важно достигать максимальной точности, поэтому он покупает тиковые базы данных большого размера за почти 20 лет, которые вам не предоставит ваш брокер, скорее всего. “Сглаженные” исторические данные от вашего брокера могут быть причиной того, что на истории робот показывает прибыль, а в реальном времени – терпит убытки.

Тестирование на демо

Когда ваш робот прошел тщательное тестирование и оптимизацию, не спешите ставить на реал.

Попробуйте вначале демо. Хотя бы несколько месяцев, чтобы торговый бот на форекс смог “пережить” несколько важных новостей. При этом вы также проверите:

Качество вашего оборудования и соединения с интернетом. Не будут ли они мешать роботу работать так, как вы этого задумываете. Чтобы минимизировать влияние этого фактора, желательно будет использовать услугу VPS.

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

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

Допустим, торговый робот работал на демо в реальном времени с 1 января по 1 мая, провел 40 сделок, увеличил депозит на 7.45% с просадкой 6%.

Теперь прогоните робота на историческом тесте, используя данные за эти 4 месяца. Вы увидите, что результаты отличаются. Как так? Один и тот же робот / рынок / период, все идентично, но результаты с демо и бектестинга с большой вероятностью будут отличаться? Да, это нормально. Главное, проверьте, не критично ли это отличие. Если отличия слишком большие, найдите причину. Важно, чтобы отличия были минимальны, тогда ваши результаты тестирования на истории за предыдущие годы можно считать достоверными.

Запуск на реальный счет

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

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

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

Далее смотрите, отклоняются ли результаты на реальном счете от результатов, полученных на демо-счете и на истории. Возможно, вы получите такую ↓ ситуацию:

сравнение результатов на демо-счете и на реальном счете

сравнение результатов на демо-счете и на реальном счете

2 счета – демо и реал от одного уважаемого брокера – работают параллельно. Но на демо – прибыль, а на реале – убыток, хотя и там и там все идентично.

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

Сколько можно заработать?

Будьте реалистами, не питайте иллюзий, что простая стратегия сможет вас обогатить. Вот данные с авторитетного сайта, где продаются разработанные специалистами стратегии для управления активами на фондовом рынке. В колонке Performance указана доходность – разброс от 6% до 18% в год. Это то, что реально.

Прибыльность робота

Может ли ваш робот на долгосроке превосходить такую доходность, демонстрируя при этом просадку не более 20%?

Отлично. Вы можете подумать о том, как:

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

строить долгосрочный финансовый план,

Частый вопрос – Может ли торговый робот работать на полном автомате?

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

Ошибки алготрейдеров

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

Недооценивают мысль: “Прошлые результаты не гарантируют прибыльность в будущем”

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

Подвергают свой капитал риску, запуская роботов по непредсказуемым “секретным” стратегиям. Это так называемые “черные ящики”.

Слишком оптимизируют роботов, тем самым просто “подгоняют” настройки.

Работают с брокерами на счетах, которые не рассчитаны для алгоритмической торговли.

Увлекаются роботами-скальперами для быстрой прибыли.

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

Одна распространенная ошибка – использование мартингейла – заслуживает отдельных абзацев. Помните захватывающую картинку выше, где робот разгоняет $20к до $1,1м за 2,5 года? Это мартингейл.

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

У мартингейла есть два минуса:

такому роботу нужен большой стартовый депозит, чтобы иметь достаточно ликвидности на случай, если полоса неудачных сделок затянется;

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

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

Выводы

Трейдинг на бирже не приносит легкие деньги. Алготрейдинг – не исключение.

Чем больше кажущаяся прибыль – тем выше на самом деле риски.

Чтобы ваш опыт с разработкой торговых роботов для форекс принес больше ценности, чем разочарований – стройте свою работу на основе информации, представленной выше. Статья написана с учетом рекомендаций профессиональных алготрейдеров, сотрудничающих с МОФТ.

Статьи по теме

CFD трейдинг — Коммодитис, Криптовалюты, Индексы. Какие типы CFD выбрать для трейдинга? - Исследование МОФТ

Лучшая криптовалюта для инвестиций в 2022 году - Аналитика МОФТ

Кто такой брокер: основные виды брокеров и правила работы с ними

Лучшие стратегии Форекс: какую стратегию выбрать для успешной торговли? - Исследование МОФТ

Скальпинг от «А» до «Я» для начинающих инвесторов

Торговля CFD (контрактом на разницу цен) - определение, варианты использования и риски

Как получить рибейт (кэшбэк) за трейдинг

Сотрудничество с МОФТ дает вам преимущество перед другими трейдерами. Ведь наши клиенты получают частичный возврат уплаченных комиссий (спреда) за трейдинг вне зависимости от того, была ли сделка прибыльной или убыточной. Таким образом вы можете получить компенсацию в размере до 100% размера спреда.

Как такое возможно?
МОФТ получает частичный возврат спреда от брокеров, поскольку у МОФТ установлены партнерские отношения с многими ведущими форекс-брокерами и криптовалютными биржами мира. Брокеры за счет возврата части комиссий привлекают новых клиентов и стимулируют их торговать активнее.

Что нужно сделать для получения рибейта?

Выберите брокера или нескольких из рейтинга на нашем сайте

Откройте счет и внесите депозит

В личном кабинете на МОФТ внести номер торгового счета в раздел Счета

Получайте компенсацию за все сделки

Калькулятор размера рибейта и подробное описание программы доступны по ссылке

Могу ли я написать торгового робота?

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

Можно ли использовать робота у моего брокера?

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

Торговый робот гарантирует прибыль?

Нет. Даже самый лучший трейдинг-бот не обеспечит вам 100% гарантию получения прибыли. Поэтому контролируйте сделки.

Я не умею писать код самостоятельно. Можно ли его сгенерировать?

Да. Существуют сервисы, которые автоматически генерируют код для MetaTrader 4 или MetaTrader 5.

Источник https://www.mql5.com/ru/articles/100

Источник https://infofx.ru/trejding/kak-pravilno-napisat-sovetnik-indikator-na-mql4-a-takzhe-kak-otladit-i-protestirovat-ego-svoimi-rukami/

Источник https://tradersunion.com/ru/interesting-articles/how-to-write-a-trading-robot/

Источник

Оставить комментарий

Ваш email нигде не будет показан.