Stuck with Hidden TrailingStop

 

Hi,
 
it's been a month i'm stuck with this problem.
 
I found nowhere on Internet how to set up a hidden trailing stop so i tried to code it myself.
 
there is an error in my code.
 
here is my bot:

//+------------------------------------------------------------------+
//                                                                   |
//                                                           autobot |
//                                                                   |
//+------------------------------------------------------------------+

extern int MagicNumber=10001;
extern double Lots =0.05;
extern double StopLoss=50;     //25/30***      //25//30//20  ej  30  55  45
extern double TakeProfit=55;   //55***      //50//55//55  ej 115  95  95
extern int TrailingStop=33;    //35/45***   //35//35//35  ej  90  95
extern int HiddenStop=23;           //17

extern double Trailing_trigger_move = 35;

extern bool AutoBot=false;
extern int atr_avgst=55;
extern int atr_avgtp=55;
//extern int atr_avgts=55;
extern int multiplicatorsl=3;     //ej  9
extern int multiplicatortp=15;    //16 17 18 19* 20 ej 25,23,21,22
//extern int multiplicatorts=10;
    
extern int MaxSpread=20; //SPREAD in points
extern int Slippage=20;  // in points


//+------------------------------------------------------------------+
//    expert start function
//+------------------------------------------------------------------+
int BarsCount = 0;

int start()
{


VARIABLE DECLARATION HERE



   double atr_sl;
   double atr_tp;
   //double atr_ts;
   double multiplicatorsl1;
   double multiplicatortp2;
   //double multiplicatorts3;
   double MyPoint=Point;
   double factor=10000;
  if(Digits==3 || Digits==5) MyPoint=Point*10; 
  if(Digits==3 || Digits==2) factor=10000/100;
  
  
  
VARIABLES HERE   




     multiplicatorsl1=multiplicatorsl*factor;
     multiplicatortp2=multiplicatortp*factor;
     //multiplicatorts3=multiplicatorts*10000;
    atr_sl=iATR(NULL,0,atr_avgst,1)*multiplicatorsl1;
    atr_tp=iATR(NULL,0,atr_avgtp,1)*multiplicatortp2;
    //atr_ts=iATR(NULL,0,atr_avgts,1)*multiplicatorts3;
    



    
          if (AutoBot==true    )
          {  
          StopLoss=atr_sl;
           TakeProfit=atr_tp;
          //TrailingStop=atr_ts;
          }
         
            if (OPEN RULE ) 
            {
              Print("spread too high ",MarketInfo(Symbol(),MODE_SPREAD));
              BarsCount = Bars;
              return(0);
            }
         
            if (OPEN RULE) 
            {
              Print("spread too high ",MarketInfo(Symbol(),MODE_SPREAD));
              BarsCount = Bars;
              return(0);
            }
            
            if (OPEN RULE 2) 
            {
              Print("spread too high ",MarketInfo(Symbol(),MODE_SPREAD));
              BarsCount = Bars;
              return(0);
            }
         
            if (OPEN RULE 2) 
            {
              Print("spread too high ",MarketInfo(Symbol(),MODE_SPREAD));
              BarsCount = Bars;
              return(0);
            }
        
  
  double TheStopLoss=0;
  double TheTakeProfit=0;
    //if( TotalOrdersCount()==0)
   if( TotalOpenOrders() == 0  && Bars>BarsCount) 
  {
     int result=0;
     if(OPEN BUY RULE HERE)
     {
        result=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,"AutoBot",MagicNumber,0,Blue);
        if(result>0)
        {
         TheStopLoss=0;
         TheTakeProfit=0;
         if(TakeProfit>0) TheTakeProfit=Ask+TakeProfit*MyPoint;
         if(StopLoss>0) TheStopLoss=Ask-StopLoss*MyPoint;
         OrderSelect(result,SELECT_BY_TICKET);
         OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(TheStopLoss,Digits),NormalizeDouble(TheTakeProfit,Digits),0,Green);         
         BarsCount = Bars;
        }
        return(0);
     }
     if(OPEN SELL RULE HERE)
     {
        result=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,"AutoBot",MagicNumber,0,Red);
        if(result>0)
        {
         TheStopLoss=0;
         TheTakeProfit=0;
         if(TakeProfit>0) TheTakeProfit=Bid-TakeProfit*MyPoint;
         if(StopLoss>0) TheStopLoss=Bid+StopLoss*MyPoint;
         OrderSelect(result,SELECT_BY_TICKET);
         OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(TheStopLoss,Digits),NormalizeDouble(TheTakeProfit,Digits),0,Green);
         BarsCount = Bars;         
        }
        return(0);
     }
     if(OPEN BUY RULE 2 HERE )    
     {
        result=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,"AutoBot",MagicNumber,0,Blue);
        if(result>0)
        {
         TheStopLoss=0;
         TheTakeProfit=0;
         if(TakeProfit>0) TheTakeProfit=Ask+TakeProfit*MyPoint;
         if(StopLoss>0) TheStopLoss=Ask-StopLoss*MyPoint;
         OrderSelect(result,SELECT_BY_TICKET);
         OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(TheStopLoss,Digits),NormalizeDouble(TheTakeProfit,Digits),0,Green);         
         BarsCount = Bars;
        }
        return(0);
     }
     if(OPEN SELL RULE 2 HERE) 
     {
        result=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,"AutoBot",MagicNumber,0,Red);
        if(result>0)
        {
         TheStopLoss=0;
         TheTakeProfit=0;
         if(TakeProfit>0) TheTakeProfit=Bid-TakeProfit*MyPoint;
         if(StopLoss>0) TheStopLoss=Bid+StopLoss*MyPoint;
         OrderSelect(result,SELECT_BY_TICKET);
         OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(TheStopLoss,Digits),NormalizeDouble(TheTakeProfit,Digits),0,Green);
         BarsCount = Bars;         
        }
        return(0);
     }
     
  }
  
  for(int cnt=0;cnt<OrdersTotal();cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&   
         OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber 
         )  
        {
         if(OrderType()==OP_BUY)  
           {
           
                datetime  SHIFT=OrderOpenTime();    // get order opening time
                  //   Print("open time for the current order ",TimeToStr(SHIFT));   
        
                    double BarsAfterOpen=iBarShift(NULL,Period(),OrderOpenTime(),false);
                  //   Print("index of the bar for the time ",TimeToStr(SHIFT)," is ",iBarShift(NULL,Period(),OrderOpenTime(),false));
             
                    double PeriodHighest = High[iHighest(Symbol(),0,MODE_HIGH,BarsAfterOpen,0)]; 
                  //   Print("periodHighest",PeriodHighest);

              if ((MarketInfo(Symbol(), MODE_SPREAD)<=MaxSpread && (Digits == 5 || Digits == 4) && ((EXIT RULE HERE)  || (DayOfWeek()==5 && Hour()>=21) 
              || (OrderOpenPrice()-Ask>=HiddenStop*MyPoint) || ((PeriodHighest-OrderOpenPrice()>Trailing_trigger_move*MyPoint) && (Ask<PeriodHighest-TrailingStop*MyPoint)) )))  // close buy rule   || Ask<=TrStop)
              {
                   OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Red);
              }
       
           // if(TrailingStop>0)  
            //  {                 
              // if(Bid-OrderOpenPrice()>MyPoint*TrailingStop)
                // {
                  //if(OrderStopLoss()<Bid-MyPoint*TrailingStop)
                    //{
                     //OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*MyPoint,OrderTakeProfit(),0,Green);
                     //return(0);
                    //}
                 //}
              //}
           }
         else 
           {
             
             datetime  SHIFT2=OrderOpenTime();    // get order opening time
              // Print("open time for the current order ",TimeToStr(SHIFT2));   
        
             double BarsAfterOpen2=iBarShift(NULL,Period(),OrderOpenTime(),false);
             //  Print("index of the bar for the time ",TimeToStr(SHIFT2)," is ",iBarShift(NULL,Period(),OrderOpenTime(),false));
             
             double PeriodLowest  =  Low[iLowest(Symbol(),0,MODE_LOW,BarsAfterOpen2,0)];
            //   Print("periodlowest",PeriodLowest);
            //  Print("BID",Bid);
            //   Print("PeriodLowest+TrailingStop*MyPoint", PeriodLowest+TrailingStop*MyPoint);
            //   Print("OrderOpenPrice()-PeriodLowest", OrderOpenPrice()-PeriodLowest);


                if ((MarketInfo(Symbol(), MODE_SPREAD)<=MaxSpread && (Digits == 5 || Digits == 4) && ((EXIT RULE HERE)  || (DayOfWeek()==5 && Hour()>=21) 
                || (Bid-OrderOpenPrice()>=HiddenStop*MyPoint) || ((OrderOpenPrice()-PeriodLowest>Trailing_trigger_move*MyPoint) && (Bid>PeriodLowest+TrailingStop*MyPoint))  )))  // close sell rule  || Bid>=TrStop) 
                {
                   OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Red);
                }
        
           // if(TrailingStop>0)  
             // {                 
              // if((OrderOpenPrice()-Ask)>(MyPoint*TrailingStop))
               //  {
                //  if((OrderStopLoss()>(Ask+MyPoint*TrailingStop)) || (OrderStopLoss()==0))
                  //  {
                   //  OrderModify(OrderTicket(),OrderOpenPrice(),Ask+MyPoint*TrailingStop,OrderTakeProfit(),0,Red);
                    // return(0);
                    //}
                 //}
              //}
           }
        }
     }
   return(0);
}

        
int TotalOpenOrders()
{
   int total_orders = 0;

   for(int order = 0; order < OrdersTotal(); order++) 
   {
      if(OrderSelect(order,SELECT_BY_POS,MODE_TRADES)==false) break;

      if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol)
         {
            total_orders++;
         }
   }

   return(total_orders);
}


the section making trouble is the exit rules section :


   for(int cnt=0;cnt<OrdersTotal();cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&   
         OrderSymbol()==Symbol() &&
         OrderMagicNumber()==MagicNumber 
         )  
        {
         if(OrderType()==OP_BUY)  
           {
           
                datetime  SHIFT=OrderOpenTime();    // get order opening time
                  //   Print("open time for the current order ",TimeToStr(SHIFT));   
        
                    double BarsAfterOpen=iBarShift(NULL,Period(),OrderOpenTime(),false);
                  //   Print("index of the bar for the time ",TimeToStr(SHIFT)," is ",iBarShift(NULL,Period(),OrderOpenTime(),false));
             
                    double PeriodHighest = High[iHighest(Symbol(),0,MODE_HIGH,BarsAfterOpen,0)]; 
                  //   Print("periodHighest",PeriodHighest);

              if ((MarketInfo(Symbol(), MODE_SPREAD)<=MaxSpread && (Digits == 5 || Digits == 4) && ((EXIT RULE HERE)  || (DayOfWeek()==5 && Hour()>=21) 
              || (OrderOpenPrice()-Ask>=HiddenStop*MyPoint) || ((PeriodHighest-OrderOpenPrice()>Trailing_trigger_move*MyPoint) && (Ask<PeriodHighest-TrailingStop*MyPoint)) )))  // close buy rule   || Ask<=TrStop)
              {
                   OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Red);
              }
       
           // if(TrailingStop>0)  
            //  {                 
              // if(Bid-OrderOpenPrice()>MyPoint*TrailingStop)
                // {
                  //if(OrderStopLoss()<Bid-MyPoint*TrailingStop)
                    //{
                     //OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*MyPoint,OrderTakeProfit(),0,Green);
                     //return(0);
                    //}
                 //}
              //}
           }
         else 
           {
             
             datetime  SHIFT2=OrderOpenTime();    // get order opening time
              // Print("open time for the current order ",TimeToStr(SHIFT2));   
        
             double BarsAfterOpen2=iBarShift(NULL,Period(),OrderOpenTime(),false);
             //  Print("index of the bar for the time ",TimeToStr(SHIFT2)," is ",iBarShift(NULL,Period(),OrderOpenTime(),false));
             
             double PeriodLowest  =  Low[iLowest(Symbol(),0,MODE_LOW,BarsAfterOpen2,0)];
            //   Print("periodlowest",PeriodLowest);
            //  Print("BID",Bid);
            //   Print("PeriodLowest+TrailingStop*MyPoint", PeriodLowest+TrailingStop*MyPoint);
            //   Print("OrderOpenPrice()-PeriodLowest", OrderOpenPrice()-PeriodLowest);


                if ((MarketInfo(Symbol(), MODE_SPREAD)<=MaxSpread && (Digits == 5 || Digits == 4) && ((EXIT RULE HERE)  || (DayOfWeek()==5 && Hour()>=21) 
                || (Bid-OrderOpenPrice()>=HiddenStop*MyPoint) || ((OrderOpenPrice()-PeriodLowest>Trailing_trigger_move*MyPoint) && (Bid>PeriodLowest+TrailingStop*MyPoint))  )))  // close sell rule  || Bid>=TrStop) 
                {
                   OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Red);
                }
        
           // if(TrailingStop>0)  
             // {                 
              // if((OrderOpenPrice()-Ask)>(MyPoint*TrailingStop))
               //  {
                //  if((OrderStopLoss()>(Ask+MyPoint*TrailingStop)) || (OrderStopLoss()==0))
                  //  {
                   //  OrderModify(OrderTicket(),OrderOpenPrice(),Ask+MyPoint*TrailingStop,OrderTakeProfit(),0,Red);
                    // return(0);
                    //}
                 //}
              //}
           }
        }
     }
   return(0);

the Hidden Trailing Stop i tried t code doesn't work in live, it works well in strategy tester using "open prices only" but using "every tick" fails.
 
it just opens one order and close it instantaneously....
 
I see no reason for this to happen, i am really clueless... I tried to debug it using "Print" and every output looks correct  to me..
 
any input welcome.


ps: if i uncomment these TrailingStop sections everything works fine:

        // if(TrailingStop>0)  
            //  {                 
              // if(Bid-OrderOpenPrice()>MyPoint*TrailingStop)
                // {
                  //if(OrderStopLoss()<Bid-MyPoint*TrailingStop)
                    //{
                     //OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*MyPoint,OrderTakeProfit(),0,Green);
                     //return(0);
                    //}
                 //}
              //}

        // if(TrailingStop>0)  
             // {                 
              // if((OrderOpenPrice()-Ask)>(MyPoint*TrailingStop))
               //  {
                //  if((OrderStopLoss()>(Ask+MyPoint*TrailingStop)) || (OrderStopLoss()==0))
                  //  {
                   //  OrderModify(OrderTicket(),OrderOpenPrice(),Ask+MyPoint*TrailingStop,OrderTakeProfit(),0,Red);
                    // return(0);
                    //}
                 //}
              //}

ps2: if i remove these lines everything works well too:

|| ((PeriodHighest-OrderOpenPrice()>Trailing_trigger_move*MyPoint) && (Ask<PeriodHighest-TrailingStop*MyPoint))
|| ((OrderOpenPrice()-PeriodLowest>Trailing_trigger_move*MyPoint) && (Bid>PeriodLowest+TrailingStop*MyPoint))

// THESE 2 LINES ARE WHAT IS SUPPOSED TO WORK AS HIDDEN TRAILING STOP


ps3: for those who think it's useless to include a hidden TrailingStop in a bot please just don't post in this thread.

 

Really ? Nobody for such a simple problem ?

I'm pretty sure i did a very stupid mistake... and the error can be very easy to spot for skilled coders...

It's just about variables in use within these 2 rules:

|| ((PeriodHighest-OrderOpenPrice()>Trailing_trigger_move*MyPoint) && (Ask<PeriodHighest-TrailingStop*MyPoint))

|| ((OrderOpenPrice()-PeriodLowest>Trailing_trigger_move*MyPoint) && (Bid>PeriodLowest+TrailingStop*MyPoint))
 
ask in right forum : MQL 4
 
Code2219 or probably 2319:
ask in right forum : MQL 4
ok i did, if moderators come around, you can delete this thread thanx.
 
kikoolol:
ok i did, if moderators come around, you can delete this thread thanx.
Try counting down with the orders, since you change them inside the loop:

Instead of
for(int cnt=0;cnt<OrdersTotal();cnt++)
code
for(int cnt=OrdersTotal()-1;cnt>=0;cnt--)
 
Thanks for your reply but same result:|
 
You have at least 2 places to change.

Maybe there still is a problem, but surely that is a step forward.
 

From looking at the close condition, EXIT RULE is part of several OR conditions and not of AND conditions,
It is part of the spread (when spread is less then MaxSpread and digits >=4)

    if ((MarketInfo(Symbol(), MODE_SPREAD)<=MaxSpread && (Digits == 5 || Digits == 4) && ((EXIT RULE HERE)  |


And one of those parts is true 

(DayOfWeek()==5 && Hour()>=21) 
   || (Bid-OrderOpenPrice()>=HiddenStop*MyPoint) 
   || ((OrderOpenPrice()-PeriodLowest>Trailing_trigger_move*MyPoint)   
     && (Bid>PeriodLowest+TrailingStop*MyPoint))  )))  // close sell rule  || Bid>=TrStop) 
                {
                   OrderClose(OrderTi
cket(),OrderLots(),OrderClosePrice(),Slippage,Red)

So just put the EXIT RULE as a single AND component with all the other rules, meaning it will exit only when EXIT RULE is true.



 
Amir Yacoby:

From looking at the close condition, EXIT RULE is part of several OR conditions and not of AND conditions,
It is part of the spread (when spread is less then MaxSpread and digits >=4)


And one of those parts is true 

So just put the EXIT RULE as a single AND component with all the other rules, meaning it will exit only when EXIT RULE is true.



 same result, in fact i did try already :| but i'm not sure to understand what you mean by "And one of those parts is true "

of course if one of those parts is true

(DayOfWeek()==5 && Hour()>=21) 
   || (Bid-OrderOpenPrice()>=HiddenStop*MyPoint) 
   || ((OrderOpenPrice()-PeriodLowest>Trailing_trigger_move*MyPoint)   
     && (Bid>PeriodLowest+TrailingStop*MyPoint))

then i want the order to close, and remember if i keep only :

(DayOfWeek()==5 && Hour()>=21) 
   || (Bid-OrderOpenPrice()>=HiddenStop*MyPoint) 

it works well on "every tick".

I'm really stuck. the weirdest part is that backtesting it using "open prices only" works well...

 
kikoolol:

 same result, in fact i did try already :| but i'm not sure to understand what you mean by "And one of those parts is true "

of course if one of those parts is true

then i want the order to close, and remember if i keep only :

it works well on "every tick".

I'm really stuck. the weirdest part is that backtesting it using "open prices only" works well...

Obviously the problem is in the first part of
   || ((OrderOpenPrice()-PeriodLowest>Trailing_trigger_move*MyPoint)   
     && (Bid>PeriodLowest+TrailingStop*MyPoint))
OrderOpenPrice() is a fixed price. Trailing_trigger_move*MyPoint is fixed as well. So, what you achieve here is when the price first moves more the Trailing_trigger_move from the open price - you close it. This is not trailing of the price, but is a take profit of Trailing_trigger_move points.
 
Amir Yacoby:
Obviously the problem is in the first part ofOrderOpenPrice() is a fixed price. Trailing_trigger_move*MyPoint is fixed as well. So, what you achieve here is when the price first moves more the Trailing_trigger_move from the open price - you close it. This is not trailing of the price, but is a take profit of Trailing_trigger_move points.

thanx for your help, but you are wrong on this point. if that was the case the problem should manifest using "open price only" in the strategy tester.

and even if the logic was wrong then at least it would wait  for the price to move the amount of pips according to "Trailing_trigger_move" variable.

What it does here is that it closes the order INSTANTANEOUSLY.

"open prices only" backtest, you can see the trailing stop is triggered on the last 2 trades (forget about the others) :


this is normal behavior of my bot.

Now have a look running "every tick" backtest with exactly the same settings:



when backtesting using "every tick" the values in the variables are messed up :/

i now think the problem reside in the iBarShift() function, probably something i misunderstood about it.

Reason: