И так, продолжим изучать язык MQL4: сегодня мы разберемся как создавать советники форекс для MT4, на основе пользовательских индикаторов Metatrader 4. Для примера, попробуем создать советник форекс на основе индикаторов форекс по «Стратегии форекс «Линия баланса».
Создадим новый советник «expert2» и скопируем в него наши функции GetLot() и NewOrder().
Ордера в этой стратегии форекс закрываются по стоп-лоссу и поэтому функция CloseOrder() нам не нужна. Для начала необходимо изучить торговую стратегию. В ней сказано что торговля ведется только отложенными ордерами Buy Stop и Sell Stop.
Перепишем нашу функцию NewOrder() так, чтобы она умела открывать такие типы ордеров Forex — т.е. отложенные ордера Buy Stop и Sell Stop:
int NewOrder(int Cmd,double Lot,double PR=0,double TP=0,double SL=0)
{while(!IsTradeAllowed()) Sleep(100);
if(Cmd==OP_BUY)
{PR=Ask;
if(TP==0 && TakeProfit>0) TP=Ask+TakeProfit*Point;
if(SL==0 && StopLoss>0) SL=Ask-StopLoss*Point;}
if(Cmd==OP_SELL)
{PR=Bid;
if(TP==0 && TakeProfit>0) TP=Bid-TakeProfit*Point;
if(SL==0 && StopLoss>0) SL=Bid+StopLoss*Point;}
int tic=OrderSend(Symbol(),Cmd,Lot,PR,3,SL,TP,«»,0,0,CLR_NONE);
if(tic<0) Print(«Ошибка открытия ордера: «,GetLastError());
return(tic);}
Мы вынесли переменные для цены, тейк-профита, стоп-лосса в параметры функции и указали им значение по умолчанию «0». Теперь эту функцию можно вызывать как и раньше с 2 параметрами, а можно с указанием дополнительных параметров. Это нам пригодится для открытия отложенных ордеров форекс.
Кроме того в условии расчета тейк-профита и стоп-лосса мы проверяем эти параметры на соответствие «0». Это поможет избежать в дальнейшем ситуации когда мы передаем эти параметры, а функция их пересчитывает.
Любой индикатор существующий в Metatrader4 можно использовать в советнике. Нам (согласно торговой стратегии) нужна всего одна экспоненциальная скользящая средняя с периодом 25 — EMA (25).
Получить ее значение можно функцией iMA().
Напишем:
extern int MAPeriod=25;
double ma=iMA(NULL,0,MAPeriod,0,MODE_EMA,PRICE_CLOSE,1);
Теперь в переменной ma будет значение экспоненциальной скользящей средней на предыдущей (закрытой) свече.
Осталось проверить что эта свеча пересекает EMA. Для этого воспользуемся предопределенными массивами Open[] и Close[]. В них содержится цена открытия и закрытия всех свечей на графике Metatrader4.
if(Open[1]<ma && Close[1]>ma) NewOrder(OP_BUYSTOP,Lot,…);
if(Open[1]>ma && Close[1]<ma) NewOrder(OP_SELLSTOP,Lot,…);
Чтобы при пересечении открывался один ордер — необходимо подсчитать уже открытые:
int oBuy=0,oSell=0;
for(int i=OrdersTotal()-1;i>=0;i—)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{if(OrderType()==OP_BUYSTOP || OrderType()==OP_BUY) oBuy++;
if(OrderType()==OP_SELLSTOP || OrderType()==OP_SELL) oSell++;}
Условие изменится:
if(oBuy==0 && Open[1]<ma && Close[1]>ma) NewOrder(OP_BUYSTOP,Lot,…);
if(oSell==0 && Open[1]>ma && Close[1]<ma) NewOrder(OP_SELLSTOP,Lot,…);
Читаем стратегию форекс «Линия баланса» еще раз и замечаем: страховочный стоп-лосс необходимо установить на один пункт выше максимума или ниже минимума бара, пересекающего EMA (25), однако не ближе 30 пипсов от текущей цены.
Максимумы и минимумы содержатся в предопределенных массивах High[] и Low[] соответственно.
Исправляем условие открытия ордеров:
if(oBuy==0 && Open[1]<ma && Close[1]>ma)
{double s1=Low[1] -1*Point;
if(Bid-s1<30*Point) s1=Bid-30*Point;
NewOrder(OP_BUYSTOP,Lot,High[1]+1*Point,0,s1);}
if(oSell==0 && Open[1]>ma && Close[1]<ma)
{double s2=High[1] +1*Point;
if(s2-Ask<30*Point) s2=Ask+30*Point;
NewOrder(OP_SELLSTOP,Lot,Low[1]-1*Point,0,s2);}
- Компилируем созданный советник из кода MQL4 в код, понятный компьютеру.
- Проверяем его на тестере стратегий Metatrader 4.
Советник по стратегии «Линия баланса» работает, но некоторые отложенные ордера не срабатывают и висят, портя всю картину. В стратегии не сказано что делать с такими ордерами. Немного подумав, решаем что при установке противоположного отложенного ордера форекс их надо удалять.
Напишем свою функцию удаления отложенных ордеров Forex:
void DelOrder()
{while(!IsTradeAllowed()) Sleep(100);
if(!OrderDelete(OrderTicket(),CLR_NONE))
Print(«Ошибка удаления ордера: «,GetLastError());
return;}
Простая функция получилась. Но для нее надо выбрать ордер. Поэтому напишем функцию выбора и удаления всех ордеров определенного типа:
void DelOrders(int Cmd)
{for(int i=OrdersTotal()-1;i>=0;i—)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
if(OrderType()==Cmd) DelOrder();
return;}
Перед установкой нового ордера будем вызывать ее с соответствующим параметром.
Перечитываем стратегию еще раз.
Находим условие: «если цена резко пробила EMA (25) и закрылась очень далеко от нее, то отложенные ордера лучше не устанавливать, т.к. очень велика вероятность переписи хая либо лоу этой свечи и дальнейшего отката. В данном случае лучше подождать отката, а уже после этого выставить необходимый ордер«.
Конкретная цифра нам не сказана. Значит вынесем ее во внешний параметр для будущей оптимизации: extern int Delta=30; и добавим условие пропуска таких свечей перед нашим условием открытия ордеров:
if(MathAbs(Close[1]-ma)>Delta*Point) return(0);
Ищем что мы еще забыли: «Необходимо просматривать ваши ордера каждые 4 часа. Если позиция не закрылась по стоп-лоссу и находится в положительной для вас зоне, то стоп-лосс необходимо передвинуть на максимум либо минимум нового H4 закрытого бара».
Что бы выполнить это условие эксперт MT4 должен выполнятся один раз при открытии новой свечи. В самом начале напишем:
datetime Today=0;
if(Time[0]==Today) return(0);
Today=Time[0];
Подсчет ордеров немного изменим:
for(int i=OrdersTotal()-1;i>=0;i—)
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{if(OrderType()==OP_BUY && Bid>OrderOpenPrice()) EditOrder(Low[1]);
if(OrderType()==OP_SELL && Ask<OrderOpenPrice()) EditOrder(High[1]);
if(OrderType()==OP_BUYSTOP || OrderType()==OP_BUY) oBuy++;
if(OrderType()==OP_SELLSTOP || OrderType()==OP_SELL) oSell++;}
Все условия стратегии форекс «Линия Баланса» выполнены!
Эксперт на MQL4 создан правильно, согласно всех условий стратегии.
Теперь остается протестировать и оптимизировать наш советник Forex на тестере стратегий Metatrader 4 — как это делается, мы уже изучали на Уроке 7 “тестирование и оптимизация в MT4”.
Скачать: советник «expert2» — торгующий по стратегии форекс Линия баланса»
У меня получилось, но пришлось конечно поводится, компилятор сначала ошибку выдавал. Но я стал замечать что приходит осмысление того что сделал
При работе, советник пишет «Ошибка редактирования ордера: 1» и «Ошибка открытия ордера: 130».
Что это такое я нашел. А что с этим делать?
Владимир
В Вопрос №5 — «Коды ошибок при тестировании советника» описаны данные ошибки.
А как робот будет понимать что бар, по которой надо передвигат стоп, есть 4 часовой бар?
венцислав
Есть несколько способов.
1) это установить советник на 4 часовой таймфрейм, тогда в переменных Open[],Close[],High[],Low[] и т.д. будут значения 4 часовых баров.
2) использовать функции iOpen(),iClose() и т.д. а в них указывать необходимый таймфрейм.
По моему в советнике не реализовано вот это условие:
При достижении прибыли +50 пунктов и закрытия 1-й H4 свечи после открытия сделки, ее необходимо перевести на трейлинг-стоп 50 пунктов.
Если условие на самом деле не реализовано, подскажите как его можно осуществить.
Почему то советник не хочет тестироваться. нажимаю старт а реакции 0
Спасибо за сайт.
И вопрос, как обозначить в советнике уровни у МА, и открытие и закрытие ордеров на этих уровнях.
Всего доброго. Алексей