Урок №12: Пишем советник по индикатору
На прошлом уроке мы с вами писали индикатор, который указывает входы в рынок. Соответственно сегодня мы займёмся разработкой эксперта, использующего его сигналы.
Начнём с создания шаблона советника(как это сделать мы разбирали на уроке №10).
Опишем входные параметры эксперта:
Значения StopLoss, TakeProfit и Slippage, присвоенные в параметрах, указаны для 4-х значного брокера, соответственно, чтобы эти же значения корректно работали у 5-ти значного ДЦ их нужно умножить на 10, что мы и сделаем в функции OnInit:
Начало нашего советника положено, что уже хорошо. Давайте теперь рассмотрим входные параметры индикатора, а заодно и номера буферов для сигналов:
Обычно я просто копирую параметры индикатора в код своего эксперта, в дальнейшем это позволит нам оптимизировать сам советник. В итоге получаем:
Переходим к функции OnTick и пишем заготовку обработчика, где описываю алгоритм работы эксперта:
- if (CountBuy() == 0) — я проверяю есть-ли у меня ордера на покупку, находящиеся в рынке, и если нет, то шаг 2.
- BuySignal = … — проверяем наличие сигнала на покупку по индикатору, кстати, это будет переменная, которую необходимо объявить заранее.
- if (BuySignal > 0) — если есть сигнал на покупку, то переходим к шагу 4.
- CloseSell() — закрываем открытые ордера на продажу, если они есть и переходим к шагу 5.
- Открываем ордер на покупку.
Точно такой же блок делается и для продаж.
Исходя из написанного алгоритма сразу видно, что предварительно нам потребуется несколько функций: CountBuy(), CountSell(), CloseBuy(), CloseSell(), а также написать код получения сигнала с индикатора.
Объявим в коде несколько переменных для дальнейшей работы и необходимые функции:
Функция CountBuy():
Аналогично пишется функция CountSell(), разве что проверяется тип ордера OP_SELL:
Далее пишем функцию CloseBuy():
Пишем практически всё то же самое и для закрытия ордеров на продажу, разница лишь в типе проверяемого ордера и цене закрытия, функция CloseSell():
На текущий момент нам осталось получить сигналы от индикаторы и написать код, открывающий ордера по его сигналам.
Для получения сигнала от любого пользовательского индикатора используется функция iCustom, обратившись к справке (F1) видим формат вызова функции:
Теперь мы можем с легкостью получить сигнал на покупку в нашем советнике:
заодно и сигнал на продажу:
кстати, обратите внимание на предпоследний параметр mode, который мы передаём в функцию iCustom — это номер буфера индикатора, где хранятся сигналы покупок и продаж.
Таким образом наша функция OnTick() будет выглядеть следующим образом:
Собственно говоря, на этом всё, разработка советника на пользовательском индикаторе завершена.
Источник
Урок №10: Наш первый советник
Уважаемые коллеги, на этом уроке мы напишем наш первый советник, познакомимся с некоторыми основными функциями языка MQL4, а также напишем несколько своих.
Приступим, и для начала запустим MetaEditor…
и создадим шаблон эксперта, ничего не меняя, просто нажимаем кнопку «Далее»…
Обязательно заполняем, как минимум, поле «Имя» — это название нашего будущего советника, поля «Автор» и «Ссылка» не обязательны к заполнению. Добавляем параметры «Lots», «TakeProfit», «StopLoss», обращая внимание тип данных каждого параметра. После заполнения нажимаем кнопку «Далее»:
На следующей форме мастера мы также ничего не отмечаем, просто нажимаем кнопку «Далее»:
И очередное окно мы оставляем без заполнения, нажимаем кнопку «Готово»:
Итак, мы получили шаблон будущего эксперта, с которым будем работать.
Итак, мы предусмотрим наш будущий советник для работы с 4-х и 5-значным брокером и тут два варианта как это реализовать. Можно заменить вид параметра «input» на «extern» для того, чтобы можно было из кода советника модифицировать эти значения (значения с видом параметра «input» изменять в коде эксперта нельзя!)
или добавить глобальные переменные «TP» и «SL», в которые скопируем значения «TakeProfit» и «StopLoss» и работать уже с ними.
Я выбираю первый вариант, т.е. меняю «input» на «extern«.
Далее в функции «OnInit» добавляю следующий код:
Поясняю:
Функция Digits в озвращает количество десятичных знаков после запятой, определяющее точность измерения цены символа текущего графика, таким образом:
- Я проверяю количество знаков после запятой у текущей валютной пары и если количество знаков равно 3 или равно 5, то делаю вывод, что мой брокер работает с пятизначными котировками.
- Следующим шагом я умножаю TakeProfit и StopLoss на 10. Запись «TakeProfit *= 10;» эквивалентна записи «TakeProfit = TakeProfit * 10;«
Теперь нужно определиться как мы будем открывать позиции, в какую сторону и в какой момент? Покупать или продавать?
Осмелюсь предложить воспользоваться для этих целей индикатором «MovingAverage» и у нас будет следующий алгоритм:
- Если текущая цена будет выше, чем значение индикатора, то будем покупать.
- Если текущая цена будет ниже, чем значение индикатора, то будем продавать.
- Закрытие позиций будет происходить либо по TakeProfit, либо по StopLoss.
Язык программирования MQL4 предоставляет нам ряд функций для работы с индикаторами, и как раз одна из них позволяет получить нам текущее значения индикатора:
Итак, у нас есть функция iMA, из справочника(вызывается по клавише «F1») нам известны её параметры, часть из которых я сразу же переношу во внешние параметры советника для последующей оптимизации параметров самого индикатора:
Обратите внимание на то, что я заменил тип «int» у двух параметров на перечисления «ENUM_MA_METHOD» и «ENUM_APPLIED_PRICE». Сделал я это для удобства восприятия самих параметров, согласитесь, что прочитать, к примеру, у параметра ma_method значение «MODE_SMA» гораздо понятней, чем наблюдать простое число. Кроме того я заранее добавил ещё один параметр «Magic». Он нам понадобится для открытия ордера.
Теперь переходим к функции «OnTick»(она выполняется каждый раз при поступлении новой котировки по валютной паре) и получим значение индикатора MovingAverage:
Мы объявляем переменную «ma» и записываем в неё значение функции «iMA» с заданными параметрами, значения которых определены в параметрах самого эксперта.
Также нам понадобится несколько функций:
- Функция подсчёта количества количества ордеров на покупку.
- Функция подсчёта количества количества ордеров на продажу.
Добавим их в код советника:
Отлично, теперь разберём каждую строчку функции «CountBuy()«:
Точно аналогичное описание применимо и для функции «CountSell()«. Тут всё тоже самое, кроме одного условия:
т.е. проверяется тип ордера «на продажу».
Далее вносим следующие дополнения в тело функции «OnTick()»:
т.е. мы объявили переменные ticket, sl, tp для дальнейшей работы с ними, а также добавили код для открытия ордера на покупку.
Теперь дополним блоком для открытия ордера на продажу, я обычно копирую уже написанный код для покупок и меняю условия и параметры функций зеркально для продаж:
На этом, пожалуй, всё. Простейший советник написан, остаётся его скомпилировать и обратить внимание на журнал ошибок:
Ну и конечно же его стоит протестировать, поэтому запускаем терминал и открываем форму тестера стратегий:
После компиляции наш первый советник в окне «Навигатор» и доступен для тестирования на форме тестера стратегий.
Выбираем параметры запуска, т.е. указываем, что тестировать будем советник «First_Expert.ex4», а также валютную пару и период:
Нажимаем кнопку «Старт» и смотрим результат:
На вкладке «График» тестера стратегий можно посмотреть график баланса.
Ну что-ж, для первого раза вполне неплохо, на этом наш урок закончен.
По ссылке доступен для скачивания полный код нашего с вами советника First_Expert.
Источник
MQL4: Пишем советник по торговле заданных паттернов
Всем привет!
Наверняка многие из вас часто замечали, что периодически графики той или иной валютной пары повторяют свои движения. На самом деле, в большинстве случаев – это всего лишь временное явление, на котором не получится сделать достаточно много денег. Но что, если есть такие надежные ценовые движения и закономерности, о которых мы и не догадываемся? Сегодня мы напишем довольно простой советник, который поможет нам с исследованиями рынка.
Что будем писать?
В основе любого исследования всегда лежит определенная гипотеза. Сначала мы выдвигаем ее, а потом уже доказываем или опровергаем.
Сегодня мы напишем простой советник, который будет работать на дневных графиках. В основе формирования входа будет лежать некий свечной паттерн с привязкой ко дню недели. Гипотеза наша заключается в следующем: если мы видим одну медвежью свечу, а затем бычью, скажем, в среду, то в четверг свеча тоже будет бычьей. Если мы видим бычью свечу, а затем медвежью, то следующий день закроется еще ниже. Проиллюстрирую это на картинке:
Как видите, паттерн очень простой, и маловероятно, что он действительно работает. Тем не менее, на рынке действительно присутствуют подобные аномалии, на которых можно спокойно из года в год зарабатывать пусть и небольшие, но все же реальные деньги.
Конструкция нашего советника
Советник будет очень простым. Он будет сверять текущий день недели с днями, в которые торговля разрешена. Затем он проверит, нет ли сейчас открытых ордеров. После этого сверится, присутствует ли заданный паттерн, и в случае его обнаружения откроет сделку. Закрытие позиции будет произведено на следующий день.
Поэтому разделим тело советника на несколько частей. Первая часть – фильтр дня недели:
Он будет возвращать false, если текущий день недели запрещен в настройках. Второй блок генерирует сигнал:
if (!TimeFilter()) return -5;
double Close1 = iClose(_Symbol, signal_period, 1);
double Open1 = iOpen(_Symbol, signal_period, 1);
double Close2 = iClose(_Symbol, signal_period, 2);
double Open2 = iOpen(_Symbol, signal_period, 2);
if (Close2 > Open2 && Close1 Open1) <
Как видите, мы просто ищем нужный нам паттерн. И этот метод вы можете переписать под поиск любого паттерна.
Дальше осталось только написать метод для открытия и закрытия позиции. И метод, сигнализирующий о том, что текущая позиция уже открыта 1 бар, и ее пора закрывать:
bool ExitTime(int dir)<
for (int i = OrdersTotal(); i >= 0; i—) <
if (OrderSymbol() != Symbol() || OrderMagicNumber() != magic) <
if (TimeCurrent() – OrderOpenTime() > 60 * exit_bars * exit_period) <
Вот, собственно, и все. Полный код советника вы можете увидеть в видеоуроке.
Результаты
Как я уже говорил, советник, как и сам паттерн, – очень простой. Но на рынках «просто» – не всегда означает плохо и не прибыльно. Даже такие простые вещи, к нашему удивлению, могут оказаться рабочими, за что мне и нравится этот рынок. Это рынок умопомрачительных контрастов. В то время как ручные трейдеры торгуют вслепую вообще, без какого-либо подтверждения статистической значимости своих систем, новички вкладывают последние деньги в сетки и мартины, алготрейдеры изобретают все более изощренных скальперов с количеством строк кода, дающим фору «Войне и миру», порой очень простые, но прибыльные вещи лежат на поверхности, но их никто не видит. В этом есть какая-то очень изощренная ирония, не находите?
Результаты не блещут, конечно, но паттерн был взят наобум, и он крайне прост. Я уверен, что если немного подкорректировать его, – то можно добиться лучших результатов.
Заключение
Идея паттерна с двумя свечами противоположных цветов и настроенного на продолжение движения – очень простой пример. Тут не учитывается ни форма, ни волатильность, ни отношение размера теней к размеру самого тела свечи. Вы же можете придумать свои паттерны и протестировать их, – как знать, может быть, вы найдете действительно ценные и очень прибыльные возможности.
Источник