Индикаторный «советник» и пользовательский индикатор

Прошлый «советник» был безиндикаторный и работал с отложенными ордерами. Теперь создадим «эксперта» который будет использовать индикаторы и работать с маркет ордерами.

Время от времени на форумах появляются просьбы сделать «советник» по параболику. Давайте сделаем простого «эксперта» который при перевороте индикатора будет закрывать открытую позицию и сразу же открывать в другую сторону по направлению индикатора.

Но не обязательно начинать все с нуля а лучше с экономить уйму времени используя готовые свои функции. Со временем у Вас будет свой набор функций из которых можно складывать «экспертов» как конструктор.

Для создания нашего «советника» воспользуемся некоторыми функциями из предыдущего – расчет лотов 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/

You May Also Like