Help, TrailingStop function cannot be executed in my EA

 

Hi Guys,

I created an EA but TrailStop() function cannbe be executed in the main fuction. I checked several times but couldn't find out the bug. Could you help me debug it? Thanks...

My thread is simple. No profit target set when sending out an order and trigger TrailStop() when getting 40 pips profit and move the stoploss to 15 pips below current market price. Pls give me a hand ^_^

extern double Trailtirger=40;
extern double Trailstop=15;
extern int MAPeriod=14;
extern double Buffer=3;
extern double Slippage=5;
extern double Lot=0.1;
extern int Magic=8848;
extern bool SingleTrade = true;



//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   double multiplier;
   if(Digits == 2 || Digits == 4) multiplier = 1;
   if(Digits == 3 || Digits == 5) multiplier = 10;
   if(Digits == 6) multiplier = 100; 
   Trailtirger*=multiplier;
   Buffer*=multiplier;
   Trailstop*=multiplier;
   Slippage*=multiplier;

   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
  
/*
Fuction list:
Doestradeexist();
Openposition();
TrailStop();
*/

void Openposition()
  {
  double ma, previousopen,previousclose, previoushigh, previouslow,buyprice,sellprice;
  ma=iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,1); 
  previousclose=Close[1];
  previousopen=Open[1];
  previoushigh=High[1];
  previouslow=Low[1];
  buyprice=NormalizeDouble(previoushigh+Buffer*Point,Digits);
  sellprice=NormalizeDouble(previouslow-Buffer*Point,Digits);
  
  if ( previousclose>ma && previousopen<ma ) 
  {
    if (OrderSend(Symbol(),OP_BUYSTOP,Lot,buyprice,Slippage,sellprice,0,"",Magic,TimeCurrent()+Period()*60,Green)>0)
      {
      Print("Opened a long order#" + DoubleToStr(OrderTicket(),0));
      }
      else
      {
      Print("Error opened a long order, error code:" + GetLastError());
      } 
  }
  if ( previousclose<ma && previousopen>ma )
  {
    if (OrderSend(Symbol(),OP_SELLSTOP,Lot,sellprice,Slippage,buyprice,0,"",Magic,TimeCurrent()+Period()*60,Red)>0)
      {
      Print("Opened a short order#" + DoubleToStr(OrderTicket(),0));
      }
      else
      {
      Print("Error opened a short order, error code:" + GetLastError());
      }
  }
  }
  
  


bool DoesTradeExist()
{
   
   int TicketNo = 0;
   if (!SingleTrade) return(false);
   
   if (OrdersTotal() == 0) return(false);
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      
      if (OrderMagicNumber()==Magic && OrderSymbol() == Symbol() )      
      {
         TicketNo = OrderTicket();
         return(true);         
      }     
   }

   return(false);

}




void TrailStop()
{
  bool result;
  double sl=OrderStopLoss();
  
  for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
  {
    if(!OrderSelect(cc,SELECT_BY_POS)) continue;
    Print("order selected in CPT:", OrderTicket()-1);
    if (OrderType() == OP_BUY) 
    {
     Print("if (OrderType() == OP_BUY) ");
      if ( (Bid - OrderOpenPrice()) >= (Trailtirger*Point)) 
      {
       Print("if ( (Bid - OrderOpenPrice()) >= (Trailtirger*Point))");
        if (OrderStopLoss() == 0) sl = OrderOpenPrice();
        if (OrderStopLoss() < (Bid - (Trailstop*Point)))
          {
            Print("if (OrderStopLoss() < (Bid - (Trailstop*Point)))");
            sl=Bid - (Trailstop*Point);
            result=OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(),0, Tan);  
               if (result)
               {
                  Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl);
               }
               else
               {
                  Print(OrderSymbol(), " order modify failed with error:",GetLastError());
               }  
          }
       }
     }
    
   if (OrderType() == OP_SELL) 
    {
      if ((OrderOpenPrice()-Ask)>=(Trailtirger*Point))
      {
        if (OrderStopLoss() == 0) sl = OrderOpenPrice();
        if (OrderStopLoss() > (Ask + (Trailstop*Point)))
          {
            sl=Ask + (Trailstop*Point);
            result=OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(),0, Yellow);  
               if (result)
               {
                  Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl);
               }
               else
               {
                  Print(OrderSymbol(), " order modify failed with error:",GetLastError());
               }  
          }
       }
     }
    
  }
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   if (DoesTradeExist()) return(0);
   Openposition();
   TrailStop();
   return(0);
  }
//+------------------------------------------------------------------+
 
  1.  if (DoesTradeExist()) return(0);
       Openposition();
       TrailStop();
    If a trade is open, you return so no trailing
  2. if(Digits == 3 || Digits == 5) multiplier = 10;
       if(Digits == 6) multiplier = 100; 
       Trailtirger*=multiplier;
       Buffer*=multiplier;
       Trailstop*=multiplier;
       Slippage*=multiplier;
    While EAs must adjust for 5 digit brokers (TP, SL, AND slippage) the above will NOT work. Each time you refresh the chart, change TF/pair, or change EAs parameter you get an deinit/init cycle. Therefor Trailtirger becomes 40, 400, 4000 etc. Instead I treat all externals as constants and multiply where used
    //++++ These are adjusted for 5 digit brokers.
    int     pips2points;    // slippage  3 pips    3=points    30=points
    double  pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
    int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
    int     init(){
        if (Digits == 5 || Digits == 3){    // Adjust for five (5) digit brokers.
                    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
        } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }
        // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
    

  3.   if (OrderSend(Symbol(),OP_SELLSTOP,Lot,sellprice,Slippage,buyprice,0,"",Magic,TimeCurrent()+Period()*60,Red)>0)
          {
          Print("Opened a short order#" + DoubleToStr(OrderTicket(),0));
    On ECN brokers you must open the order and THEN set stops. This may not work for SELLSTOPs. Your print statement won't work because you never select the opened order so OrderTicket() is bogus.
    int ticket = OrderSend(Symbol(), OP_SELLSTOP, Lot, sellprice, Slippage, buyprice, 0,
                           "", Magic, TimeCurrent()+Period()*60, Red);
    if (ticket > 0){
        OrderSelect(oo.ticket,SELECT_BY_TICKET))
        Print("Opened a short order#" + DoubleToStr(OrderTicket(),0));

 
WHRoeder:
  1. If a trade is open, you return so no trailing
  2. While EAs must adjust for 5 digit brokers (TP, SL, AND slippage) the above will NOT work. Each time you refresh the chart, change TF/pair, or change EAs parameter you get an deinit/init cycle. Therefor Trailtirger becomes 40, 400, 4000 etc. Instead I treat all externals as constants and multiply where used
  3. On ECN brokers you must open the order and THEN set stops. This may not work for SELLSTOPs. Your print statement won't work because you never select the opened order so OrderTicket() is bogus.


Thanks but please see my double checking as below. It doesn't tackle the problem yet.

1. DoesTradeExist() is used to detect if any open order exists already. This EA is designed only for single trade. So this function is a necessity and will be no impact for execution of Trailing stop if no open order available before that.

2. Mutiplier works ok for different digits. It works well in my other EAs.

3. Ordersend() return to an integrity number, so OrderSend(Symbol(),OP_BUYSTOP,Lot,buyprice,Slippage,sellprice,0,"",Magic,TimeCurrent()+Period()*60,Green)>0 should be OK. To be specific, BUYSTOP is ought to retun 5 if executed.

 
  1. If DoesTradeExist returns true, you return from start, so the TrailStop() IS NEVER CALLED.
  2. Your multiplier is NOT OK, Just right click -> refresh several times and then watch where it puts the stops the next time it opens.
  3. OrderSend if fine BUT the Print statement is not. No OrderSelect(ticket) then OrderTicket() is Bogus.
 

Thanks WhRoeder!! I will try again^_^

 

Hi Roeder, I make some modification per your instructions as below and it works now. Thanks again...

extern double Trailtriger=40;
extern double Trailstop=15;
extern int MAPeriod=14;
extern double Buffer=3;
extern double Slippage=5;
extern double Lot=0.1;
extern int Magic=8848;
extern bool SingleTrade = true;



//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   if(Digits == 3 || Digits == 5)
   {
     Trailtriger=400;
     Trailstop=150;
     Buffer=30;
     Slippage=50;
   }
   else
   {
     Trailtriger=40;
     Trailstop=15;
     Buffer=3;
     Slippage=5;  
   }

   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
  
/*
Fuction list:
Doestradeexist();
Openposition();
TrailStop();
*/


bool DoesTradeExist()
{
   
   int TicketNo = 0;
   if (!SingleTrade) return(false);
   
   if (OrdersTotal() == 0) return(false);
   
   for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
   {
      if (!OrderSelect(cc,SELECT_BY_POS)) continue;
      
      if (OrderMagicNumber()==Magic && OrderSymbol() == Symbol() )      
      {
         TicketNo = OrderTicket();
         return(true);         
      }     
   }

   return(false);

}



void Openposition()
{
  double ma, previousopen,previousclose, previoushigh, previouslow,buyprice,sellprice;
  ma=iMA(NULL,0,MAPeriod,0,MODE_SMA,PRICE_CLOSE,1); 
  previousclose=Close[1];
  previousopen=Open[1];
  previoushigh=High[1];
  previouslow=Low[1];
  buyprice=NormalizeDouble(previoushigh+Buffer*Point,Digits);
  sellprice=NormalizeDouble(previouslow-Buffer*Point,Digits);
  int ticket1, ticket2;
  if (DoesTradeExist()) return;
  if ( previousclose>ma && previousopen<ma ) 
  {
    ticket1=OrderSend(Symbol(),OP_BUYSTOP,Lot,buyprice,Slippage,sellprice,0,"",Magic,TimeCurrent()+Period()*60,Green);
    if (ticket1>0)
      {
      Print("Opened a long order#" + DoubleToStr(OrderTicket(),0));
      }
      else
      {
      Print("Error opened a long order, error code:" + GetLastError());
      } 
  }
  if ( previousclose<ma && previousopen>ma )
  {
    ticket2=OrderSend(Symbol(),OP_SELLSTOP,Lot,sellprice,Slippage,buyprice,0,"",Magic,TimeCurrent()+Period()*60,Red);
      if (ticket2>0)
      {
      Print("Opened a short order#" + DoubleToStr(OrderTicket(),0));
      }
      else
      {
      Print("Error opened a short order, error code:" + GetLastError());
      }
  }
}
  
  


void TrailStop()
{
  bool result;
  double sl=OrderStopLoss();
  
  for (int cc = OrdersTotal() - 1; cc >= 0 ; cc--)
  {
    //if(!OrderSelect(cc,SELECT_BY_POS)) continue;
    if(OrderSelect(cc,SELECT_BY_POS,MODE_TRADES)==false) continue;
    if (OrderType() == OP_BUY) 
    {
      if ( (Bid - OrderOpenPrice()) >= (Trailtriger*Point)) 
      {
        if (OrderStopLoss() == 0) sl = OrderOpenPrice();
        if (OrderStopLoss() < (Bid - (Trailstop*Point)))
          {
            sl=Bid - (Trailstop*Point);
            result=OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(),0, Tan);  
               if (result)
               {
                  Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl);
               }
               else
               {
                  Print(OrderSymbol(), " order modify failed with error:",GetLastError());
               }  
          }
       }
     }
    
   if (OrderType() == OP_SELL) 
    {
      if ((OrderOpenPrice()-Ask)>=(Trailtriger*Point))
      {
        if (OrderStopLoss() == 0) sl = OrderOpenPrice();
        if (OrderStopLoss() > (Ask + (Trailstop*Point)))
          {
            sl=Ask + (Trailstop*Point);
            result=OrderModify(OrderTicket(), OrderOpenPrice(), sl, OrderTakeProfit(),0, Yellow);  
               if (result)
               {
                  Print("Trailing stop updated: ", OrderSymbol(), ": SL ", sl);
               }
               else
               {
                  Print(OrderSymbol(), " order modify failed with error:",GetLastError());
               }  
          }
       }
     }
    
  }
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   Openposition();
   TrailStop();
   return(0);
  }
//+------------------------------------------------------------------+
 
morken:

Hi Roeder, I make some modification per your instructions as below and it works now. Thanks again...

   if(Digits == 3 || Digits == 5)
   {
     Trailtriger=400;
     Trailstop=150;

Except now you can not optimize those externals in the tester.
Reason: