//+------------------------------------------------------------------+ //| TrailingByATR.mq4 | //| I_D | //| http://www.mymmk.com/ | //+------------------------------------------------------------------+ #property copyright "I_D" #property link "http://www.mymmk.com/" #property library //+------------------------------------------------------------------+ //| ТРЕЙЛИНГ ПО ATR (Average True Range, Средний истинный диапазон) | //| Функции передаётся тикет позиции, период АТR и коэффициент, на | //| который умножается ATR. Т.о. стоплосс "тянется" на расстоянии | //| ATR х N от текущего курса; перенос - на новом баре (т.е. от цены | //| открытия очередного бара) | //+------------------------------------------------------------------+ void TrailingByATR(int ticket,int atr_timeframe,int atr1_period,int atr1_shift,int atr2_period,int atr2_shift,double coeff,bool trlinloss) { // проверяем переданные значения //Print("ticket: ",ticket,", atr1_period: ",atr1_period,", atr2_period: ",atr2_period,", coeff: ",coeff,", OrderSelect(ticket,SELECT_BY_TICKET): ",OrderSelect(ticket,SELECT_BY_TICKET),", atr_timeframe: ",atr_timeframe,", atr1_shift: ",atr1_shift,", atr2_shift: ",atr2_shift); if ((ticket==0) || (atr1_period<1) || (atr2_period<1) || (coeff==0) || (coeff<0) || (!OrderSelect(ticket,SELECT_BY_TICKET)) || ((atr_timeframe!=1) && (atr_timeframe!=5) && (atr_timeframe!=15) && (atr_timeframe!=30) && (atr_timeframe!=60) && (atr_timeframe!=240) && (atr_timeframe!=1440) && (atr_timeframe!=10080) && (atr_timeframe!=43200)) || (atr1_shift<0) || (atr2_shift<0)) { Print("Трейлинг функцией TrailingByATR() невозможен из-за некорректности значений переданных ей аргументов."); return(0); } double curr_atr1; // текущее значение ATR - 1 double curr_atr2; // текущее значение ATR - 2 double best_atr; // большее из значений ATR double atrXcoeff; // результат умножения большего из ATR на коэффициент double newstop; // новый стоплосс // текущее значение ATR-1, ATR-2 curr_atr1 = iATR(Symbol(),atr_timeframe,atr1_period,atr1_shift); curr_atr2 = iATR(Symbol(),atr_timeframe,atr2_period,atr2_shift); // большее из значений best_atr = MathMax(curr_atr1,curr_atr2); // после умножения на коэффициент atrXcoeff = best_atr * coeff; // если длинная позиция (OP_BUY) if (OrderType()==OP_BUY) { // откладываем от текущего курса (новый стоплосс) newstop = Bid - atrXcoeff; // если trlinloss==true (т.е. следует тралить в зоне лоссов), то if (trlinloss==true) { // проверяем, является ли он лучше текущего стоплосса, если да, то последний корректируем if (newstop>OrderStopLoss()) OrderModify(ticket,OrderOpenPrice(),newstop,OrderTakeProfit(),OrderExpiration()); } else { Print("Bid: ",Bid,", atrXcoeff: ",atrXcoeff,", newstop: ",newstop); // иначе тралить начинаем только тогда, когда стоплосс лучше курса открытия (в профите) if ((newstop>OrderStopLoss()) && (newstop>OrderOpenPrice())) OrderModify(ticket,OrderOpenPrice(),newstop,OrderTakeProfit(),OrderExpiration()); } } // если короткая позиция (OP_SELL) if (OrderType()==OP_SELL) { // откладываем от текущего курса (новый стоплосс) newstop = Ask + (atrXcoeff + MarketInfo(Symbol(),MODE_SPREAD)*Point); // если trlinloss==true (т.е. следует тралить в зоне лоссов), то if (trlinloss==true) { // если стоплосс неопределен, то тралим в любом случае if (OrderStopLoss()==0) OrderModify(ticket,OrderOpenPrice(),newstop,OrderTakeProfit(),OrderExpiration()); // если стоплосс в убытке или в профите, тралим только если новый стоп лучше старого else { if (newstop