Прошлый «советник» был безиндикаторный и работал с отложенными ордерами. Теперь создадим «эксперта» который будет использовать индикаторы и работать с маркет ордерами.
Время от времени на форумах появляются просьбы сделать «советник» по параболику. Давайте сделаем простого «эксперта» который при перевороте индикатора будет закрывать открытую позицию и сразу же открывать в другую сторону по направлению индикатора.
Но не обязательно начинать все с нуля а лучше с экономить уйму времени используя готовые свои функции. Со временем у Вас будет свой набор функций из которых можно складывать «экспертов» как конструктор.
Для создания нашего «советника» воспользуемся некоторыми функциями из предыдущего – расчет лотов 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/








