Trouble modifying SL to follow Trailing Stop

 

Hello Community,

Consider the following function: 

 bool trailStop(double trailingSta, double trailingSto) { 
         double tSL;
          RefreshRates();
         for(int i = OrdersTotal()-1; i >= 0; i--) {
            if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
               continue;
               }
           if(OrderType() == OP_BUY) {
              if(Ask > NormalizeDouble(OrderOpenPrice() + trailingSta * Point,Digits) && OrderStopLoss() < NormalizeDouble(Bid -(trailingSto + trailingStep)* Point,Digits)){ // trailingStep is an external variable
                 tSL = Bid - trailingSto * Point;
                 if(tSL > MathMax(OrderOpenPrice(),OrderStopLoss())){
                   if(!OrderModify(OrderTicket(),OrderOpenPrice(),tSL, OrderTakeProfit(),0)){
                     Print("OrderModify error " , GetLastError());
                }
                  return true;
               }         
             }
          }
          
         if(OrderType() == OP_SELL) {
               if(Bid < NormalizeDouble(OrderOpenPrice() - trailingSta * Point,Digits) && OrderStopLoss() > NormalizeDouble(Ask + (trailingSto + trailingStep) * Point,Digits)){
                  tSL = Ask + trailingSto * Point;
                if(tSL < MathMax(OrderOpenPrice(),OrderStopLoss())){
                  if(!OrderModify(OrderTicket(),OrderOpenPrice(),tSL, OrderTakeProfit(),0)){
                     Print("OrderModify error " , GetLastError());
               }
              return true;
             }
          }
                     
       }
     }
     
      return false;          
  } 

This function just goes through my open orders, and starts modifying their stop losses with a trailing stop if a certain price is reached, up or down. 

What I need is that once a trailing stop for any order is activated, ALL SUBSEQUENT orders in the same market direction must open with the same stop loss. 

I tried modifying my OrderSend() function as follows : 

if(OrderSelect(ticket1,SELECT_BY_TICKET) || nbOrders == 0){
    if(OrderType() == 0 || nbOrders == 0) {     
     if(curAsk >= curOpen + entryValue* Point){  
         if(entryCounter <= nbOperations && counter == 0) {  //To limit the number of orders per bar. nbOperations is an external integer.
            if(!trailStop(trailingStart,trailingStop))     
               ticket1 = OrderSend(Symbol(),OP_BUY,firstLot,curAsk,oSlippage,curLow,doubleBuyTP);
            if(trailStop(trailingStart,trailingStop))
               ticket1 = OrderSend(Symbol(),OP_BUY,firstLot,curAsk,oSlippage,Bid -(trailingStop * Point),doubleBuyTP);
             if(OrderSelect(ticket1,SELECT_BY_TICKET)){
                 initAsk = OrderOpenPrice();
                 counter = 1;
                 entryCounter ++;
                }
             }
         } 
      } 
    }  

( The Green lines are the ones I added to this code to make it work as I want. Same thing is done for the SELL orders.) However, this did not work. Once trailing stop is being initiated, subsequent orders continue to have the original stop loss value ( current low for BUY orders, current High for SELL orders). What am I missing? Any insight on this is greatly appreciated.

Thanks in advance,

Best Regards.

 
Lord Odin: What am I missing?
         for(int i = OrdersTotal()-1; i >= 0; i--) {
            if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
  1. Using OrdersTotal (or OrdersHistoryTotal) directly and/or no Magic number filtering on your OrderSelect loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

  2. if(OrderSelect(ticket1,SELECT_BY_TICKET) || nbOrders == 0){
    EAs must be coded to recover. If the power fails, OS crashes, terminal or chart is accidentally closed, on the next tick, any static/global ticket variables will have been lost. You will have an open order but don't know it, so the EA will never try to close it, trail SL, etc. How are you going to recover? Use a OrderSelect loop to recover, or persistent storage (GV+flush or files) of ticket numbers required.

  3. Lord Odin: What I need is that once a trailing stop for any order is activated, ALL SUBSEQUENT orders in the same market direction must open with the same stop loss. 
    Remember the TSL in your trail function and use it in the send function.

  4. Your trail function only works with one order.
 
William Roeder:
  1. Using OrdersTotal (or OrdersHistoryTotal) directly and/or no Magic number filtering on your OrderSelect loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

  2. EAs must be coded to recover. If the power fails, OS crashes, terminal or chart is accidentally closed, on the next tick, any static/global ticket variables will have been lost. You will have an open order but don't know it, so the EA will never try to close it, trail SL, etc. How are you going to recover? Use a OrderSelect loop to recover, or persistent storage (GV+flush or files) of ticket numbers required.

  3. Remember the TSL in your trail function and use it in the send function.

  4. Your trail function only works with one order.

Thank you for the fast reply mate.
 1) Got it. This code is taken from an EA designed only for backtests on historical data. Of course, making it live would require adding some more fault-proof stuff like the magic number you mentioned. Your link is a good read on that matter, thanks.

2) Noted. Thanks.

3) Isn't that what I did? I mean in my send function, the stop loss value should become ( Bid - (trailingStop * Point) ), which is equal to the TSL.

4) Sorry, this I didn't quite follow. Isn't it looping on all open orders and modifying the stop losses?

Thanks in advance for your help.

Best Regards.

 

Greetings again,

If anyone can give some thoughts on this matter, it would be greatly appreciated.

I have modified a few things regarding the above functions, they are now as follows:

   void trailStop(double trailingSta, double trailingSto) { 
         double tSL;
          RefreshRates();
         for(int i = OrdersTotal()-1; i >= 0; i--) {
            if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
               continue;
               }
            if(OrderMagicNumber() != magicNumber || OrderSymbol() != Symbol())
               continue;
                  
       
           if(OrderType() == OP_BUY) {
              if(Ask > NormalizeDouble(OrderOpenPrice() + trailingSta * Point,Digits) && OrderStopLoss() < NormalizeDouble(Bid -(trailingSto + trailingStep)* Point,Digits)){
                 tSL = Bid - trailingSto * Point;
                 trailingBuyPrice = tSL; 
                 if(tSL > MathMax(OrderOpenPrice(),OrderStopLoss())){
                   if(!OrderModify(OrderTicket(),OrderOpenPrice(),tSL, OrderTakeProfit(),0)){
                     Print("OrderModify error " , GetLastError());
                }     
                  trailOn = 1; // To mark that the function has been activated
                  return;
               }         
             }
          }
          
         if(OrderType() == OP_SELL) {
               if(Bid < NormalizeDouble(OrderOpenPrice() - trailingSta * Point,Digits) && OrderStopLoss() > NormalizeDouble(Ask + (trailingSto + trailingStep) * Point,Digits)){
                  tSL = Ask + trailingSto * Point;
                  trailingSellPrice = tSL;
                if(tSL < MathMax(OrderOpenPrice(),OrderStopLoss())){
                  if(!OrderModify(OrderTicket(),OrderOpenPrice(),tSL, OrderTakeProfit(),0)){
                     Print("OrderModify error " , GetLastError());
               }
              trailOn = 1;
              return;
             }
          }               
       }
    }          
  }   
if(OrderSelect(OrdersTotal()-1,SELECT_BY_POS,MODE_TRADES) || nbOrders == 0){ //If there is an order in the pool, or this is first entry
   if((OrderMagicNumber() == magicNumber && OrderSymbol() == Symbol()) || nbOrders == 0){
    if(OrderType() == 0 || nbOrders == 0 ) {     
     if((curAsk >= curOpen + entryValue* Point) && (curAsk <= curOpen + (entryValue + 50) *Point) && entryCounter <= nbOperations && counter == 0){  
           if(trailOn == 0) // If trail function did not activate, then put the SL at current Low.
               ticket1 = OrderSend(Symbol(),OP_BUY,firstLot,curAsk,oSlippage,curLow,doubleBuyTP,NULL,magicNumber);
           if(trailOn == 1) // If trail function was activated, I need the stop loss to be the saved static value from the function.
               ticket1 = OrderSend(Symbol(),OP_BUY,firstLot,curAsk,oSlippage,trailingBuyPrice,doubleBuyTP,NULL,magicNumber);  
             if(OrderSelect(ticket1,SELECT_BY_TICKET)){
                 initAsk = OrderOpenPrice();
                 counter = 1;
                 entryCounter ++;
                }
             }
         } 
      } 
}
   if(nbOrders == 0){
         trailOn = 0;
         trailingBuyPrice = 0;
         trailingSellPrice = 0;
        }

The "return" in the function works well because the function is being called on every tick. However, this is not working as desired; some orders are following the trail, and at some point, orders just STOP having ANY stop loss. (Order being sent WITHOUT STOP LOSS AT ALL).

Is there a way to notify subsequent orders that the function is activated and that stop loss values should be now set to the trailing one, other than the use of a static variable?

I am missing something obvious... Kindly help me figure this out.

Best Regards.

 

Lord Odin:

3) Isn't that what I did? I mean in my send function, the stop loss value should become ( Bid - (trailingStop * Point) ), which is equal to the TSL.

4) Sorry, this I didn't quite follow. Isn't it looping on all open orders and modifying the stop losses?

  1.    void trailStop(double trailingSta, double trailingSto) { 
             double tSL;
    The moment you return from the function, your tSL has been lost. I said "Remember the TSL from your trail function and use it in the send function." How can use the lost value in the other send function?

  2. Lord Odin: ALL SUBSEQUENT orders in the same market direction must open with the same stop loss. 
    You compute the SL relative to that order's open price. You are not using "the same stop loss."

  3.          for(int i = OrdersTotal()-1; i >= 0; i--) {
                if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
    
    Using OrdersTotal (or OrdersHistoryTotal) directly and/or no Magic number filtering on your OrderSelect loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

 
William Roeder:
  1. The moment you return from the function, your tSL has been lost. I said "Remember the TSL from your trail function and use it in the send function." How can use the lost value in the other send function?

  2. You compute the SL relative to that order's open price. You are not using "the same stop loss."

  3. Using OrdersTotal (or OrdersHistoryTotal) directly and/or no Magic number filtering on your OrderSelect loop means your code is incompatible with every EA (including itself on other charts and manual trading.)
              Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 programming forum
              MagicNumber: "Magic" Identifier of the Order - MQL4 Articles

Thanks again for your time. 

1. Sorry I forgot to point out that inside the function, I have used the variable trailingBuyPrice, which is a static variable in which I am saving the tSL value in. Therefore, I don't care about the tSL variable losing its value on each return.

2. Indeed, computing a relative SL is a better approach.

3. I have worked by your advice and added a magic number filter as it shows in my second piece of the function. Thanks.

Your answers have given me insight on where to focus. Cheers.


Best Regards.