Trailing Stop not working in STP Broker

 

Hi all,

 I've a workable EA with no problems in an ECN Broker, but on a STP Broker the Trailing Stop do not work. A error 4051 and invalid lots amount for order send function has been returned but can't figure out how to get from here.

following is the code for TrailingStop. Any clues here ? 

void Trail()
  { 
       int TrailingStop =1;
       double StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL)*Point;
                
      for(int OrderCounter = 0; OrderCounter <= OrdersTotal()-1; OrderCounter++)
         {//23
        if(!OrderSelect(OrderCounter,SELECT_BY_POS))continue;
         if(OrderType()==OP_BUY && OrderSymbol()== Symbol() 
            && OrderMagicNumber()== MagicNumber)
            
            {
             if(TrailingStop < StopLevel)
               {
                TrailingStop = StopLevel;                                   
            {//24
            if(OrderStopLoss() < (MarketInfo(Symbol(),MODE_BID) - TrailingStop * pips2dbl) && MarketInfo(Symbol(),MODE_BID) - OrderOpenPrice() >= (MinimumProfit*pips2dbl)) 
               {//25
               OrderModify(OrderTicket(),OrderOpenPrice(),MarketInfo(Symbol(),MODE_BID) - TrailingStop * pips2dbl, OrderTakeProfit(),0,Yellow);  
               }//25
             }//24
           }//23          
           if(OrderType()==OP_SELL && OrderSymbol()== Symbol() 
              && OrderMagicNumber()== MagicNumber)
              {//26
              if(OrderStopLoss() > (MarketInfo(Symbol(),MODE_ASK) + TrailingStop * pips2dbl) && OrderOpenPrice() - MarketInfo(Symbol(),MODE_ASK) >= (MinimumProfit*pips2dbl))
                 {//27
                  OrderModify(OrderTicket(),OrderOpenPrice(),MarketInfo(Symbol(),MODE_ASK) + TrailingStop * pips2dbl,OrderTakeProfit(),0,Yellow);
               }//27
              }
            }                 
            return(0);     
          }//26   
  }

 

Thanks in advance 

Luis 

 
luisneves: A error 4051 and invalid lots ...
{//25
  OrderModify(OrderTicket(), OrderOpenPrice(), 
              MarketInfo(Symbol(),MODE_BID) - TrailingStop * pips2dbl, OrderTakeProfit(),0,Yellow);  
}//25
  1. Check your return codes to find out why. What are Function return values ? How do I use them ? - MQL4 forum Your 4051 is bogus - you must check and THEN get the last error code.
  2. double StopLevel = MarketInfo(Symbol(),MODE_STOPLEVEL)*Point; // Something like 0.0030
    :                
    if(TrailingStop < StopLevel)                                  // Something like 10 < 0.0030
    
    will never happen.
  3. if(OrderStopLoss() < (MarketInfo(Symbol(),MODE_BID) - TrailingStop * pips2dbl) 
    Why use a function call instead of the simplier predefined variable? MarketInfo(Symbol(),MODE_BID) == Bid
 
luisneves:

Hi all,

 I've a workable EA with no problems in an ECN Broker, but on a STP Broker the Trailing Stop do not work. A error 4051 and invalid lots amount for order send function has been returned but can't figure out how to get from here.

following is the code for TrailingStop. Any clues here ? 

Why aren't you checking if the OrderModify() works and if it didn't then why not report the error using Alert() or Print() or Comment() ?  don't you want to know if it failed ?  and if it did fail don't you want to know why ?  and what Bid, Ask were at the time it failed ?  and what your trailing stop value was ?

 

Read this and implement it : What are Function return values ? How do I use them ?

Regarding the invalid lots figure,  does your code check for MAXLOT, MINLOT  and LOTSTEP ?    or just Max and Min ?

 

Hi RaptorUK,

Thank you for your prompt response.

You are right, you are always tell me to include the "GetLastError" routine and I have not give the deserved attention to the fact. Now The routine is included and I'm testing in Demo.

Regarding your comment about the code that I'm using is here is it ;

if(LotSize < MarketInfo(Symbol(),MODE_MINLOT))
     {//2
     LotSize = MarketInfo(Symbol(),MODE_MINLOT);
     }//2
  else if(LotSize > MarketInfo(Symbol(),MODE_MAXLOT))
     {//3
     LotSize = MarketInfo(Symbol(),MODE_MAXLOT);
     }//3       
  if(MarketInfo(Symbol(),MODE_LOTSTEP) == 0.1)
     {//4
     LotSize = NormalizeDouble(LotSize,1);
     }//4
  else LotSize = NormalizeDouble(LotSize,2);

 Do you think that is not the correct way to deal with this issue ?

Best regards

Luis 

 
luisneves:

Regarding your comment about the code that I'm using is here is it ;

Do you think that is not the correct way to deal with this issue ?


No,  that code will not work for all possible values of LOTSTEP

Use this:

double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);

LotSize = MathFloor(LotSize / lotStep) * lotStep;
 

Hi RaptorUk,

I am try to include a setting in the EA,but using several ways to get so the result is negative.

What I am looking for is to close all open positions when MaxOrders is above say, 4. In following code to close all I've try to include extra code (marked in two places) but seems that is not the right way. 

Could you clarify me where I'm rough ?

Thank you in advance

Best regards

Luis 

OTLastTick = OTCurrentTick;                      
  OTCurrentTick = OrdersTotal();                  
    if(OTCurrentTick == 0 && OTLastTick > 0)
      {
      BuyTrigger = Ask + OpenDistance * pips2dbl;
      SellTrigger = Bid - OpenDistance * pips2dbl;
      }             
    if(OTCurrentTick > 0 )Trail();                   
    if(OTLastTick >= 2                                                
      && OTCurrentTick < OTLastTick
      && OTCurrentTick > 0)
      {
      CloseAllOnSL();return;
      }      
   // if(OTCurrentTick >= MaxOrders)return//<-------------------------cancel this line                                                           
    if(OTCurrentTick > 0)OpenOppositeOrder();                        
    if(OTCurrentTick == 0)
      {
       BuyAllowed = true;
       SellAllowed = true; 

 

 

void CloseAllOnSL()
 {
   int OrdType, GLError;
   double OrderClosed;
   int orders = 4;
        
   int LastClosedTicket=GetTicketFromHistory(Symbol(),MagicNumber);  
   if(LastClosedTicket > 0 )                                          
   {//28                                                  
      Print("LastClosedTicket=",LastClosedTicket);                   
      if(OrderSelect(LastClosedTicket,SELECT_BY_TICKET))             
      {//29 
             
         if(MathAbs(OrderTakeProfit()- OrderClosePrice())>            
            MathAbs(OrderStopLoss()- OrderClosePrice() || MaxOrders >= 4))//<-------------------------------------------Include this code
                     
            {//30        
            Print("Order with ticketnr: ", LastClosedTicket,
                  " hit SL! Close all open orders");

      for(int OrderPos = OrdersTotal()-1; OrderPos >= 0; OrderPos--)       
         if(OrderSelect(OrderPos, SELECT_BY_POS, MODE_TRADES)
            && OrderMagicNumber()== MagicNumber 
            && OrderSymbol()== Symbol())                                       
            {//31
            OrdType = OrderType();
            if(OrdType == OP_BUY || OrdType==OP_SELL)
              {//32
              while(IsTradeContextBusy()) 
                    Sleep(SleepTime);  
                         RefreshRates(); 
              if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),Slippage*pips2points, Yellow))continue;                
                 else
                 GLError = GetLastError();
              }//32               
             }//31      
         }//28 
      }//29     
   }//30 
 
  if(GLError > 0) Print("Error Closing/Deleting Order, error # ", GLError, " for ticket: ", OrderTicket());           
}
 
luisneves:

Hi RaptorUk,

I am try to include a setting in the EA,but using several ways to get so the result is negative.

What I am looking for is to close all open positions when MaxOrders is above say, 4. In following code to close all I've try to include extra code (marked in two places) but seems that is not the right way. 

If you want to have a Function that will do the same thing but in response to different circumstances then the code that determines if the Function should be used must be outside of the Function,  not inside it.

//  check if last order closed was by way of SL or not
if true  CloseAllOrders();


// check how many open positions we have
if Number of open positions > 4   CloseAllOrders();





//  Function declaration
void CloseAllOrders()
   {
   .
   .
   .
   }

 

Your error handling in your CloseAllOnSL() function is still wrong . . .   if   !  OrderClose()  means if OrderClose failed . . .  you continue if it fails,  if it fails you need to immediately report the error by Print, Alert or Comment  or some other custom error reporting function,  not when the loop is closed,  what happens if you have multiple failures ? you only Print for the last.

 

Do something like this . . .

 

void CloseAllOnSL()
   {
   int OrdType, GLError;
   double OrderClosed;
   int orders = 4;
        
   int LastClosedTicket = GetTicketFromHistory(Symbol(),MagicNumber);  
   if(LastClosedTicket > 0 )                                          
      {//28                                                  
      Print("LastClosedTicket= ",LastClosedTicket);                   
      if(OrderSelect(LastClosedTicket,SELECT_BY_TICKET))             
         {//29 
             
         if(MathAbs(OrderTakeProfit()- OrderClosePrice())>            
            MathAbs(OrderStopLoss()- OrderClosePrice() || MaxOrders >= 4))//<-------------------------------------------Include this code
                     
            {//30        
            Print("Order with ticketnr: ", LastClosedTicket,
                  " hit SL! Close all open orders");

            for(int OrderPos = OrdersTotal()-1; OrderPos >= 0; OrderPos--)       
               if(OrderSelect(OrderPos, SELECT_BY_POS, MODE_TRADES)
                  && OrderMagicNumber()== MagicNumber 
                  && OrderSymbol()== Symbol())                                       
                  {//31
                  OrdType = OrderType();
                  if(OrdType == OP_BUY || OrdType==OP_SELL)
                     {//32
                     while(IsTradeContextBusy()) 
                        Sleep(SleepTime);  
                     RefreshRates();
 
                     if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),Slippage*pips2points, Yellow))               
                        {
                        GLError = GetLastError();
                        Print("Error Closing/Deleting Order, error # ", GLError, " for ticket: ", OrderTicket());           
                        }
                     }//32               
                  }//31      
            }//30 
         }//29     
      }//28 
   }
 
RaptorUK:

If you want to have a Function that will do the same thing but in response to different circumstances then the code that determines if the Function should be used must be outside of the Function,  not inside it.

 

Your error handling in your CloseAllOnSL() function is still wrong . . .   if   !  OrderClose()  means if OrderClose failed . . .  you continue if it fails,  if it fails you need to immediately report the error by Print, Alert or Comment  or some other custom error reporting function,  not when the loop is closed,  what happens if you have multiple failures ? you only Print for the last.

 

Do something like this . . .

 

 


Hi RaptorUK,

It's done. Now the EA close both ways.

best regard's

Luis 

 
luisneves:


Hi RaptorUK,

It's done. Now the EA close both ways.

best regard's

Luis 

Well done :-)
Reason: