Is There Way to Know That SL Was Hit?

 
Is there any way to know that SL was hit? I can use OnTrade(), but I won't be able to know the reason why the order closed or am I missing something?
 
enivid:
Is there any way to know that SL was hit? I can use OnTrade(), but I won't be able to know the reason why the order closed or am I missing something?

 

You're right - there doesn't seem to be an order reason code.  You'd probably be able to infer it from the fact that you got an OnTrade event when your EA didn't send an order, but the code would be a little complex.

Paul 

 
phampton:

 

You're right - there doesn't seem to be an order reason code.  You'd probably be able to infer it from the fact that you got an OnTrade event when your EA didn't send an order, but the code would be a little complex.

Paul 

Yeah, but how do I differentiate between SL and TP hit then?
 

Try this for Market Stops. May not always be the exact Market Stop, but should be very close.

if(PositionsTotal() > 0)
   {
      if(PositionSelect(_Symbol))
         {
            if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
               {
                  if(SymbolInfoDouble(Symbol(), SYMBOL_BID) >= PositionGetDouble(POSITION_TP) )
                     {
                        Print("Buy Position Closed at TP ",DoubleToString(PositionGetDouble(POSITION_TP),_Digits)); 
                     }
               else
                  if(SymbolInfoDouble(Symbol(), SYMBOL_BID) <= PositionGetDouble(POSITION_SL) )
                     {
                        Print("Buy Position Closed at SL ",DoubleToString(PositionGetDouble(POSITION_SL),_Digits)); 
                     }
               }
               
            if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
               {
                  if(SymbolInfoDouble(Symbol(), SYMBOL_ASK) <= PositionGetDouble(POSITION_TP) )
                     {
                        Print("Sell Position Closed at TP ",DoubleToString(PositionGetDouble(POSITION_TP),_Digits)); 
                     }
               else
                  if(SymbolInfoDouble(Symbol(), SYMBOL_ASK) >= PositionGetDouble(POSITION_SL) )
                     {
                        Print("Sell Position Closed at SL ",DoubleToString(PositionGetDouble(POSITION_SL),_Digits)); 
                     }
               }
         }
   }




 

Wait, but

PositionsTotal()

will return 0 if it's already closed, won't it?


 
Currently I've got off by setting an internal flag when the position is taken (it saves direction, SL and TP) then I check in OnTick() if the current price is above/below SL/TP for Short/Long and there is no position open, then SL/TP has been hit. Don't know if it will be effective during the volatile markets. I am lucky my EA opens and closes always only 1 position of the same size.
 
enivid:

Wait, but

will return 0 if it's already closed, won't it?


While PositionsTotal() > 0, assigned TP and SL to  double variables. Then values will be available when PositionsTotal() == 0. You could also use HistorySelect() feature to find last order TP and SL.

double BuyTP, SellTP, BuySL, SellSL;
uint total=0;
ulong ticket;
   
HistorySelect(0,TimeCurrent());
total=HistoryOrdersTotal(); // This number is last order filed.
if(PositionsTotal() > 0) ticket=total; 
else ticket=total-1; // Skip last order when PositionsTotal()=0
   
for(uint i=0;i<ticket;i++)
 {
   if( HistoryOrderGetString(i,ORDER_SYMBOL)==_Symbol )
     {
       if(HistoryOrderGetInteger(i,ORDER_TYPE)==ORDER_TYPE_BUY)
         { 
           BuyTP=HistoryOrderGetDouble(i,ORDER_TP);
           BuySL=HistoryOrderGetDouble(i,ORDER_SL);
         }
                     
       if(HistoryOrderGetInteger(ticket,ORDER_TYPE)==ORDER_TYPE_SELL)
         {
           SellTP=HistoryOrderGetDouble(i,ORDER_TP);
           SellSL=HistoryOrderGetDouble(i,ORDER_SL);
         }
     }
 }




Reason: