Прошлый «советник» был безиндикаторный и работал с отложенными ордерами. Теперь создадим «эксперта» который будет использовать индикаторы и работать с маркет ордерами.
Время от времени на форумах появляются просьбы сделать «советник» по параболику. Давайте сделаем простого «эксперта» который при перевороте индикатора будет закрывать открытую позицию и сразу же открывать в другую сторону по направлению индикатора.
Но не обязательно начинать все с нуля а лучше с экономить уйму времени используя готовые свои функции. Со временем у Вас будет свой набор функций из которых можно складывать «экспертов» как конструктор.
Для создания нашего «советника» воспользуемся некоторыми функциями из предыдущего – расчет лотов Lot(), учет ордеров Orders() и информационная inf().
Создадим еще две, одну для открытия маркет ордеров Send(tip), значение переменной tip задает функции какой тип ордера открывать бай или селл.
int Send(int tip) { LT = Lot(); // вызываем функцию расчета лота if(LT == -1) return(0); // если функция Lot() вернула -1 значит нет денег даже на минимальный лот - выходим в start if(tip == 1) { Text = "Sell"; // для функции inf... чтобы вывести в сообщении с каким ордером работаем. inf(1, Ticket, -1); // вызываем информационную функцию... сообщаем о попытке открыть Sell ордер Ticket = OrderSend(Symb,OP_SELL,LT,Price,3,SL,TP,NULL,Magic,0,Red); // открываем сел if(Ticket > 0) // если Ticket больше 0 значит все прошло успешно... Ticket содержит номер ордера { // сообщаем об этом inf(2, Ticket, -1); // вызываем информационную функцию... сообщаем что попытка открыть Sell ордер удалась return(1); // выходим в start } inf(15, GetLastError()); // если дошли сюда значит есть ошибка... узнаем какая именно return(0); // выходим в start } if(tip == 0) { Text = "Buy"; // для функции inf... что бы вывести в сообщении с каким ордером работаем. inf(1, Ticket, -1); // вызываем информационную функцию... сообщаем о попытке открыть Buy ордер Ticket = OrderSend(Symb,OP_BUY,LT,Price,3,SL,TP,NULL,Magic,0,Blue); //открываем бай if(Ticket > 0) // если Ticket больше 0 значит все прошло успешно... Ticket содержит номер ордера { // сообщаем об этом inf(2, Ticket, -1); // вызываем информационную функцию... сообщаем что попытка открыть Buy ордер удалась return(1); // выходим в start } inf(15, GetLastError()); // если дошли сюда значит есть ошибка... узнаем какая именно return(0); // выходим в start } return(0); // выходим в start }
И функция закрытия маркет ордеров Closing(tip), значение переменной tip задает функции какой тип ордера закрывать бай или селл.
int Closing(int tip) // если ордеров больше одного - в нашем случае два { for(int i = 0; i < total; i ++) // начало цикла { if(OrderSelect(i, SELECT_BY_POS) == false) continue; // если ордер не выбран, возвращаемся в начало цикла if(Magic != OrderMagicNumber()) continue; // если магическое число не совпадает с нашим Magic - возвращаемся в начало цикла Ticket = OrderTicket(); // запоминаем номер ордера if(OrderType() == tip) { Text ="Sell"; // для функции inf... что бы вывести в сообщении с каким ордером работаем. Price = NormalizeDouble(Ask,Digits); LT = OrderLots(); inf(5, Ticket, -1); // вызываем информационную функцию... сообщаем о попытке закрыть Sell ордер answer = OrderClose(Ticket,LT,Price,3,Violet); if(answer == true) // если true значит все прошло успешно { // сообщаем об этом inf(6, Ticket, -1); // вызываем информационную функцию... сообщаем что попытка закрыть Sell ордер удалась return(1); // выходим в start } inf(15, GetLastError()); // если дошли сюда значит есть ошибка... узнаем какая именно return(0); // выходим в start } if(OrderType() == tip) { Text ="Buy"; // для функции inf... что бы вывести в сообщении с каким ордером работаем. Price = NormalizeDouble(Bid,Digits); LT = OrderLots(); inf(5, Ticket, -1); // вызываем информационную функцию... сообщаем о попытке закрыть Buy ордер answer = OrderClose(Ticket,LT,Price,3,Violet); if(answer == true) // если true значит все прошло успешно { // сообщаем об этом inf(6, Ticket, -1); // вызываем информационную функцию... сообщаем что попытка закрыть Buy ордер удалась return(1); // выходим в start } inf(15, GetLastError()); // если дошли сюда значит есть ошибка... узнаем какая именно return(0); // выходим в start } } // конец цикла return(0); }
В функции Closing() для закрытия маркет ордеров используем торговую функцию OrderClose.
Перейдем к индикатору. В МТ4 есть набор стандартных индикаторов (набор функций), их можно использовать в «советнике». В любом индикаторе есть изменяемые параметры (аналог настройки индикатора).
Для того, что бы «эксперт» мог получить данные индикатора, его необязательно цеплять на график. Индикатор будет загружен и рассчитан в потоке. Для себя что бы видеть весь процесс, можно прицепить индикатор к графику.
Получаем данные от индикатора.
double par = iSAR(NULL,0,0.02,0.2,0); // получаем данные от параболика
Не забываем нормализировать
par = NormalizeDouble(par,Digits);
Когда есть открытый ордер, проверяем совпадают ли направления ордера и индикатора, если нет закрываем.
Параболик вверх – закрываем селл.
if((total == 1) && (par < Bid) && (Mas_Tip[1] > 0)) Closing(1); // если ордер селл а параболик разернулся в верх - закрываем
Параболик вниз – закрываем бай.
if((total == 1) && (par > Ask) && (Mas_Tip[0] > 0)) Closing(0); // если ордер бай а параболик развернулся вниз - закрываем
Если открытых позиций нет, отрываем ордер в направлении индикатора.
Параболик вниз – открываем селл.
if(total == 0 && par > Ask) // если параболик вниз открываем селл { … Send(1); // вызываем функцию открытия (Sell)
Параболик вверх – открываем бай.
if((total == 0) && (par < Bid)) // если параболик вверх открываем бай { … Send(0); // вызываем функцию открытия (Buy)
Исходник: Parabolic-0.0
Выше мы использовали технический индикатор. Но их набор в МТ4 ограничен, это капля в море тех, что написали пользователи.
Что бы использовать пользовательский индикатор он должен быть скомпилирован (файл с расширением ex4) и помещен в папку indicators.
iCustom – эта функция позволяет использовать пользовательские индикаторы в «советниках».
Для примера возьмем индикатор TrendMagic – индикатор тренда.
При смене тренда он изменяет цвет. Он использует два буфера, когда индикатор окрашен в синий цвет используется буфер с индексом — 0,при окраске в синий используется буфер — 1. По значениям буферов будем определять в какой цвет окрашен индикатор в данный момент.
Алгоритм нашего «эксперта» тот же что и прошлого Parabolic 0.0 только вместо технического параболика будем использовать пользовательский TrendMagic.
Цвет голубой – закрываем селл и открываем бай.
Цвет красный – закрываем бай и открываем селл.
Для нашего нового «советника» возьмем за основу Parabolic 0.0, просто переименуем его и внесем минимальные изменения в код.
double trm = iCustom(NULL,0,"TrendMagic",0,1); // получаем данные от TrendMagic trm = NormalizeDouble(trm,Digits); double trm1 = iCustom(NULL,0,"TrendMagic",1,1); // получаем данные от TrendMagic trm1 = NormalizeDouble(trm1,Digits); if((trm < 1000000 && trm1 > 1000000) && (Mas_Tip[1] > 0)) Closing(1); // если ордер селл а TrendMagic синий - закрываем if((trm > 1000000 && trm1 < 1000000) && (Mas_Tip[0] > 0)) Closing(0); // если ордер бай а TrendMagic красный - закрываем //----------------------------------- if(total == 0 && (trm > 1000000 && trm1 < 1000000)) // если TrendMagic красный открываем селл {
И для открытия бай ордера.
if((total == 0) && (trm < 1000000 && trm1 > 1000000)) // если TrendMagic синий открываем бай {
Индикатор: TrendMagic
Исходник: TrendMagic-0.0
Обновленная версия с рабочим тейкпрофитом
Исходник: TrendMagic-0.02
Работа над ошибками — https://forexlab.ru/rabota-nad-oshibkami/