Designing Prop Firm EAs: Automation for Rules, Not Just Returns
1. Introduction — The Problem
Expert Advisors are usually evaluated using familiar metrics: Net Profit, Profit Factor, Maximum Drawdown, recovery factor, win rate and expected payoff.
These metrics are useful, but they do not tell the entire story when an automated strategy is moved to a Prop Firm or Funded Account environment.
A strategy may be profitable over hundreds of trades and still violate an account rule in a single trading session.
That creates a different engineering problem.
Consider an Expert Advisor with the following characteristics:
Average risk per trade: 1%
Positive long-term expectancy
Maximum historical drawdown: 12%
Several trades may be open simultaneously
On a personal account, the trader may consider this acceptable.
Now imagine that the same EA is placed on an account configured with:
Daily Loss Limit: 5%
Maximum Loss Limit: 10%
The trading strategy itself has not changed.
The market has not changed.
But the operating environment has.
If the EA opens four positions, each risking approximately 1%, the account can already contain around 4% of potential Stop Loss exposure.
Now assume that the account is currently down 1.50% for the day.
The situation becomes:
Current Daily Loss: 1.50%
Existing Stop Loss Exposure: 4.00%
Projected Daily Exposure: 5.50%
The account has not necessarily violated the Daily Loss rule yet.
However, if all currently protected positions reach their Stop Losses, the projected loss exceeds the configured 5% boundary.
From the strategy's point of view, the trades may all be valid.
From the account's point of view, another problem exists.
This distinction is the foundation of this article.
A Prop Firm-oriented EA should not only ask:
"Is there a trading signal?"
It should also ask:
"Can the account accept this trade?"
These are two different questions.
And, in my view, they should be handled by two different parts of the system.
2. How the Problem Is Solved
2.1 Separate Market Logic from Account Permission
A traditional Expert Advisor often follows a straightforward sequence:
Market data → Signal → Position size → Order
The strategy identifies an opportunity and the EA sends the trade.
For accounts operating under strict rules, I prefer a slightly different architecture:
Market data → Trading signal → Account risk engine → Execution permission → Order
The trading strategy remains responsible for determining whether the setup is valid.
The account-risk layer determines whether that valid setup is compatible with the current condition of the account.
This distinction is important because a valid BUY or SELL signal does not automatically mean that another position should be opened.
For example:
Signal: BUY
Strategy condition: VALID
Proposed trade risk: 0.75%
Current Daily DD: 2.20%
Existing Risk to SL: 2.30%
Projected account exposure after entry: 5.25%
Configured protection threshold: 4.90%
Result:
TRADE REJECTED
Nothing is necessarily wrong with the BUY signal.
The account simply does not have enough remaining risk capacity for another position under the configured rules.
This gives us two separate validation layers:
Market Validation
and
Account Validation.
Only when both return a positive result should the EA be allowed to execute the trade.
2.2 Daily Drawdown Should Be Treated as a Dynamic Account Variable
Daily Drawdown is often displayed as a percentage on a dashboard.
For an automated system, however, it should be treated as an active variable that can influence execution.
The first requirement is a reference value.
Depending on the account structure being modeled, that reference may be based on:
Balance at Daily Reset
or
Equity at Daily Reset.
Suppose the reference is:
Daily Reference Equity: $100,000
Current Equity: $98,600
The current monetary loss is:
$100,000 - $98,600 = $1,400
Current Daily Drawdown:
$1,400 / $100,000 × 100 = 1.40%
If the Daily Loss Limit is 5%, a basic calculation suggests that the account still has:
5.00% - 1.40% = 3.60%
available.
But this number is incomplete.
It tells us the current state.
It does not tell us how much additional downside has already been committed through open positions.
That is where Risk to Stop Loss becomes useful.
2.3 Floating P/L Is Not the Same as Remaining Trade Risk
Suppose three positions are currently open.
Their combined Floating P/L is:
-$500
Looking at the account, a trader may assume that current risk is relatively small.
But imagine that the Stop Losses of those positions are still far from current prices.
Position A can lose another $500.
Position B can lose another $750.
Position C can lose another $450.
The additional downside before all three Stop Losses are reached is:
$500 + $750 + $450 = $1,700
Floating P/L tells us what has happened so far.
Risk to Stop Loss estimates how much additional protected downside remains.
These are different numbers.
And both matter.
A risk engine that only monitors current Equity can underestimate the risk already embedded in the account.
2.4 Calculating Risk to Stop Loss in MQL5
For each protected position, we can estimate the result if price moves from its current level to the Stop Loss.
In MQL5, OrderCalcProfit() is particularly useful because it performs the calculation using the actual symbol specifications rather than assuming that every instrument behaves the same way.
A simplified function could look like this:
double CalculateRiskToSL() { double total_risk = 0.0; for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket == 0 || !PositionSelectByTicket(ticket)) continue; string symbol = PositionGetString(POSITION_SYMBOL); double volume = PositionGetDouble(POSITION_VOLUME); double stop_loss = PositionGetDouble(POSITION_SL); if(stop_loss <= 0.0) continue; double current_price = PositionGetDouble(POSITION_PRICE_CURRENT); ENUM_POSITION_TYPE position_type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); ENUM_ORDER_TYPE order_type = position_type == POSITION_TYPE_BUY ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; double result = 0.0; if(OrderCalcProfit(order_type, symbol, volume, current_price, stop_loss, result)) { if(result < 0.0) total_risk += MathAbs(result); } } return total_risk; }
The production version would normally contain additional validation, but the concept is straightforward.
Each position contributes its remaining monetary downside.
Those values are then added together.
This gives us account-level Risk to SL.
2.5 Unprotected Positions Need Special Treatment
There is an important exception.
What happens when a position has no Stop Loss?
A poorly designed risk engine might treat this as:
Risk to SL = 0
That would be misleading.
The correct interpretation is closer to:
Risk to SL = UNKNOWN
Without a defined Stop Loss, there is no known endpoint from which the system can estimate maximum protected downside.
For that reason, I prefer to treat positions without SL separately.
For example:
XAUUSD BUY
Volume: 0.50
Stop Loss: NONE
Status: UNPROTECTED
Once an unprotected position is detected, the EA can decide how conservative it should be.
It might display a warning.
It might block additional entries.
It might attempt to restore the intended Stop Loss.
Or it might close the position after a defined protection period.
The specific behavior depends on the system.
But one principle should remain:
Unknown risk should not be interpreted as zero risk.
2.6 From Current Drawdown to Projected Drawdown
Once Current Daily Drawdown and Risk to Stop Loss are known, we can build a more useful account metric.
Projected Daily Drawdown.
Consider:
Daily Reference: $100,000
Current Equity: $98,600
Current Daily Loss: $1,400
Additional Risk to SL: $2,700
If all currently protected trades reach their Stop Losses:
Projected Daily Loss = $1,400 + $2,700
Projected Daily Loss = $4,100
Therefore:
Projected Daily Drawdown = 4.10%
The dashboard can now show:
Current Daily DD: 1.40%
Risk to SL: 2.70%
Projected Daily DD: 4.10% / 5.00%
This gives a very different interpretation of the account.
Looking only at current Drawdown suggested that 3.60% of daily capacity remained.
After open Stop Loss exposure is considered, the projected remaining capacity is only:
5.00% - 4.10% = 0.90%
That information can materially affect the next trading decision.
2.7 Evaluate the Next Trade Before Opening It
The next logical step is to add the proposed trade itself.
Suppose:
Current Daily DD: 1.40%
Existing Risk to SL: 2.70%
Projected Daily DD before new trade: 4.10%
The EA identifies another setup.
The new position would risk:
0.50%
New Projected Daily DD:
1.40% + 2.70% + 0.50% = 4.60%
If the protection threshold is 4.90%, the order may still be allowed.
Now consider a proposed trade with:
1.00% risk.
The result becomes:
1.40% + 2.70% + 1.00% = 5.10%
That exceeds the threshold.
The trading signal may still be valid.
But the execution should be rejected.
Conceptually:
Current Account Risk
- Existing Stop Loss Exposure
- Proposed Trade Risk
= Projected Account Exposure
This is the core idea behind a pre-trade account guard.
2.8 Building the Execution Guard
The implementation does not need to be complicated.
A simplified function could be:
bool CanOpenTrade(double current_dd, double existing_risk, double proposed_risk, double protection_threshold) { double projected_dd = current_dd + existing_risk + proposed_risk; if(projected_dd >= protection_threshold) { Print("Trade blocked. Projected DD = ", DoubleToString(projected_dd, 2), "%"); return false; } return true; }
In a real EA, the calculation would normally use monetary account values internally and convert to percentage where appropriate.
The architecture is more important than this simplified code.
Instead of:
Signal → Trade
we now have:
Signal → Risk Evaluation → Allow / Reject → Trade
This is a relatively small software change with a major impact on how the EA behaves around account constraints.
2.9 Do Not Place the Internal Protection Exactly at the Official Limit
Suppose the configured Daily Loss Limit is:
5.00%
Should the EA continue accepting risk until exactly:
5.00%?
I would generally avoid designing protection with zero margin.
Live execution contains uncertainty.
Spread can widen.
Slippage can occur.
Liquidity can deteriorate.
Markets can gap.
Commission and other costs may also influence the final account value.
A simple way to create room is an internal Safety Trigger.
Example:
Daily Loss Limit: 5.00%
Safety Trigger: 98%
Internal Protection Threshold:
5.00% × 0.98 = 4.90%
The EA now treats 4.90% as its working boundary.
This does not guarantee that the official limit can never be exceeded.
No software can guarantee exact execution under every market condition.
But it creates a practical buffer between the internal risk system and the nominal account limit.
2.10 Maximum Drawdown Requires Separate Logic
Daily Drawdown and Maximum Drawdown should not be treated as the same variable.
Daily risk normally resets.
Maximum Loss generally represents a longer-term account constraint.
The reference can also be different.
Consider a Fixed Starting Balance model.
Starting Balance:
$100,000
Maximum Loss:
10%
Minimum allowed level:
$90,000
The reference remains fixed.
Now consider a Trailing Highest Balance model.
Starting Balance:
$100,000
Highest Balance later reaches:
$106,000
If the Maximum Loss threshold trails the high-water mark by 10%, the new reference becomes:
$95,400
The same account now has a very different Maximum Loss structure.
For that reason, a generic Prop Firm-oriented EA should not assume that one hard-coded Drawdown method applies everywhere.
The risk model should be configurable.
2.11 Projected Maximum Drawdown
The same concept used for Daily Drawdown can be applied to Maximum Loss.
Suppose:
Current Maximum DD: 4.70%
Existing Risk to SL: 2.70%
Projected Maximum DD:
4.70% + 2.70% = 7.40%
Maximum Loss Limit:
10%
The dashboard can display:
Projected Max DD: 7.40% / 10.00%
This matters because a trade can fit comfortably inside the Daily Drawdown framework and still place the account too close to its overall Maximum Loss limit.
A robust pre-trade guard should therefore evaluate both.
2.12 Position Sizing Should Be Risk-Based
Another common problem appears when an EA uses fixed volume.
Consider two XAUUSD trades.
Trade A:
Stop Loss: 300 points
Trade B:
Stop Loss: 1,000 points
If both trades use exactly the same lot size, their monetary risks will be very different.
For constrained accounts, I prefer to start from risk and calculate volume from the Stop Loss.
Example:
Account Balance: $100,000
Risk Per Trade: 0.50%
Maximum intended risk:
$500
Position volume is then determined using:
Risk Amount
Stop Loss Distance
Tick Size
Tick Value
Contract Specification
Broker Minimum Volume
Broker Maximum Volume
Volume Step
This produces a more consistent account-risk profile.
There is also an important edge case.
Suppose the required risk-based lot size is:
0.006 lots
but the broker minimum is:
0.01 lots.
Automatically rounding to 0.01 increases the intended risk.
A conservative EA may choose to reject that trade rather than silently exceed the configured percentage.
That is another example of account permission overriding signal permission.
2.13 Simultaneous Exposure Matters
Risk per trade can be perfectly calculated and the account can still become overexposed.
Suppose three trades each risk 0.50%.
Individually:
Trade A: 0.50%
Trade B: 0.50%
Trade C: 0.50%
Combined:
1.50%
That may still be acceptable.
But correlation can make the real situation more complex.
For example:
EURUSD BUY
GBPUSD BUY
XAUUSD BUY
These trades may express overlapping exposure to the same underlying USD movement.
A basic account guard may not attempt to model full portfolio correlation.
Even so, simple controls such as:
Maximum Open Positions
Maximum Account Risk
Maximum Lot
Maximum Symbol Exposure
can reduce unintended concentration.
2.14 Trading Discipline Can Be Converted into Software Rules
Many trading plans contain statements like:
"I will stop after three trades."
"I will not trade after reaching my daily target."
"I will only trade during London and New York."
"I will not open positions around major news."
If the system is automated, these rules can become code.
For example:
Maximum Trades Per Day = 3
Maximum Open Positions = 2
Maximum Lot = 1.00
Daily Profit Lock = 2%
Trading Window = 08:00–16:00
Friday Cutoff = 15:00
This has a major advantage.
The trader no longer relies exclusively on discipline in the moment.
The system enforces the predefined framework.
A useful principle here is:
The strongest trading rule is often the one the software does not allow you to break.
2.15 News and Execution Conditions
A backtest generally cannot represent every detail of live execution perfectly.
Around important economic events, conditions can change quickly.
Spread can expand.
Slippage can increase.
Liquidity can decrease.
Price movement can accelerate.
For an account with strict loss limits, those effects matter.
MetaTrader 5 provides an integrated Economic Calendar that can be used as part of an execution filter.
An EA can define:
High Impact events only
or
Medium + High Impact events.
It can then restrict new orders:
60 minutes before the event
and
30 minutes after the event.
This does not improve the prediction of market direction.
It controls when the strategy is permitted to expose the account.
The same logic applies to spread.
If the strategy normally trades with a spread of 20 points and current spread reaches 80 points, the EA can reject the order.
Execution quality is part of risk.
2.16 Trading Sessions Matter Too
Many strategies behave differently depending on the trading session.
A breakout model designed around London liquidity should not necessarily operate during every hour of the day.
The EA can therefore define:
Start Hour
Start Minute
End Hour
End Minute
using broker-server time.
This also makes testing more consistent.
The strategy is evaluated inside the market conditions for which it was designed instead of simply trading whenever a signal happens to appear.
2.17 Overtrading Is Not Only a Manual-Trader Problem
Automated systems can overtrade.
An EA does not become tired or emotional, but it can repeatedly trigger during poor market conditions.
Imagine a reversal strategy that generates six entries during a highly directional session.
The code may be working exactly as designed.
The account can still suffer from excessive trade frequency.
Useful controls include:
Maximum Trades Per Day
Maximum Consecutive Losses
Minimum Time Between Trades
Maximum Open Positions
Daily Loss Lock
Daily Profit Lock
These parameters are not necessarily part of the market edge itself.
They are part of operational risk control.
2.18 Account-Wide Protection vs EA-Specific Protection
Another important design question appears when more than one strategy operates on the same account.
Suppose:
EA A has Magic Number 1001.
EA B has Magic Number 2001.
There is also one manually opened trade.
Which positions should the Daily Drawdown engine consider?
For an account-level rule, the logical answer is usually:
All of them.
Breakeven management can remain Magic Number specific.
Trailing Stop can remain strategy specific.
Take Profit logic can remain strategy specific.
But the account's Daily Loss does not care which EA created the loss.
A separate EA, a manual trade or another symbol can still move the entire account toward its loss threshold.
This means Prop Firm architecture often needs two scopes:
Strategy-level management
and
Account-level protection.
They should not be confused.
2.19 Testing Prop Firm EAs Requires Different Metrics
This is where the Strategy Tester becomes particularly interesting.
Traditional optimization often focuses on maximizing:
Net Profit
Profit Factor
Expected Payoff
Recovery Factor
and minimizing:
Maximum Drawdown.
For a Prop Firm system, I would add more questions.
What was the worst intraday loss?
What was the highest simultaneous Risk to SL?
How many positions were open at the same time?
What was the worst consecutive-loss sequence?
How often did the EA approach the Daily Loss boundary?
How often did the account-risk guard reject otherwise valid signals?
Did performance depend on one unusually profitable period?
How sensitive was the system to increased spread?
Suppose we compare two configurations.
Configuration A:
Higher Net Profit
Higher Daily Exposure
More simultaneous positions
Larger worst-day loss
Configuration B:
Slightly lower Net Profit
Lower projected exposure
Lower worst-day loss
Fewer periods near the account boundary
The highest-return configuration is not automatically the most suitable configuration for a rule-constrained account.
This is why optimization objectives should reflect the environment in which the EA will actually operate.
2.20 A Practical Rule-Aware Architecture
A complete architecture might look like this:
MARKET DATA | v TRADING STRATEGY | |-- Trend |-- Momentum |-- Breakout |-- Reversal | v VALID SIGNAL? | v ACCOUNT RISK ENGINE | |-- Daily Drawdown |-- Maximum Drawdown |-- Existing Risk to SL |-- Proposed Trade Risk |-- Open Positions | v EXECUTION GUARD | |-- Spread |-- Trading Hours |-- News |-- Max Trades |-- Max Lot | v ALLOW / REJECT | v ORDER EXECUTION | v TRADE MANAGEMENT | |-- Stop Loss |-- Take Profit |-- Breakeven |-- Trailing
This architecture keeps responsibilities separated.
The signal engine does not need to understand every account rule.
The account-risk engine does not need to know why the strategy wants to BUY.
The execution guard does not need to predict the market.
Each component solves a specific problem.
That makes the EA easier to maintain, test and extend.
3. Conclusion — What the Reader Gets
Designing an Expert Advisor for a Prop Firm or Funded Account requires a slightly different mindset.
Profitability still matters.
A strategy still needs a real edge.
Entry logic still matters.
Execution still matters.
But strict account limits introduce an additional layer.
The EA needs to understand the state of the account.
A trade can be individually valid and still be inappropriate when combined with existing exposure.
A profitable system can still produce an unacceptable daily loss.
A correct lot size can still contribute to excessive simultaneous risk.
A valid signal can still arrive during an unsuitable spread, session or news window.
That is why I prefer to separate two questions:
Is this a valid trade?
and
Can this account take this trade?
For rule-constrained automated trading, both answers should be YES before an order is sent.
The framework developed in this article can be summarized as:
Current Account Risk
- Existing Stop Loss Exposure
- Proposed Trade Risk
= Projected Account Exposure
Around that calculation, additional controls can be added for:
Daily Drawdown
Maximum Drawdown
Position sizing
Trading frequency
Open positions
Spread
Trading sessions
Economic news
and account-level protection.
The purpose is not to eliminate risk.
That is impossible.
The purpose is to make the risk architecture part of the Expert Advisor from the beginning instead of adding protection only after the trading strategy has already been built.
At Goldexa, this rule-aware approach is also part of the development philosophy behind projects such as Prop Strike, where trading logic and account-level protection are treated as components of the same automated system.
The objective is not simply to automate more trades.
It is to build automation that understands when it should trade — and when it should stay out.
For Prop Firm automation, returns matter. But rules determine whether the system gets to keep trading.


