use on EURUSD from 01.01.2025 on 10K deposit
#include <Trade/Trade.mqh> CTrade trade; datetime tr_time; bool open_pos; int OnInit() { tr_time = TimeCurrent(); open_pos=true; return(INIT_SUCCEEDED); } void OnTick() { if(open_pos &&TimeCurrent() > tr_time + 12000) { tr_time = TimeCurrent(); trade.Sell(3); uint ret_code = trade.ResultRetcode(); if(ret_code != 10009 && ret_code != 1004){ open_pos=false; } } } void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result) { //--- filter the transaction types we care about if(trans.type==TRADE_TRANSACTION_DEAL_ADD || // live Stop-Out trans.type==TRADE_TRANSACTION_DEAL_UPDATE || // partial close trans.type==TRADE_TRANSACTION_HISTORY_ADD) // tester Stop-Out { if(trans.deal==0) // ignore empty tickets occasionally sent by tester return; /* Put something in the history cache first. We don’t know the deal time yet, so use a 1-minute window around the current tester/server time. */ datetime now = TimeCurrent(); // server time in forward-test, virtual time in tester HistorySelect(now-3600, now+1); // 60-min span is enough if(!HistoryDealSelect(trans.deal)) return; // deal still not visible — exit and wait for next tick /* Only interested in closing deals */ ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(trans.deal, DEAL_ENTRY); if(entry!=DEAL_ENTRY_OUT && entry!=DEAL_ENTRY_OUT_BY) return; /* Detect Stop-Out */ ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)HistoryDealGetInteger(trans.deal, DEAL_REASON); if(reason==DEAL_REASON_SO) // margin stop-out DebugBreak(); // ← execution stops here under MetaEditor debugger } }
you can see the stop-out but in theh journal and also in history but code can not catch it.
The mq5 code file is attached.
if you are sure it is a bug, then, i recommend that you search for a thread "release XXXX" the x's being the version of your terminal.
And create a message on that thread with a reference to this thread.
if you are sure it is a bug, then, i recommend that you search for a thread "release XXXX" the x's being the version of your terminal.
And create a message on that thread with a reference to this thread.
What is your goal ? A stop-out in the Strategy Tester means an end of the backtest. There is no point trying to catch it.
I think just because you can’t define a point to catch them, it doesn’t mean there isn’t one.
I finally realized that stop-out closures are handled behind the scenes, and no existing method can catch them in the Strategy Tester. I had to use a trick in the OnDeinit method just to detect them.
Since you're a moderator, I suggest reporting this so it can be included in the documentation.
All the best

- www.mql5.com
I think just because you can’t define a point to catch them, it doesn’t mean there isn’t one.
I finally realized that stop-out closures are handled behind the scenes, and no existing method can catch them in the Strategy Tester. I had to use a trick in the OnDeinit method just to detect them.
Since you're a moderator, I suggest reporting this so it can be included in the documentation.
All the best
I am sure there are a few threads on the forum and i am sure i remember reading that in the documents of OnTradeTransaction(s), that strategy tester may not catch them. So, it is clear that they already know about it, so no one seems to care or they would have fixed it.
I've tried multiple methods to detect the stop-out event while running an Expert Advisor in the Strategy Tester, but none have worked so far. The OnTradeTransaction function doesn’t seem to catch it, even though there's an ENUM_DEAL_REASON type that should indicate a stop-out. I haven’t tested this in a live market yet, so I’m not sure whether the issue is specific to backtesting. However, I need a reliable way to detect stop-outs during backtests. Any suggestions?
In Tester, DEAL_REASON_SO often doesn't trigger. Use PositionsTotal() + equity drop to detect stop-out manually.
I am sure there are a few threads on the forum and i am sure i remember reading that in the documents of OnTradeTransaction(s), that strategy tester may not catch them. So, it is clear that they already know about it, so no one seems to care or they would have fixed it.
Could you please refer me to just one of them?
A programmer is working based on the documentation, not forum topics. I don't have to read the whole forum to understand this issue—even though no topic is shown for this issue in the search, except mine.
Even my question has been left unanswered for two days, which means the programmers don’t know about it.
Is the documentation correct? Yes, it is. The doc indicates the following situations to trigger OnTradeTransaction:
-
sending a trade request from an MQL5 program using the OrderSend()/OrderSendAsync() functions and its subsequent execution;
-
sending a trade request manually via the GUI and its subsequent execution;
-
activation of pending and stop orders on the server;
-
performing operations on the trade server side.
Yes—no transaction would occur on the server side when using the strategy tester. I can NOT say the document is not correct, but assembling all this data to understand that triggering stop-out is not handled by OnTradeTransaction in the strategy tester is an unnecessary, absurd waste of time, while the documentation could state it outright.
On the other hand, I didn’t test stop-out catching in the live market to see if OnTradeTransaction can catch it there, and if it doesn’t, it’s definitely a BUG that needs fixing.
In addition, I believe a strategy-tester platform should simulate all trading conditions of the live market—which MQL5 doesn’t do at all. There are many modifications and complexities that differ between backtesting and live-market runs.
A search of "OnTradeTransaction" brings up several forum posts and articles; all mentioning that responses "is not guaranteed". No real reason given, altho each post makes a claim of why, but each post has a different reason.

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
DEAL_REASON_SO
that should indicate a stop-out. I haven’t tested this in a live market yet, so I’m not sure whether the issue is specific to backtesting. However, I need a reliable way to detect stop-outs during backtests. Any suggestions?