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 "Hidden TrailingStop" 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);       // GET INDEX OF THE BAR AT ORDER OPENING (OR IF YOU PREFER "BAR SHIFT NUMBER")
                  //   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)]; //GET HIGHEST PRICE SINCE ORDER OPENING
                  //   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);           // GET INDEX OF THE BAR AT ORDER OPENING (OR IF YOU PREFER "BAR SHIFT NUMBER")      
             //  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)];    //GET LOWEST PRICE SINCE ORDER OPENING 
            //   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);        // GET INDEX OF THE BAR AT ORDER OPENING (OR IF YOU PREFER "BAR SHIFT NUMBER")
                  //   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)];     //GET HIGHEST PRICE SINCE ORDER OPENING
                  //   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);        // GET INDEX OF THE BAR AT ORDER OPENING (OR IF YOU PREFER "BAR SHIFT NUMBER")
             //  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)];     //GET LOWEST PRICE SINCE ORDER OPENING
            //   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 to 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 look correct  to me..
 
any input welcome.


ps: if i uncomment these lines and use "normal"  TrailingStop  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);
                    //}
                 //}
              //}


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

// THESE 2 LINES ARE WHAT IS SUPPOSED TO WORK AS HIDDEN TRAILING STOP
 
"the Hidden Trailing Stop i tried to 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 think it is best you post the entire actual code you are using, because that will help us find the problem. Then again,
that is a personal decision and I really should not demand to see your actual code. Therefore, I can only give my best guess based on whats likely causing this.

Now, the strategy tester has several settings for spread to use during backtest, which you will find just above the "Optimization"
checkbox. It is likely that you may have intentionally or unintentionally, set this to use a constant spread while backtesting. 
This means that if your code has no other errors and the spread setting you have on the strategy tester(e.g. 2,5...) is less than your maximum 
allowed spread in your code, then your code always run. In real life , however, spread is not constant, unless your broker is a Market Maker
 or some other special arrangement. So, when you attempt to run your code live the spread at that time might be higher than your maximum.
Based on what I see in your code, the current order will be closed if the current spread is equal to or higher than 20. Which leads me to 
another question: Why would you open an order then if the spread is higher than the max spread? I think you should only open an order if 

the spread is less than max spread. Your method will almost certainly blow your account.


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

Since you are sure where the problem is, you can see and confirm it yourself by looking at the actual values in the variables using the attached tool below.


I suggest you start by placing the below code just above the two OrderClose:

BreakPoint("","","",true,"(OrderOpenPrice()-Ask>=HiddenStop*MyPoint)",DoubleToStr((OrderOpenPrice()-Ask>=HiddenStop*MyPoint)),"(MarketInfo(Symbol(), MODE_SPREAD)",DoubleToStr((MarketInfo(Symbol(), MODE_SPREAD)) );//for OP_BUY section
BreakPoint("","","",true,"(Bid-OrderOpenPrice()>=HiddenStop*MyPoint)",DoubleToStr((Bid-OrderOpenPrice()>=HiddenStop*MyPoint)),"(MarketInfo(Symbol(), MODE_SPREAD)",DoubleToStr((MarketInfo(Symbol(), MODE_SPREAD)) );//for OP_SELL section



This should help you do less guessing as you code.  Remember to add 
#include <BreakPoint.mqh>//you can comment this out when live
at the top section of your code just below "#property strict".
Files:
BreakPoint.mqh  10 kb