Counting stops in an MT5 EA with OnTradeTransaction: DEAL_REASON_SL is not always a loss
Posted: Sat Oct 24, 2026 7:55 pm
Counting stops in an MT5 EA with OnTradeTransaction: DEAL_REASON_SL is not always a loss
A common request is an EA that pauses after three stop-outs in a row. OnTradeTransaction is the place to detect them, because it fires for each deal as it happens, including closes made by the server when a stop or target triggers.
The skeleton:
void OnTradeTransaction(const MqlTradeTransaction &t, const MqlTradeRequest &r, const MqlTradeResult &res)
{
if(t.type != TRADE_TRANSACTION_DEAL_ADD) return;
if(!HistoryDealSelect(t.deal)) return;
if(HistoryDealGetInteger(t.deal, DEAL_ENTRY) != DEAL_ENTRY_OUT) return;
if(HistoryDealGetInteger(t.deal, DEAL_MAGIC) != MyMagic) return;
double net = HistoryDealGetDouble(t.deal, DEAL_PROFIT) + HistoryDealGetDouble(t.deal, DEAL_COMMISSION) + HistoryDealGetDouble(t.deal, DEAL_SWAP);
if(net < 0) lossStreak++; else lossStreak = 0;
}
I count the sign of the net result and not DEAL_REASON_SL, because the reason only says what closed the deal. A trailing stop that has moved to +12 pips and then gets hit still has the reason DEAL_REASON_SL, and it is a winner. Counting those as stops would put you in a pause after three winning trails. Check the reason when you want to know how trades end, and the net amount when you want to know whether they lost.
A common request is an EA that pauses after three stop-outs in a row. OnTradeTransaction is the place to detect them, because it fires for each deal as it happens, including closes made by the server when a stop or target triggers.
The skeleton:
void OnTradeTransaction(const MqlTradeTransaction &t, const MqlTradeRequest &r, const MqlTradeResult &res)
{
if(t.type != TRADE_TRANSACTION_DEAL_ADD) return;
if(!HistoryDealSelect(t.deal)) return;
if(HistoryDealGetInteger(t.deal, DEAL_ENTRY) != DEAL_ENTRY_OUT) return;
if(HistoryDealGetInteger(t.deal, DEAL_MAGIC) != MyMagic) return;
double net = HistoryDealGetDouble(t.deal, DEAL_PROFIT) + HistoryDealGetDouble(t.deal, DEAL_COMMISSION) + HistoryDealGetDouble(t.deal, DEAL_SWAP);
if(net < 0) lossStreak++; else lossStreak = 0;
}
I count the sign of the net result and not DEAL_REASON_SL, because the reason only says what closed the deal. A trailing stop that has moved to +12 pips and then gets hit still has the reason DEAL_REASON_SL, and it is a winner. Counting those as stops would put you in a pause after three winning trails. Check the reason when you want to know how trades end, and the net amount when you want to know whether they lost.