Смотри, как бесплатно скачать роботов
Ищи нас в Telegram!
Ставь лайки и следи за новостями
Интересный скрипт?
Поставь на него ссылку - пусть другие тоже оценят
Понравился скрипт?
Оцени его работу в терминале MetaTrader 5
Советники

Шаблон простого советника с комбинированным закрытием по ТП и СЛ или противоположному сигналу - эксперт для MetaTrader 4

Просмотров:
6448
Рейтинг:
(11)
Опубликован:
2016.03.15 10:35
Обновлен:
2016.03.23 14:54
Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу

В предыдущем примере показал шаблон советника с открытием по сигналу и закрытием по противоположному сигналу. В этот раз дополнил шаблон возможностью закрытия по тейк-профиту и стоп-лоссу (далее ТП и СТ). Для задания уровня ТП и СЛ в параметры советника были добавлены две переменные: TakeProfit и StopLoss. Функцию отправки ордера заменил на самописную, из примера https://www.mql5.com/ru/code/14998, это позволило задавать размер стопов, а не их уровень как в обычной функции. По своей сути это та же стандартная функция, облепленная дополнительными проверками перед отправкой.

Далее чуть модифицировал сигнальную часть советника так, чтобы сигнал был не постоянным, пока одна МА выше/ниже другой, а только в момент пересечения.

int Signal_()
  {
   double MACD1=iMACD(NULL,0,PeriodMA_Fast,PeriodMA_Slow,Sig_Period,0,MODE_MAIN,1);
   double MACD2=iMACD(NULL,0,PeriodMA_Fast,PeriodMA_Slow,Sig_Period,0,MODE_MAIN,2);
   if(MACD1>=0&&MACD2<0)return(1);//пересечение МА снизу вверх
   if(MACD1<=0&&MACD2>0)return(-1);//пересечение МА сверху вниз
   return(0);
  }

Ещё добавил функцию трейлинга, писать её не стал, она уже была готовая, в примере MACD Sample, но всё же сделал нормализацию цены при модификации и проверку на модификацию по той же цене. А также заменил return на break, чтобы прекращалось выполнение оператора switch, а не полностью всей функции OnTick. Хотя можно было оставить, для данного примера это не критично, программа работает почти одинаково в обоих случаях. Кому интересно может поэкспериментировать. Куски кода, отвечающего за трейлинг-стоп, вставил в блок перебора ордеров, каждый в свою ветку кода.

Трал покупки:

               if(TrailingStop>0)//сюда вставил кусок кода отвечающего за трейлинг покупки
                 {
                  if(Bid-OrderOpenPrice()>Point*TrailingStop)
                    {
                     if(OrderStopLoss()<Bid-Point*TrailingStop)
                       {
                        //--- modify order and exit
                        if(OrderStopLoss()!=n(Bid-Point*TrailingStop,_Symbol))
                        {
                           if(!OrderModify(OrderTicket(),OrderOpenPrice(),n(Bid-Point*TrailingStop,_Symbol),OrderTakeProfit(),0,Green))
                              Print("OrderModify error ",GetLastError());
                        }
                        break;
                       }
                    }
                 }

Трал продажи:

               if(TrailingStop>0)//сюда вставил кусок кода отвечающего за трейлинг продажи
                 {
                  if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                    {
                     if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                       {
                        //--- modify order and exit
                        if(OrderStopLoss()!=n(Ask+Point*TrailingStop,_Symbol))
                        {
                           if(!OrderModify(OrderTicket(),OrderOpenPrice(),n(Ask+Point*TrailingStop,_Symbol),OrderTakeProfit(),0,Red))
                              Print("OrderModify error ",GetLastError());
                        }
                        break;
                       }
                    }
                 }

Вообще очень часто код не пишется, а собирается из разных кусков. Своих, ранее написанных, либо чужих. Надеюсь MQ не сильно расстроятся, что я взял кусок кода из их примера.

Остался ещё один штрих: если открываемый ордер закроется (по СЛ или ТП) на баре, на котором открылся, то происходит повторная отправка ордера, т.к. сигнал ещё действует. Для того чтобы это не происходило, сделал контроль обработанных сигналов. Вообще сделать это можно по разному, в данном примере показал контроль обработки сигнала при помощи запоминания времени бара, на котором пришёл сигнал. Суть проста, делать попытку открытия ордера пока запомненное время не равно времени текущего бара, если попытка отправки прошла удачна, то запоминаем время текущего бара.

if(ti!=Time[0])//если время текущего бара не равно запомненному, пробуем открыть ордер если есть сигнал
     {
      if(total==0)//если нет открытых ордеров
        {
         switch(Signal)
           {
            case 1://если сигнал на покупку
              {
               if(OpenOrders(_Symbol,OP_BUY,Ask,Lot,Slippage,StopLoss,TakeProfit,Magik,"","",true)>0)
               //если ордер открыт успешно, но запоминаем время текущего бара
                 {
                  ti=Time[0];
                 }
               break;
              }
            case(-1)://если сигнал на продажу
              {
               if(OpenOrders(_Symbol,OP_SELL,Bid,Lot,Slippage,StopLoss,TakeProfit,Magik,"","",true)>0)
               //если ордер открыт успешно, но запоминаем время текущего бара
                 {
                  ti=Time[0];
                 }
               break;
              }
           }
        }
     }

вот что получается без такой проверки:

Вот и всё.

MartHandRand MartHandRand

Советник торгует по системе Мартингейла.

Stochastic_Chart Stochastic_Chart

Индикатор Stochastic Oscillator в основном окне графика.

Drawdown of the account Drawdown of the account

Советник отправляет пуш-уведомления о просадке на счете.

MA Signal MA Signal

Индикатор ставит стрелку на пересечении МА.