How to run an Expert Advisor on a prop firm account without breaking the daily loss rule
Most Expert Advisors I see on funded accounts are reasonable strategies that have no idea a rule exists. The EA sizes its trade, the account drifts down, and the breach happens while nobody watches. Below is the setup I ended up with after running my own EAs on a funded account, written as steps you can rebuild yourself. The code is one compiling sketch split into pieces, a starting point for your own utility.
| Task | Keep an expert advisor on a funded account inside the daily loss rule, including floating loss, restarts and trades opened after the limit. |
| Time | About an hour to build the utility from the sketches below, plus a rehearsal on a demo account. |
| Works on | MetaTrader 5, any broker, any EA; one utility per account. |
Step 1: Write down which number your firm actually measures
Almost every firm measures equity including floating profit and loss, not closed balance. That one fact decides everything else, because an open position sitting 400 in the red has already used 400 of today's allowance while your balance still looks untouched. FTMO measures the daily loss against the balance at the reset time and counts floating P/L against that number. The5ers, FundingPips, Alpha Capital and Goat Funded anchor on the higher of balance or equity at their reset. Storing MathMax(balance, equity) at the reset is the conservative choice for all of them.
Step 2: Find your firm's reset clock, not your broker's midnight
Of the firms I checked in September 2026, FTMO resets at 00:00 Central European time, Goat Funded at 5 PM New York, Maven at 00:00 UTC, and FundedNext, The5ers, FundingPips and Alpha Capital at 00:00 on their own platform server. If your EA runs on the firm's own MT5 account, server midnight is exact and needs no offset. If you run somewhere else, a hardcoded GMT offset is wrong for two weeks every spring and autumn, because the EU switches on the last Sunday of March and October while the US switches on the second Sunday of March and the first Sunday of November. Derive the reset from those dates. Central European version below; the US rule is the same loop with other bounds.
datetime EuSwitchUtc(const int year,const int month) { MqlDateTime t = {}; t.year = year; t.mon = month; t.hour = 1; // 01:00 UTC for(int day=31; day>=25; day--) // March and October have 31 days { t.day = day; datetime candidate = StructToTime(t); MqlDateTime c; TimeToStruct(candidate,c); if(c.day_of_week==0) return candidate; } return 0; } int EuOffsetHours(const datetime utcNow) { MqlDateTime n; TimeToStruct(utcNow,n); bool summer = (utcNow >= EuSwitchUtc(n.year,3) && utcNow < EuSwitchUtc(n.year,10)); return summer ? 2 : 1; // CEST or CET } datetime LastResetUtc(const datetime utcNow) { long offset = (long)EuOffsetHours(utcNow)*3600; long local = (long)utcNow + offset; return (datetime)(local - (local % 86400) - offset); }
Step 3: Put the limit check in one account level utility, not inside every EA
The firm measures the account, so the thing watching the limit has to measure the account. Per EA budgets look tidy on paper and come apart the first time two EAs lose in the same hour. I run one utility on one chart per account. It reads equity on every tick and on a one second timer, because a tick only check goes quiet on a slow chart at the wrong moment. The trading EAs ask that utility for a risk multiplier before they size. DayStartAnchor is in step 5, LockDay and IsDayLocked in step 6.
input double InpDailyPct = 4.5; // armed below the firm's 5 percent void CheckDailyLimit() { datetime reset = LastResetUtc(TimeGMT()); double anchor = DayStartAnchor(reset); double limit = anchor * InpDailyPct / 100.0; double used = anchor - AccountInfoDouble(ACCOUNT_EQUITY); if(used >= limit && !IsDayLocked()) LockDay(); } int OnInit() { EventSetTimer(1); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { EventKillTimer(); } void OnTick() { CheckDailyLimit(); } void OnTimer() { CheckDailyLimit(); // ticks stop, the clock does not }
Step 4: Arm below the published limit
Detection is tick based, so the close executes past the level you configured. On a demo test with a fixed limit of 250 my close fired at a loss of 267.19. The journal line, with the account tag stripped:
DAILY LIMIT BREACHED: loss 267.19 EUR >= limit 250.00 EUR. Closing all positions.
I arm 0.5 percentage points below the daily limit and 1 point below the max drawdown, so a firm rule of 5% and 10% becomes 4.5% and 9%.
Step 5: Persist the state so a reboot does not reset your protection
Most guards count from the moment you attached them, so a VPS reboot at 11:00 hands you a fresh day with a fresh allowance. Write the day start anchor, the used percentage and the lock flag into terminal global variables with the account login in the name (https://www.mql5.com/en/docs/globals). They are stored on disk, they survive a terminal restart, and they are removed automatically after four weeks without access. One trap: GlobalVariableTime() returns the last access, and your own check accesses the variable every tick, so keep the reset stamp in a second variable.
string GvName(const string key) { return StringFormat("DLG_%I64d_%s",AccountInfoInteger(ACCOUNT_LOGIN),key); } double DayStartAnchor(const datetime lastReset) { string gvValue = GvName("anchor"); string gvStamp = GvName("anchor_time"); // GlobalVariableTime() is the time of the last ACCESS, not of the last // write, so the reset stamp is kept in a second variable. if(GlobalVariableCheck(gvValue) && GlobalVariableCheck(gvStamp) && (datetime)GlobalVariableGet(gvStamp) >= lastReset) return GlobalVariableGet(gvValue); double anchor = MathMax(AccountInfoDouble(ACCOUNT_BALANCE), AccountInfoDouble(ACCOUNT_EQUITY)); GlobalVariableSet(gvValue,anchor); GlobalVariableSet(gvStamp,(double)lastReset); GlobalVariablesFlush(); return anchor; }
Step 6: Lock the day, and deal with whatever opens during the lock
Closing everything is only half of it. A Market product cannot switch AutoTrading off without a DLL, so any EA still attached keeps firing signals into your locked day. My utility subscribes to trade transactions and closes anything that appears during the lock within milliseconds, measured at 148 ms for three positions on a demo account. That costs one spread per attempt, a price I will pay over a breach. The tidier route is to detach the EAs yourself as soon as you see the lock.
#include <Trade\Trade.mqh> CTrade trade; bool IsDayLocked() { string gv = GvName("locked"); return (GlobalVariableCheck(gv) && GlobalVariableGet(gv) > 0.0); } void LockDay() { GlobalVariableSet(GvName("locked"),1.0); GlobalVariablesFlush(); for(int i=PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if(ticket>0) trade.PositionClose(ticket); } Print("DAILY LIMIT BREACHED. All positions closed, day locked."); } void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result) { if(!IsDayLocked()) return; if(trans.type != TRADE_TRANSACTION_DEAL_ADD) return; if(trans.position>0 && PositionSelectByTicket(trans.position)) trade.PositionClose(trans.position); }
Step 7: Rehearse a losing day before you have one
Open a demo account on the same server, set the daily limit to something tiny, and trade into it by hand. You want to see the warning, the close all, the lock, a blocked trade and the reset in your journal while nothing is at stake. I later packaged my own guard as a Market utility, but the seven steps above are the substance.
Limits
The max drawdown rule is a separate measurement and needs separate code: static from the initial balance at most firms, trailing at some, trailing on end of day values at others. Consistency scores, news windows, minimum trading days and strike systems are rules you keep yourself, because no terminal side tool can see them. And none of this helps a strategy with negative expectancy. A guard turns a rule breach into a bad day, it does not turn a losing system into a winning one. The firm rules above were collected on 3 September 2026 and firms revise them, so verify yours before you configure anything.
Built as a ready utility: PropGuardian setup guide (presets for nine firms, the reset clock, what a breach looks like).
More guides: my blog · Tools for prop firm accounts: all my products
Firm rules as collected in September 2026; check your firm's current rules. This is not investment advice.


