MQL для чайников, программирование на MQL4, MQL5
22 Янв
Сегодня разберемся, как работать в языке MQL4 с внешними индикаторами. Невозможно встроить все индикаторы форекс в терминал Metatrader. Постоянно появляются новые индикаторы Forex и усовершенствуються старые индикаторы. Поэтому разработчики терминала Metatrader4 позаботились о работе с внешними индикаторами в языке MQL.
Рассмотрим например индикатор форекс "ZigZag":
Он не встроен в терминал MT4, хотя и поставляется вместе с ним. Если взглянуть на график валютной пары, то прекрасно видно преимущества данного индикатора Forex.
Было бы здорово, если бы трейдер покупал внизу и продавать вверху точек излома индикатора ZigZagа. Стратегию я такую не нашел. Поэтому просто проверю — действительно это так или нет. Но для начала необходимо сформулировать условия торговли: — покупаем когда ZigZag рисует линию вниз. — продаем когда ZigZag рисует линию вверх. — окончание линии ZigZagа анализируем при открытии следующей свечи — стоп-лосс ставим на 5 пунктов вниз или вверх от экстремума ZigZagа — тейк-профит ставим в 5 раз больше величины стоп-лосса — при образовании нового фрактала, стоп-лосс переносим вслед за ценой
Правила сформулировали, теперь можно заняться созданием советника форекс для Metatrader 4 на языке MQL4.
Создаем новый советник — назовем его "expert3".
Переносить наши функции теперь не надо, достаточно подключить нашу библиотеку «MyLib».
Добавим новые параметры для индикатора форекс ZigZag:
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
Вот что у нас получится:
//±-----------------------------------------------------------------+
//| expert3.mq4 |
//| Copyright c 2010, MQL для тебя. |
//| http://mql4you.ru |
//±-----------------------------------------------------------------+
#property copyright "Copyright c 2010, MQL для тебя."
#property link "http://mql4you.ru"
#include <MyLib.mqh>
extern int MaxRisk=2;
extern int TakeProfit=5;
extern int StopLoss=5;
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
datetime Today=0;
//±-----------------------------------------------------------------+
int init() {return(0);}
//±-----------------------------------------------------------------+
int deinit() {return(0);}
//±-----------------------------------------------------------------+
int start()
{if(DayOfWeek()==0 || DayOfWeek()==6) return(0); // в выходные не работаем
if(!IsTradeAllowed()) return(0); // пропустим тик если терминал занят
//:проверим открытие новой свечи
if(Time[0]==Today) return(0);
Today=Time[0];
//:получим значение ZigZag на предыдущей свече
double lZZ=iCustom(NULL,0,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep,0,1);
return(0);}
//±-----------------------------------------------------------------+
С помощью функции iCustom() можно получить значение из внешнего индикатора. Хорошо скажите Вы. А откуда мы знаем, какие параметры и сколько буферов у индикатора, если он скомпилирован? Ведь нам их надо указать функции iCustom().
Установите индикатор на график в терминале и посмотрите его параметры:
Вот мы и увидели параметры индикатора и порядок их следования.
А здесь мы видим что буфер для рисования всего один:
Продолжим. Нам необходимо знать количество уже открытых ордеров что бы не открывать ордера повторно. Это мы можем глянуть в наших предыдущих советниках. Предлагаю сразу же в цикле подсчета ордеров реализовать перенос стоп-лосса по фракталам:
int oBuy=0,oSell=0;
for(int i=OrdersTotal() −1;i>=0;i--)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{if(OrderType()==OP_BUY)
{double f1=NormalizeDouble(iFractals(NULL,0,MODE_LOWER,3),Digits);
if(f1>0 && OrderStopLoss()<f1 && f1<Bid) EditOrder(OrderTicket(),f1);}
if(OrderType()==OP_SELL)
{double f2=NormalizeDouble(iFractals(NULL,0,MODE_UPPER,3),Digits);
if(f2>0 && OrderStopLoss()>f2 && f2>Ask) EditOrder(OrderTicket(),f2);}
if(OrderType()==OP_BUY) oBuy++;
if(OrderType()==OP_SELL) oSell++;}
С помощью функции iFractals() мы получаем значение индикатора. Для ордеров типа Buy — берем нижние фракталы, а для ордеров типа Sell — верхние. Фракталы ищем на 3 свече от текущей. Дело в том что фрактал считается сформировавшимся если после свечи со стрелочкой идет 2 подряд свечи вверх или вниз соответственно.
Еще я использовал округление: NormalizeDouble(...,Digits). Дело в том, что некоторые Брокеры форекс с 4 значными котировками (типа Forex4you) не имеют истории своих котировок. При подгрузке котировок в этом случае будет использоваться сервер MetaQuotes, а там хранятся 5 значные котировки — в итоге при тестировании будут ошибки при открытии или модификации ордеров.
Осталось самое основное: открытие ордеров.
if(lZZ>0 && oBuy+oSell==0)
{i=2;
while(iCustom(NULL,0,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep,0,i)==0) i++;
double fZZ=iCustom(NULL,0,"ZigZag",ExtDepth,ExtDeviation,ExtBackstep,0,i);
double Lot=GetLot(MaxRisk);
if(Lot==0) {Alert("Недостаточно средств!");return(0);}
double tp=0;
double sl=0;
if(lZZ>fZZ)
{sl=NormalizeDouble(lZZ+StopLoss*Point,Digits);
if(TakeProfit>0) tp=NormalizeDouble(Bid— (sl-Bid)*TakeProfit,Digits);
NewOrder(OP_SELL,Lot,0,tp,sl);}
if(lZZ<fZZ)
{sl=NormalizeDouble(lZZ-StopLoss*Point,Digits);
if(TakeProfit>0) tp=NormalizeDouble(Ask+(Ask-sl)*TakeProfit,Digits);
NewOrder(OP_BUY,Lot,0,tp,sl);}}
Здесь мы проверяем что нет открытых ордеров и что окончание линии индикатора ZigZagа на предыдущей свече. Определяем направлении линии ZigZagа (для этого сравниваем точки между которыми проведена последняя линия) и открываем ордера. Осталось проверить как это все работает.
Для этого запустим тестер стратегий MT4 в визуальном режиме:
Обратите внимание на галочку «Визуализация». Нажимаем старт и после этого кнопочку: ![]()
Откроется график, но тестирование дальше не пойдет. Нам это и нужно. Устанавливаем на открывшийся график индикаторы ZigZag и Фракталы. После этого нажимаем кнопочку: ![]()
Начинается тестирование и мы видим все действия эксперта:

За декабрь месяц у меня, созданный нами эксперт "expert3" получил прибыль:
Признаться, я такого результата даже и не ожидал... При тестировании же эксперта "expert3" на большем промежутке времени, получили полный слив депозита.
Но т.к. я и не нанадеялся что созданный нами советник сразу будет прибыльным, то это вполне нормально! Я хотел всего лишь проверить свою идею и показать Вам, как можно использовать в своем эксперте MT4 внешние индикаторы.
Скачать: Советник «expert3»
Если Вы хотите изучать язык MQL или вам понравилась данная публикация - Вы можете подписаться на получение новых материалов сайта mql4you.ru по или по e-mail: |
Отзывов (22) на «Язык MQL — Урок 10 «Работа с внешними индикаторами»»
[...] прошлом уроке по изучению языка MQL4 мы научились использовать индикаторы Forex в своих [...]
При компиляции советника выдает две ошибки
А какие ошибки? К сожалению я еще не научился читать мысли
И не зная что за ошибки проблематично ответить из-за чего они возникают.
компилятор ругнулся на скобки
')' wrong parametr count (35,78 и (38,77) которые стоят в вызове функции EditOrder после f1 и f2 соответственно
хотя по количеству скобок все нормально, не могу понять в чем дело
Когда скобок не хватает компилятор ругается по другому: '\end_of_program' — unbalanced left parenthesis
В данном случае компилятор сообщает что количество параметров функции EditOrder и количество параметров передаваемых ей при вызове не совпадают.
Если вы копировали код прямо со страницы — рекомендую скачать советника в конце статьи. Редактор не всегда правильно оформляет код.
указанные ошибки возникают при компиляции скачанного советника.
Странно. Скачал сейчас советника и библиотеку с заголовочным файлом. Откомпилировал. Все работает. Скачайте заново библиотеку и заголовочный файл из урока MyLib
Возможно Вы ранее скачали первую версию библиотеки. Там действительно был всего 1 параметр у функции EditOrder. В обновленной 2 параметра.
Здравствуйте !
Очень интересный и классный материал , но мне непонятно как реализован трейлинг стоп . Можно ли объяснить подробнее
Здравствуйте Александр!
А можно ли дополнить советник на zigzag чтобы открывалось несколько ордеров и sl у них был общий
при открытии ордера в другую сторону все открытые ордера закрывались Спасибо за интересный сайт. Но есть просьба подробнее объяснять, потому что Вам может быть все понятно, а нам неучам еще далековато, хотя благодаря Вашей работе, начинает что-то проясняться
Добрый день!
В данном уроке трал происходит по фракталам. Перебираем в цикле все открытые ордера и для каждого ордера смотрим где находится стоп лосс. Если ордер Buy и стоплосс находится ниже последнего фрактала «вниз», то мы его переносим на уровень этого фрактала. Если ордер Sell и стоп лосс находится выше последнего фрактала «вверх», то переносим его на уровень этого фрактала.
Добрый день!
Можно открывать любое количество ордеров. Для этого необходимо вызвать функцию NewOrder() столько раз — сколько ордеров необходимо открыть. Например так: for(i=1;i<3;i++) NewOrder(...,sl); будет открыто 2 ордера с одинаковым стоп лоссом.
Советник игнорирует все сигналы пока есть хоть один открытый ордер. Для изменения его согласно Вашим условиям необходимо исправить: if(lZZ>0 && oBuy+oSell==0) на if(lZZ>0), if(lZZ>fZZ) на if(lZZ>fZZ && oSell==0) и if(lZZ<fZZ) на if(lZZ<fZZ && oBuy==0). А для закрытия противоположных — перед вызовом функции NewOrder() сделать цикл по всем открытым ордерам (аналогично подсчету ордеров) только с вызовом функции CloseOrder() из библиотеки MyLib Пример:
if(lZZ>fZZ && oSell==0)
{sl=NormalizeDouble(lZZ+StopLoss*Point,Digits);
if(TakeProfit>0) tp=NormalizeDouble(Bid— (sl-Bid)*TakeProfit,Digits);
for(i=OrdersTotal() −1;i>=0;i--)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderType()==OP_BUY) CloseOrder(OrderTicket());
for(i=1;i<3;i++) NewOrder(OP_SELL,Lot,0,tp,sl);}
А как сделать советника, который просто ставит стоп-лосс на открытую позицию на уровне вершины (низины) zigzag'а? И чтобы был трал (отключаемый) тоже по zigzag'у. Вроде бы простой принцип, но что-то нигде не нашел. Много всяких советников со сложнейшими алгоритмами, а когда нужен просто с элементарными функциями, оказывается, что такого и нет.
Здравствуйте!
Хотел создать советник по фракталам , т.е. Как написать код, например когда один фрактал выше предыдущего то buy , если еще выше то опять + buy , и т.д. но вдруг не пробил high , то стоп, все позы закрываются
Здравствуйте!
Почему то при тестировании советника перенос SL осуществляется с запозданием
Пожалуйста можно комментировать строки, было бы хорошо для понимания
Здравствуйте!
В строках , где идет установка SL и TP мне кажется есть ошибка т.к. эти параметры не устанавливаются
Hermann
Аналогично тралу по фракталам описаному в Работа с внешними индикаторами
Амир
Ошибок нет. Советника я тестировал. Возможно Вы пытаетесь запускать советника у брокера с 5 значными котировками. Если это так, то необходимо увеличить параметры TakeProfit и StopLoss в 10 раз.
Амир
Что значит с запаздыванием?
Амир
Добрый день! Фракталы есть вверх и вниз. Обычно они чередуются. Если имеется ввиду фракталы вверх, то приблизительно так:
double fl=0;
for(int i=1;i
{double ff=iFractals(NULL,0,MODE_UPPER,i);
if(ff>0 && fl>0) break;
if(ff>0) fl=ff;}
if(fl>ff) OrderSend(...);
if(fl
Здраствуйте палт,
Возник такой вопрос, а как в индикатор фракталов они смещены несколко пипсов над хай и лоу баров! Думаю если разясните ето будет интересно для постоение собственных индикаторов! Оригинальной код невозможно прочитат с метаедитор!
венцислав
Добрый день.
Индикаторный буфер содержит цены (как значения одной из оси координат). Если мы сами заполняем буфер (пишем индикатор), то кто нам мешает к значению прибавить или отнять несколько пунктов? А это и будет смещение.
Оставьте отзыв