Помогите разобраться в коде трейлинг-стопа по 2-м ATR...

 

Здравствуйте! Код по 2-м ATR-ам переделал из стандартного кода трейлинг-стопа учебника (трейлинг на строго определенное количество пунктов).

В итоге получилось, что при возвращении курса против ордера SL модифицируется.   Допустим, при бай цена вверх трейлинг - стоп

за ценой на расстоянии АТР*множитель также вверх, цена вниз и трейлинг - стоп за ценой на расстоянии АТР*множитель также вниз, что противоречит

понятию трейлинг-стопа (строго по тренду и стоп-лосс не более установленного при открытии ордера при сопровождении позиции).  Вроде все правильно делаю... Подскажите. От души благодарю...

Вместо 0-го и 1-го бара использовал 1-ый и 2-ой, хотя все равно. Возможна ошибся где-то в 4-ом 5-ом блоке...

//--------------------------------------------------------------------
// Tral_Stop.mqh
//
// ТРЕЙЛИНГ ПО 2-ум ATR (Average True Range, Средний истинный диапазон)  
// период АТR и коэффициент, на который умножается ATR. Т.о. стоплосс "тянется" на расстоянии
// ATR х N от текущего курса; перенос - на новом баре (т.е. от цены 
// открытия очередного бара). Выбирается из двух АТР максимальный, чтобы из-за возможной           
// низкой волатильности рынка, дерганьем цены не выбило лося.
//--------------------------------------------------------------- 1 --
// Функция модификации StopLoss всех ордеров указанного типа
// Глобальные переменные:
// Mas_Ord_New             Массив ордеров последний известный
// 
//--------------------------------------------------------------- 2 --
int Tral_Stop(int Tip)
  {
   int Ticket;                      // Номер ордера
   double
   Price,                           // Цена открытия рыночного ордера
   TS,                              // TralingStop (относит.знач.цены)
   SL,                              // Значение StopLoss ордера
   TP;                              // Значение TakeProfit ордера
   bool Modify;                     // Признак необходимости модифи.
   
   double prev_atr1;                // previos значение ATR1
   double prev_atr2;                // previos значение ATR2
   double curr_atr1;                // текущее значение ATR1
   double curr_atr2;                // текущее значение ATR2
   double best_atr_prev;            // большее из значений ATR на предыдущем баре (2-ом)
   double best_atr_curr;            // большее из значений ATR на текущем баре (1-ом)
   double atrXmul_prev;  // результат умножения большего из ATR на множитель на предыдущем баре, 2
   double atrXmul_curr;  // результат умножения большего из ATR на множитель на текущем баре (1-ом)
   double newstop;                  // новый стоплосс
//--------------------------------------------------------------- 3 --
   for(int i=1;i<=Mas_Ord_New[0][0];i++)  // Цикл по всем ордерам
     {                                    // Ищем ордера задан. типа
      if (Mas_Ord_New[i][6]!=Tip)         // Если это не наш тип..
         continue;                        //.. то переступим ордер
      Modify=false;                       // Пока не назначен к модифи
      Price =Mas_Ord_New[i][1];           // Цена открытия ордера
      SL    =Mas_Ord_New[i][2];           // Значение StopLoss ордера
      TP    =Mas_Ord_New[i][3];           // Значение TakeProft ордера
      Ticket=Mas_Ord_New[i][4];           // Номер ордера
     
      //--------------------------------------------------------- 4 --
       // previos значение ATR1, ATR2
   prev_atr1 = iATR(Symbol(),0,ATRPeriod_1,2);
   prev_atr2 = iATR(Symbol(),0,ATRPeriod_2,2);
       
       // текущее значение ATR1, ATR2
   curr_atr1 = iATR(Symbol(),0,ATRPeriod_1,1);
   curr_atr2 = iATR(Symbol(),0,ATRPeriod_2,1);
   
      // большее из значений ATR на предыдущем и текущем барах
   best_atr_prev = MathMax(prev_atr1,prev_atr2); 
   best_atr_curr = MathMax(curr_atr1,curr_atr2);
   
      // после умножения на множитель
   atrXmul_prev = best_atr_prev * Mul; 
   atrXmul_curr = best_atr_curr * Mul;      
      
      switch(Tip)                         // Переход на тип ордера
        {
         case 0 :                         // Ордер Buy
               if (NormalizeDouble(atrXmul_prev,Digits)<  // Если ниже желаемого.. 
             NormalizeDouble(atrXmul_curr,Digits)) 
              {                           // ..то модифицируем его:  
               SL=Bid-atrXmul_curr;       // Новый его StopLoss
               Modify=true;               // Назначен к модифи.              
               }
              
            break;                        // Выход из switch
         case 1 :                         // Ордер Sell
               if (NormalizeDouble(atrXmul_prev,Digits)>  // Если выше желаемого.. 
             NormalizeDouble(atrXmul_curr,Digits)) 
              {                           // ..то модифицируем его:  
               SL=Ask+atrXmul_curr;       // Новый его StopLoss
               Modify=true;               // Назначен к модифи.              
               }
                          
        }                                 // Конец switch
      if (Modify==false)                  // Если его не надо модифи..
         continue;                        // ..то идём по циклу дальше
      bool Ans=OrderModify(Ticket,Price,SL,TP,0);//Модифицируем его!
      //--------------------------------------------------------- 5 --
      if (Ans==false)                     // Не получилось  
        {                                 // Поинтересуемся ошибками:
         if(Errors(GetLastError())==false)// Если ошибка непреодолимая
            return;                       // .. то уходим.
         i--;                             // Понижение счётчика
        }
      Terminal();                         // Функция учёта ордеров 
      Events();                           // Отслеживание событий
     }
   return;                                // Выход из пользов. функции
  }
//--------------------------------------------------------------- 6 --




 
А что происходит ? Стоплосс идёт за ценой и вверх и вниз?
 
zhuki >>:
А что происходит ? Стоплосс идёт за ценой и вверх и вниз?


именно так. Хотелось бы если бай то вверх, селл - вниз...
 
У вас нет сравнения старого уровня стоплосс, с новым, который вы модифицируете всегда.
 
zhuki >>:
У вас нет сравнения старого уровня стоплосс, с новым, который вы модифицируете всегда.


Да там все в порядке - просто лось модифицируется в две стороны, а надо в одну...
 
Нужна проверка . Например для BUY   Bid-atrXmul_curr- OrderStopLoss()>=Step  ,где Step - шаг трейлинга.
 
zhuki >>:
Нужна проверка . Например для BUY   Bid-atrXmul_curr- OrderStopLoss()>=Step  ,где Step - шаг трейлинга. 


Понятно - буду что-нибудь думать...
 
//-------- Если двигаемся в ту сторону куда и открылись тралим по Step ----------------------------------
        if (OrderSelect(Tic_B,SELECT_BY_TICKET,MODE_TRADES)==true && B>0 )
        {    //--------- Самый первый раз ----------------------------------
        if (OrderStopLoss()==0  && OrderTakeProfit()==0)
        { 
        ret=OrderModify(Tic_B,OrderOpenPrice(),OrderOpenPrice()-SL*Point,OrderOpenPrice()+TP*Point,0,CLR_NONE);
        PlaySound("tick.wav");
        return(0);
        }  //----------- Трейлинг --------------------------
        if (Bid-OrderStopLoss()>(SL+Step)*Point && OrderStopLoss()!=0)
        { 
        ret=OrderModify(Tic_B,OrderOpenPrice(),OrderStopLoss()+Step*Point,OrderTakeProfit(),0,CLR_NONE);
        PlaySound("tick.wav");
        return(0);
        }
        }

        if (OrderSelect(Tic_S,SELECT_BY_TICKET,MODE_TRADES==true) && S>0)
        {      //--------- Самый первый раз ----------------------------------
        if (OrderStopLoss()==0 && OrderTakeProfit()==0)
        {
        ret=OrderModify(Tic_S,OrderOpenPrice(),OrderOpenPrice()+SL*Point,OrderOpenPrice()-TP*Point,0,CLR_NONE);
        PlaySound("tick.wav");
        return(0);
        }          //----------- Трейлинг --------------------------
        if (OrderStopLoss()-Ask>(SL+Step)*Point && OrderStopLoss()!=0)
        { 
        ret=OrderModify(Tic_S,OrderOpenPrice(),OrderStopLoss()-Step*Point,OrderTakeProfit(),0,CLR_NONE);
        PlaySound("tick.wav");
        return(0);
        }
        }
Это Вам для изучения.
 
от души Вас благодарю! Буду заниматься.
Причина обращения: