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?
- The open order will no longer be there
- 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; }
- The open order will no longer be there
- 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) ?
- The open order will no longer be there
- 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.
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.
// 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(); }
OrderClosePrice() == OrderTakeProfit(
- Doubles are rarely equal. Understand the links in:
The == operand. - MQL4 programming forum - SL/TP becomes stop order/limit order and are subject to slippage. They may not be equal.
// By TP means close price closer to TP than SL. bool byTP = MathAbs( OrderClosePrice() - OrderTakeProfit() ) < MathAbs( OrderClosePrice() - OrderStopLoss() );

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
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.