Ставь лайки и следи за новостями
Поставь на него ссылку - пусть другие тоже оценят
Оцени его работу в терминале MetaTrader 5
![Советники](https://c.mql5.com/i/code/expert.png)
Шаблон простого советника с комбинированным закрытием по ТП и СЛ или противоположному сигналу - эксперт для MetaTrader 4
- Просмотров:
- 6508
- Рейтинг:
- Опубликован:
- 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](https://c.mql5.com/i/code/expert.png)
Советник торгует по системе Мартингейла.
![Stochastic_Chart](https://c.mql5.com/i/code/indicator.png)
Индикатор Stochastic Oscillator в основном окне графика.
![Drawdown of the account](https://c.mql5.com/i/code/expert.png)
Советник отправляет пуш-уведомления о просадке на счете.
![MA Signal](https://c.mql5.com/i/code/indicator.png)
Индикатор ставит стрелку на пересечении МА.