Помогите с кодом трейлинг-стопа...

 

Здравствуйте! Всем доброго времени суток! Не первый день бьюсь над ситуацией, хотя понимаю, что заблудился в трех соснах, вроде все прописываю правильно, просто существуют какие-то особенности... Код по 2-м ATR-ам переделал из стандартного кода трейлинг-стопа учебника (трейлинг на строго определенное количество пунктов). В итоге получилось, что при возвращении курса против ордера -  SL модифицируется. Допустим, при бай цена вверх трейлинг - стоп - за ценой на расстоянии АТР*множитель также вверх - все нормально, цена вниз и трейлинг - стоп за ценой на расстоянии АТР*множитель также вниз - не нормально, т.к. противоречит понятию трейлинг-стопа (строго по тренду и стоп-лосс не более установленного при открытии ордера при сопровождении позиции), т.е. трейлинг-стоп должен двигаться только в направлении позиции - если бай - то вверх, селл - вниз, а здесь он движется как вверх так и вниз на расстоянии АТР*множитель. Вроде все правильно делаю... Возможно необходимо еще прописать дополнительные условия перемещения ордера  в 4-ом блоке...  Подскажите... От души благодарю...

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

При использовании стандартного трейлинга кода учебника -  на определенное количество пунктов - все работает... При модификации кода - по 2-м АТР - нет...

//--------------------------------------------------------------------
// 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 --
 

расставляйте Print по коду и анализируйте выполнение.

Также проверяйте GetLastError()

 
Roman. >>:
 //--------------------------------------------------------- 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);


может оно и не имеет отношения к делу, но почему у вас текущее значение 1, а предыдущее 2, когда оно 0 и 1

 
sashasan >>:

может оно и не имеет отношения к делу, но почему у вас текущее значение 1, а предыдущее 2, когда оно 0 и 1


точно не имеет отношения. Роман по закрытым барам работает... комент есть комент. .
 
sergeev >>:


точно не имеет отношения. Роман по закрытым барам работает... комент есть комент. .


Полностью с Вами согласен.
 

Как раз в том месте где сравнивается условие изменения стопа, вы сравниваете не совсем те вещи. Его надо маленько расширить. я так понял у Вас сравниваются текщее и предъидущее значение ATR умноженное на множитель. То есть фактически размер стопа. А если вы будете сравнивать уровень стопов (цена при которой должно произойти закрытие). Уровень на который будет выставлен новый расчитанный стоп (Bid-atrXmul_curr) должен быть больше уровня стопа который на данной момент имеется по данной позиции (с помощю MarketInfo()) это по Buy, и соответственно наоборот по Sell. Проблема будет решена.

Причина обращения: