Download MetaTrader 5

Can't get my Trailing Stop to work, need help.

To add comments, please log in or register
Johan Strandberg
104
Johan Strandberg  
Hi, 

In my EA based on MA's I want to have a trailing stop attached to any open order. 

I thought I did it right but the trailing stop moves both direction, not only following price up (or down if it's a sell position).  For instance, open price buy position 100, ts 10, price moves to 110 and my sl moves to 100, then price moves to 95 and my sl moves down to 85 when it instead should have stayed at 100 and triggered the sl.


Can anybody see what is wrong with my code? Everything works except the trailing stop which I want as a safety measure against sudden price movements.
int oSend;  //I still should the the check to see if this returns -1, see https://www.mql5.com/en/forum/139592
int oClose; //I still should the the check to see if this returns -1, see https://www.mql5.com/en/forum/139592
int xSend;
int xClose;

//Setting MagicNumer
int magic = 8;
int buyTicket;
int sellTicket;

//For SL, not needed I guess as I can use OrderStopLoss() directly in the code
//double previousSellSL;
//double previousBuySL;


int checkOrders()
{
buyTicket = 0;
sellTicket = 0;

for (int i=OrdersTotal()-1; i>=0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS) && OrderSymbol()== _Symbol && OrderMagicNumber() == magic)
         {
            if (OrderType() == OP_BUY)
               {
                   buyTicket=OrderTicket();
                   return buyTicket;
               }
            if (OrderType() == OP_SELL)
               {
                  sellTicket=OrderTicket();
                  return sellTicket;
               }
         }
        
    }
     return 0;
}

//Method for having a trailing stop for open buy order.
void trailingStopBuy()
{  
     if (OrderSelect(buyTicket, SELECT_BY_TICKET)== true)
      {
            //previousBuySL = OrderStopLoss();

            if ((Bid > (OrderOpenPrice() + 10*Point)) && (Bid-50*Point > OrderStopLoss()))
               bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), Bid-60*Point,NULL, NULL, NULL);
      }
}

//Method for having a trailing stop for open sell order.
void trailingStopSell()
{  
     if (OrderSelect(sellTicket, SELECT_BY_TICKET) == true)
      //double earlierSL = OrderStopLoss();
         {
            //previousSellSL = OrderStopLoss();
            
            if ((Ask < (OrderOpenPrice() - 10*Point)) && (Ask+50*Point < OrderStopLoss()))
              bool modiFiera = OrderModify(sellTicket, OrderOpenPrice(), Ask+60*Point,NULL, NULL, NULL);
            
         }
}

//A bunch of different params for getting iMA-value
string symbol = NULL;
int timeFrame = 0;
int period = 2;
int period2 = 5;
int maShift = 0;
int lastBarShift = 0;
double imaTest;
double imaTest2;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
void init()
  {
    Alert("Function init startade");
  }
  
  
//+------------------------------------------------------------------+
//| start function                                                   |
//+------------------------------------------------------------------+
void start()
{
//Calculating value of two different MA's
imaTest = iMA(symbol,timeFrame,period, maShift,MODE_SMA,PRICE_MEDIAN,lastBarShift);

imaTest2 = iMA(symbol,timeFrame,period2, maShift,MODE_SMA,PRICE_MEDIAN,lastBarShift);





//OPENING BUY ORDER AND CLOSING SELL ORDER
if((imaTest-imaTest2) > 0)
{
     checkOrders();
  
     if (sellTicket > 0)
      {  
          xClose = OrderClose (sellTicket, 0.01, Ask, 3);  //See input param to complete the oSend check.
          Sleep(5000);
      }
  
      checkOrders();
  
     if (buyTicket == 0)
      {
          oSend = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, Bid-60*Point, NULL,NULL, magic);  //See input param to complete the oSend check.
          Alert("Buy order opened for this particular asset");
          Sleep(5000);
      }
      
      if (buyTicket != 0)
      {
         //double previousBuySL = OrderStopLoss();
         //Alert (
      //Here I want trail the SL
         trailingStopBuy();
      }
  

}
//CLOSING ORDER
if (imaTest-imaTest2 < 0)
{    
      checkOrders();
      
      if (buyTicket > 0)
         {
            oClose = OrderClose (buyTicket, 0.01, Bid, 3);  //See input param to complete the oSend check.
            Sleep(5000);
         }
        
      checkOrders();
        
      if (sellTicket == 0)
      {
          xSend = OrderSend(Symbol(), OP_SELL, 0.01, Bid, 3, Ask+60*Point, NULL,NULL, magic);  //See input param to complete the oSend check.
          Alert("Sell order opened for this particular asset");
          Sleep(5000);
      }
      
      if (sellTicket != 0)
      {
      //Here I want trail the SL
         trailingStopSell();
      }
      
}

}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void deinit()
  {
      Alert("Function deinit startade");
  }

y code?
Marco vd Heijden
Moderator
5505
Marco vd Heijden  
if ((Bid > (OrderOpenPrice() + 10*Point)) && (Bid-50*Point > OrderStopLoss())) ‌

If both of them are true OrderModify() will be called.

‌So also to adjust your stop in the unwanted direction.

‌Either one of them should become false after the adjustment or you will see it jumping up and down like a pinball machine.

whroeder1
15913
whroeder1  
  1. if ((Bid > (OrderOpenPrice() + 10*Point)) && (Bid-50*Point > OrderStopLoss()))
       bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), Bid-60*Point,NULL, NULL, NULL);
    Overly complicated. Simplify.
    double tsl = Bid-60*Point;
    if (tsl > MathMax(OrderOpenPrice(), OrderStopLoss() )
       bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), tsl, NULL, NULL, NULL);
  2. NULL is not a valid take profit. You can only use NULL in those calls that the documentation specifically says you can, and those are mostly as a substitute for _Symbol.
  3. NULL is not a valid expiration. You can only use NULL in those calls that the documentation specifically says you can, and those are mostly as a substitute for _Symbol.
  4. NULL is not a valid color. You can only use NULL in those calls that the documentation specifically says you can, and those are mostly as a substitute for _Symbol.
  5. Check your return codes and find out why. What are Function return values ? How do I use them ? - MQL4 forum and Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
  6. You are not adjusting SL, TP, and slippage for 4/5 digit brokers and for JPY pairs.

  7. xSend = OrderSend(Symbol(), OP_SELL, 0.01, Bid, 3, Ask+60*Point, NULL,NULL, magic);  //See input param to complete the oSend check.
    Alert("Sell order opened for this particular asset");
    #2 #3 #5 #6
  8. The SL (/TP) can not be closer than MODE_STOPLEVEL Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial Is yours at least 60?
Johan Strandberg
104
Johan Strandberg  
Marco vd Heijden:
if ((Bid > (OrderOpenPrice() + 10*Point)) && (Bid-50*Point > OrderStopLoss())) ‌

If both of them are true OrderModify() will be called.

‌So also to adjust your stop in the unwanted direction.

‌Either one of them should become false after the adjustment or you will see it jumping up and down like a pinball machine.


Thanks for the help. 

if both them are true, I will modify the order setting a new StopLoss with the OrderModify() to Bid-60*Point (in a buyPosition in this example)‌

if ((Bid > (OrderOpenPrice() + 10*Point)) && (Bid-50*Point > OrderStopLoss()))
               bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), Bid-60*Point,NULL, NULL, NULL);

‌Next iteration, say that the price have in fact gone down since we re-set the SL, say from 1,2345 to 1,2344 then the part of the if-statement below should be false?

F‌irst we re-set SL at price 1,2345, SL set to 1,2339 as above code. 

T‌hen, price at 1,2344, we look at this part of the if-statment (below)

(Bid-50*Point > OrderStopLoss())

‌Bid-50*Point = 1,2344-0,0005 = 1,2339  is not > then previous SL at 1,2339 and we shouldn't enter the if-statement?

A‌LL THIS SAID, NOT SURE HOW THE LOGIC WORKS BUT I SEEM TO HAVE FIXED BY SETTING THE SAME AMOUNT OF POINTS OR AT LEAST NOT RESETTING THE SL TO MORE THAN THE IF-STATEMENT POINTS. BOTH TO 50 IN THIS CASE. I TRIED IT AND THE SL ONLY GOES ONE DIRECTION, THE DIRECTION I WANT IT TO GO. MAYBE YOU UNDERSTAND IT, I'M PERPLEXED.

if ((Bid > (OrderOpenPrice() + 10*Point)) && (Bid-50*Point > OrderStopLoss()))
               bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), Bid-50*Point,NULL, NULL, NULL);


Johan Strandberg
104
Johan Strandberg  
whroeder1:
  1. if ((Bid > (OrderOpenPrice() + 10*Point)) && (Bid-50*Point > OrderStopLoss()))
       bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), Bid-60*Point,NULL, NULL, NULL);
    Overly complicated. Simplify.
    double tsl = Bid-60*Point;
    if (tsl > MathMax(OrderOpenPrice(), OrderStopLoss() )
       bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), tsl, NULL, NULL, NULL);
  2. NULL is not a valid take profit. You can only use NULL in those calls that the documentation specifically says you can, and those are mostly as a substitute for _Symbol.
  3. NULL is not a valid expiration. You can only use NULL in those calls that the documentation specifically says you can, and those are mostly as a substitute for _Symbol.
  4. NULL is not a valid color. You can only use NULL in those calls that the documentation specifically says you can, and those are mostly as a substitute for _Symbol.
  5. Check your return codes and find out why. What are Function return values ? How do I use them ? - MQL4 forum and Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
  6. You are not adjusting SL, TP, and slippage for 4/5 digit brokers and for JPY pairs.

  7. xSend = OrderSend(Symbol(), OP_SELL, 0.01, Bid, 3, Ask+60*Point, NULL,NULL, magic);  //See input param to complete the oSend check.
    Alert("Sell order opened for this particular asset");
    #2 #3 #5 #6
  8. The SL (/TP) can not be closer than MODE_STOPLEVEL Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial Is yours at least 60?


Thanks Whroeder, good input. I have some questions about your answers maybe you can help me understand. 


1‌. Not really sure how to simplify it as I need both conditions to be true.

2‌-4 It seems to work fine using NULL-values as I don't want to set a TP, expiration or color, I've tried removing them but then I get "wrong parameters count" in my OrderModify(). Not sure how to change my SL otherwise? Am open to suggestions as I want to learn. 

5. Yes I need to do this, it's on my backlog but haven't gotten that far yet, prioritized getting the EA to work so-so first :)

6. Really good point, I didn't even think about this until now, will pause my JPY-EA's and have a look at this.

8. No min requirements for SL in contrast to price, using Darwinex at the moment. 
whroeder1
15913
whroeder1  
JoBo: 2‌-4 It seems to work fine using NULL-values as I don't want to set a TP, expiration or color, I've tried removing them but then I get "wrong parameters count" in my OrderModify(). Not sure how to change my SL otherwise? Am open to suggestions as I want to learn.
  1. How do you know they "work fine?" You aren't checking for errors?
  2. You can't remove them from the call.
  3. Use the current values of the order like you already do with OrderOpenPrice.
Johan Strandberg
104
Johan Strandberg  
whroeder1:
  1. How do you know they "work fine?" You aren't checking for errors?
  2. You can't remove them from the call.
  3. Use the current values of the order like you already do with OrderOpenPrice.


Thansk for the answers, I really appreciate the discussion as it helps me improve my mql4 skills :) 

1‌) I'm looking at the work in real time, everything seems to work fine, the TS is moving as I want it to. Maybe I'm missing something but it looks fine on my trading platform. 

2‌) This I don't really get, why can't I remove them? If I don't want a TP, color or ezpiration why should I be forced to use it, what errors might come from not using TP, expiration or color? My close criteria is definied not by TP but by either TS or a cross of the 2 MAs.

3‌) I didn't get this one, could you ellaborate? 

P‌S, I found that MT4 deals with the JPY-problem it self. If I set point it automatically knows which decimals I'm telling it to look at. As there are five decimals (or 3 in the JPY case) on my platform I set e.g. 250 point which equals 2,5 pips when it comes to forex.

Thanks again.

whroeder1
15913
whroeder1  
JoBo:


2‌) This I don't really get, why can't I remove them? If I don't want a TP, color or ezpiration why should I be forced to use it, what errors might come from not using TP, expiration or color? My close criteria is definied not by TP but by either TS or a cross of the 2 MAs.

3‌) I didn't get this one, could you ellaborate? 

‌P‌S, I found that MT4 deals with the JPY-problem it self. If I set point it automatically knows which decimals I'm telling it to look at. As there are five decimals (or 3 in the JPY case) on my platform I set e.g. 250 point which equals 2,5 pips when it comes to forex.

  1. .

  2. If you don't want to listen to the radio in your car, what do you do? Do you A) ripe it out and leave it home? Or B) turn it off? You can not remove them from the call. If you don't want one, turn it off, (TP/expir=0, color=none.)

  3. bool modiFiera = OrderModify(buyTicket, OrderOpenPrice(), tsl, NULL, NULL, NULL);
    You don't (can't) modify the open price. Don't modify the others, use the corresponding Trade Functions
  4. You are defining your SL as 250 points. That's fine until you switch to a four digit broker. Then your code breaks, stops are now ten times too big. Your slippage is define as 3 points. Same problem
To add comments, please log in or register