detection of stop loss or profit limit

To add comments, please log in or register
Pratik
55
Pratik  

All -

How do I detect when a stop loss or profit limit event has occurred?

Specifically, if I placed a BUY order and placed an OCO ---> 1. SELL_LIMIT 2. SELL_STOP how do I know if when either #1 or #2 occur?

Also, if I hit a SELL_STOP (or BUY_STOP for that matter), how can I determine the number of pips I have lost?

For example, let's say I buy at 1.4000 and place an OCO --->1. SELL_LIMIT = 1.4010 2. SELL_STOP = 1.3990.

If the price slips to 1.3989 my OCO should immediately execute and report to me that I have lost 11 pips. My question is how do I get the number 11 in MQL4?

All / any help will be much appreciated.

Ubzen
5299
Ubzen  

Event tracking... Here. Also a library in the Code-Base... Here.

William Roeder
20250
William Roeder  
mathurpratik:
How do I detect when a stop loss or profit limit event has occurred?
Specifically, if I placed a BUY order and placed an OCO ---> 1. SELL_LIMIT 2. SELL_STOP how do I know if when either #1 or #2 occur?
  1. The open order will no longer be there
  2. MT4 doesn't have OCO, The EA will have to delete the other
int start(){
    static int previousOpenCount;

    // Find my orders
    int openCount=0, ocoTicket=0, openTicket;
    for(pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
        OrderSelect(pos, SELECT_BY_POS)                 // Only my orders w/
    &&  OrderMagicNumber()  == magic.number             // my magic number
    &&  OrderSymbol()       == Symbol() ){              // and my pair.
        if (OrderType() <= OP_SELL){
            openCount++;                                // Open buy or sell
            openTicket  = OrderTicket();
        }
        else    ocoTicket=OrderTicket();                // Pending
    }
    if (openCount != 0 && ocoTicket != 0){              // Have open order
        if (!OrderDelete(ocoTicket)                     // cancel other.
            Alert("OrderDelete failed: ", GetLastError());
    }
    if (previousOpenCount > openCount){
        Print("previously opened order has closed");
    }
    previousOpenCount = openCount;
}
Pratik
55
Pratik  
WHRoeder:
  1. The open order will no longer be there
  2. MT4 doesn't have OCO, The EA will have to delete the other

Thanks WHRoeder. I will try this out.

So using the code above, for example, if I detect a SELL_STOP or a BUY_STOP, would I have to compute the loss (i.e. order_price - current_price) ?

Pratik
55
Pratik  
WHRoeder:
  1. The open order will no longer be there
  2. MT4 doesn't have OCO, The EA will have to delete the other


Hi WHRoeder -

Is this an acceptable way of determining whether I hit a stop loss?


// this function is called inside the start() in expert advisor.  This means it is called every tick. 
// returns -1 if no stop loss on latest open order
// returns 0 if stop loss on a latest BUY order
// returns 1 if stop loss on latest SELL order
// the "BUY_SL_COMMENT" is defined to be "*****[sl]" where the ***** are strings I use to ensure they are my orders

int stopLossHit(){
   if (currOrderTicket == -1){ // no open orders
      // possibility of stop loss, check further..
      
      for (int i=0; i<OrdersHistoryTotal(); i++){
         OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
         Print("Looking for stop loss order, curr order = ");
         OrderPrint();
         if (OrderOpenTime() == lastOrderTimeSent &&
             OrderMagicNumber() == MAGIC_NUMBER) {
            if (OrderComment() == BUY_SL_COMMENT && OrderType() == OP_BUY){
                Print("Stop loss encountered on previous BUY order.");
               workingStopLossTicket = OrderTicket();
               return (OP_BUY); // hit stop loss on previous BUY order
            }
            else if (OrderComment() == SELL_SL_COMMENT && OrderType() == OP_SELL){
               Print("Stop loss encountered on previous SELL order.");
               workingStopLossTicket = OrderTicket();
               return (OP_SELL); // hit stop loss on previous SELL order
            }
         }
      }
   }
   return (-1);


The "BUY_SELL_COMMENT" string ends with "[sl]" string, which is what the server appends to a previously opened order's comment. So that is the main give-away I have hit a stop loss.

the "lastOrderTimeSent" is basically a "datetime" data type I am using to keep track of the latest time an order was opened by me (i.e. Every time I do a successful OrderSend() I set lastOrderTimeSent = OrderOpenTime(); That way, I can check for it in history if it hits a stop loss.

Does any of this make sense? Or do you see a flaw?
William Roeder
20250
William Roeder  

Brokers can modify the comment, some DON'T, some append [sl], and some completely REPLACE the comment with other things.

I'd simply check the sign of close price vs open price vs order type

    static datetime lastClose;
    for(int pos=0; pos < OrdersHistoryTotal(); pos++) if (
        OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY)   // Only orders w/
    &&  OrderCloseTime()    > lastClose                 // not yet processed,
    &&  OrderMagicNumber()  == magic.number             // my magic number
    &&  OrderSymbol()       == Symbol()                 // and my pair.
    &&  OrderType()         <= OP_SELL){// Avoid cr/bal https://www.mql5.com/en/forum/126192
        lastClose    = OrderCloseTime();
        double DIR   = Direction( OrderType() ),
               delta = OrderClosePrice() - OrderOpenPrice();
        bool   HitTP = delta*DIR > 0; // HitSL = !HitTP
    }
==========
double  Direction(int op_xxx){  return( 1. - 2. * (op_xxx%2) );                }

Or you could just check if OrderProfit() > 0

I don't know if history contains the TP, SL. If it does then

bool   HitTP = MathAbs( OrderTakeProfit() - OrderClosePrice() ) < MathAbs( OrderStopLoss() - OrderClosePrice() );
works even for trailing stops.
maxwellowusu
3
maxwellowusu  
hi guys i want to add this feature to my EA. what i want it to do is to delete all pending orders when take profit is hit but i am finding it difficult please help me
           // auto closing order
           int ii = OrdersHistoryTotal()-1;
           if(OrderSelect(ii,SELECT_BY_POS)==true && OrderType()== OP_BUY && OrderClosePrice() == OrderTakeProfit()){
           Alert("the buy trade just hit take profit");
           deleteallpendingorders();
           
         }

 
William Roeder
20250
William Roeder  
maxwellowusu:
OrderClosePrice() == OrderTakeProfit(
  1. Doubles are rarely equal. Understand the links in:
              The == operand. - MQL4 programming forum

  2. SL/TP becomes stop order/limit order and are subject to slippage. They may not be equal.

  3. // By TP means close price closer to TP than SL.
    bool byTP = MathAbs( OrderClosePrice() - OrderTakeProfit() ) < MathAbs( OrderClosePrice() - OrderStopLoss() );

To add comments, please log in or register