Перенос стопа в б/у

 

Подскажите как грамотно реализовать перенос стопа в бу. Вот как получилось у меня для БАЙ

 if (OrderType()==OP_BUY)
      {
      //стоп в бу
      if (Close[0]>buyprice+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point && OrderStopLoss()<buyprice)
              { 
               OrderModify(OrderTicket(),0,NormalizeDouble(buyprice,Digits),OrderTakeProfit(),0,Yellow);
              }
      }

для СЕЛЛ

if (OrderType()==OP_SELL)
      {
      //Стоп в бу
      if (Close[0]<sellprice-MarketInfo(Symbol(),MODE_STOPLEVEL)*Point+MarketInfo(Symbol(),MODE_SPREAD)*Point && OrderStopLoss()>sellprice)
              { 
               OrderModify(OrderTicket(),0,NormalizeDouble(sellprice,Digits),OrderTakeProfit(),0,Yellow);
              }
      }

вроде как всё что надо учёл, переносим в бу когда текущая цена больше цены открытия+минимальное расстояние стопа, в том случае когда текущий стоп-лосс меньше цены открытия... buyprice - цена открытия ордера. Но в тестах проскакивает ошибка модификации ордера 130. Может логика страдает?)

 
barada писал (а) >>

Но в тестах проскакивает ошибка модификации ордера 130. Может логика страдает?)

а когда выскакивает ошибка? есть такая зараза как "проскальзывания". на момент расчета стоп может быть правильный, но пока дойдет дело до его исполнения - цена сошла на пару пунктов назад и он уже внутри StopLevel... тут и добавка спреда может не спасти :(

 
ForexTools писал (а) >>

а когда выскакивает ошибка? есть такая зараза как "проскальзывания". на момент расчета стоп может быть правильный, но пока дойдет дело до его исполнения - цена сошла на пару пунктов назад и он уже внутри StopLevel... тут и добавка спреда может не спасти :(

выскакивает когда цена приблежается к нужному нам уровню, штук 5 ошибок и после стоп передвигается, редко бывает, но напрягает, спрэд я учёл для стопа Sell поз. Просто может я вобще не правильно описал казалось бы лёгкий приём?

 

Не плохо при этом еще и проверить стоплосс на значение, а то к примеру он уже в БУ а ты хочеш его еще раз изменить не меняя цены

//-------------------------------------------------------------------+
//функция переводит ордер с нужным тикетом в бу или на нужный уровень+
//+------------------------------------------------------------------+
int Bu(int ti=0)
{
  int err;double sl;
  if(ti==0){return(-1);}
  if(OrderSelect(ti,SELECT_BY_TICKET,MODE_TRADES)&&(OrderCloseTime()==0)){
    if(bu==0){sl=OrderOpenPrice();}else{
      if(OrderType()==OP_BUY) {sl=NormalizeDouble((OrderOpenPrice()+bu*Point),Digits);}
       if(OrderType()==OP_SELL){sl=NormalizeDouble((OrderOpenPrice()-bu*Point),Digits);}} 
    if(OrderType()==OP_BUY){
     if(sl<MarketInfo(OrderSymbol(),MODE_BID)-(MarketInfo(OrderSymbol(),MODE_STOPLEVEL)*Point)&&sl!=OrderStopLoss()){ 
      err = OrderModify(ti,OrderOpenPrice(),sl,OrderTakeProfit(),0,Green);}} 
    if(OrderType()==OP_SELL){
     if(sl>MarketInfo(OrderSymbol(),MODE_ASK)+(MarketInfo(OrderSymbol(),MODE_STOPLEVEL)*Point)&&sl!=OrderStopLoss()){ 
      err = OrderModify(ti,OrderOpenPrice(),sl,OrderTakeProfit(),0,Green);}}}      
return(err);
}
//--------------------------------------------------------------------+

для корректной работы во внешние переменные надо вставить это

//-------------------------------------------------------------------+
extern int      bu=0;//кол-во пунктов трала: Если "0",то в безубыток |
//+------------------------------------------------------------------+
 
xrust писал (а) >>

Не плохо при этом еще и проверить стоплосс на значение, а то к примеру он уже в БУ а ты хочеш его еще раз изменить не меняя цены

для корректной работы во внешние переменные надо вставить это

Спасибо, теперь проверяю стоп вот так

sl!=OrderStopLoss()

вместо

OrderStopLoss()<buyprice

ошибочка исчезла

 

Ну вообще-то ошибка 130 возникала совсем не из-за этого, поэтому весьма странно что она исчезла после добавления sl!=OrderStopLoss(). Тут должна была исчезнуть ошибка 1. А ошибка 130 возникала из-за неправильной проверки на STOPLEVEL. Вот обрати внимание как xrust использует эту проверку. Там используется ЦЕНА ЗАКРЫТИЯ ордера (т.е. Bid для buy или Ask для sel), а не как у тебя (цена открытия ордера).

Но вообще эту проверку можно было написать гораздо проще и короче, без учёта OrderType:

if (MathAbs(sl-OrderClosePrice())<MarketInfo(OrderSymbol(),MODE_STOPLEVEL)*Point) && sl!=OrderStopLoss())
  err = OrderModify(ti,OrderOpenPrice(),sl,OrderTakeProfit(),0,Green);

Конечно тут подразумевается что уже выполнена предыдущая часть кода по установке значения sl.

Если могут использоваться ордера с разными символами, то тогда разумеется вместо Point надо использовать переменную point, присвоив ей значение MarketInfo(OrderSymbol(),MODE_POINT)

 
bool CheckAccessModifyOrder(int ticket, double stoploss, double takeprofit)
{ bool result = true;
  if (OrderSelect(ticket, SELECT_BY_TICKET))
   {
     double FreezeLevel = MarketInfo(Symbol(), MODE_FREEZELEVEL) * Point;
     switch (OrderType())
      {
       case OP_BUY:
        result = (Bid-stoploss > FreezeLevel) && (takeprofit-Bid > FreezeLevel);
        break;
       case OP_SELL:
        result = (stoploss-Ask > FreezeLevel) && (Ask-takeprofit > FreezeLevel);
        break;
       default:
        result = true;
        break; 
      }  
   }
  else 
   result = false;
  if (result == false) 
   PrintEx("Модиф. запрещена; FL="+FreezeLevel+"; Bid="+Bid+"; Ask="+Ask+"; sl="+stoploss+"; tp="+takeprofit); 
  return (result) ;
  //return (true) ;
} // end CheckAccessModifyOrder
Я тоже много сталкивался с такой ошибкой. В итоге написал такую ф-ию, после чего проблема исчезла, по крайней мере больше не наблюдал)
 
Meat писал (а) >>

Ну вообще-то ошибка 130 возникала совсем не из-за этого, поэтому весьма странно что она исчезла после добавления sl!=OrderStopLoss(). Тут должна была исчезнуть ошибка 1. А ошибка 130 возникала из-за неправильной проверки на STOPLEVEL. Вот обрати внимание как xrust использует эту проверку. Там используется ЦЕНА ЗАКРЫТИЯ ордера (т.е. Bid для buy или Ask для sel), а не как у тебя (цена открытия ордера).

Но вообще эту проверку можно было написать гораздо проще и короче, без учёта OrderType:

Конечно тут подразумевается что уже выполнена предыдущая часть кода по установке значения sl.

Если могут использоваться ордера с разными символами, то тогда разумеется вместо Point надо использовать переменную point, присвоив ей значение MarketInfo(OrderSymbol(),MODE_POINT)

Помогите советника доработать, тоже ошибку выдает 130 и ещё какую-то.

Трейлинг-стоп не могу нормально сделать, чтобы оптимизировать его.

Файлы:
grider2_7.mq4  26 kb
 
поищите Вы не первый кто это делает, допустим вот варианты 'Библиотека функций и советники для трейлинга / Юрий Дзюбан'
 

Ой, я в прошлом своём посте ошибку сделал в коде. Там вместо знака "<" должно быть ">="

 
Prival писал (а) >>
поищите Вы не первый кто это делает, допустим вот варианты 'Библиотека функций и советники для трейлинга / Юрий Дзюбан'

Большое спасибо всем за советы,после парочки ночей вроде довёл эксперта до ума... Хотелось бы сказать пару слов об этой библиотеке функций, у меня при использовании трала по теням пишет ошибку 1, вот часть исходного кода для селл ордеров

 if (OrderType()==OP_SELL)
      {
      for(i=1;i<=bars_n;i++)
         {
         if (i==1) new_extremum = iHigh(Symbol(),tmfrm,i);
         else 
         if (new_extremum<iHigh(Symbol(),tmfrm,i)) new_extremum = iHigh(Symbol(),tmfrm,i);
         }         
           
      // если тралим и в зоне убытков
      if (trlinloss==true)
         {
         // если найденное значение "лучше" текущего стоплосса позиции, переносим 
         if ((((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderStopLoss()) || (OrderStopLoss()==0)) && (new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }
      else
         {
         // если новый стоплосс не только лучше предыдущего, но и курса открытия позиции
         if ((((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderStopLoss()) || (OrderStopLoss()==0)) && ((new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point)<OrderOpenPrice()) && (new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point>Ask+MarketInfo(Symbol(),MODE_STOPLEVEL)*Point))
         if (!OrderModify(ticket,OrderOpenPrice(),new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point,OrderTakeProfit(),OrderExpiration()))
         Print("Не удалось модифицировать ордер №",OrderTicket(),". Ошибка: ",GetLastError());
         }      
      }


дописал условие перед фунцией модификации

if (NormalizeDouble(new_extremum + (indent + MarketInfo(Symbol(),MODE_SPREAD))*Point,Digits)!=NormalizeDouble(OrderStopLoss(),Digits))

ошибка исчезла, причём только после нормализации значений нового и старого СЛ. Вот это условие

if (new_extremum + (indent + MarketInfo(Symbol()!=OrderStopLoss())
как ни странно пропускало 2 одинаковых значения о_О
Причина обращения: