Pipsgrowth EX18003 TrendFollow
MT5 Expert Advisor (Open Source) · XAUUSD · M5, H1
Pipsgrowth.com EX18003 CustomMetric_XAUUSD_5M — EMA crossover trend-following EA, full 12-layer stack.
Overview
Pipsgrowth EX18003 TrendFollow is a closed-bar trend follower for MetaTrader 5 whose centre of gravity is not the signal itself but the eight-state regime classifier that sits in front of it. The trade idea is the simplest possible: an EMA(10) crossing an EMA(50) on a closed bar, and the EA will only act on that one shape. Everything else in the 1,000-line source is about deciding whether the cross is real, whether the cross is worth trading, and how to take the money off the table once it is in. There are no martingale legs, no grid layers, no recovery sequences — entries are one position at a time, and a position is closed by one of five distinct exit paths. That is the whole design.
The decision pipeline in OnTick() is strictly ordered. The very first thing the EA does on a new bar is call ClassifyRegime(), which reads ADX(14) and Bollinger Band width off a 100-bar history and labels the market into one of seven states: REGIME_CHOPPY when ADX is below 18, REGIME_BREAKOUT when Bollinger width is at or above the 80th percentile, REGIME_COMPRESS when width is at or below the 20th percentile, REGIME_STRONG when ADX is at or above 25, REGIME_WEAK when ADX is at or above 14 but below 25, REGIME_RANGE otherwise, and a final REGIME_EXPAND override that fires when both the ATR and BB-width percentiles are above 70 with ADX at or above 20. The label gets cached into a global so the rest of the bar can read it. The signal itself — SignalDirection() reading two closed bars of the fast and slow EMAs and returning +1/-1/0 — runs only after the regime pass.
Before any signal is even looked at, the EA walks NoTradeBlock(). This is a single function but it is a long one: it returns true (and the bar is skipped) on any of ten guards. The capital floor is enforced first: if g_effectiveCap has dropped below InpCapitalCapFloor (50 USD by default), no new entries. Then the spread guard: if the symbol spread is more than MAX_SPREAD_MULT (3.0) times the rolling 50-tick average, the bar is skipped. Then the session window: SESSION_START_H=7 to SESSION_END_H=20 in server hour. Then the weekend-proximity block: Friday after 22:00, or any time on Saturday or Sunday. Then the daily loss limit: realised PnL for the EA's own magic on this symbol, recomputed from the deal history, cannot be worse than -3% of effective capital. Then the weekly loss limit: same logic, -6% of effective capital, week starting Monday at 00:00 server. Then the cooldown flag, the max-concurrent check, the data-quality check on bid/ask, and the broker-trade-disabled check. Any one of those returns true and the rest of the bar is dead.
If the regime is labelled and the no-trade gates are all clear, the signal can finally run. SignalDirection() reads the two most recent closed bars of the fast and slow EMAs and checks for a strict crossover — the fast must be at or below the slow on bar 2 and strictly above on bar 1, or vice versa. A wick-cross that does not close across does not count. A close that happened two bars ago does not count. The signal is then handed to ConfirmFilters(), which applies four more side-checks. The H1 EMA(50) must be on the same side of the close as the signal. The RSI(14) must be on the right side of 50 — above for longs, below for shorts. The ADX(14) on the closed bar must be at or above InpAdxMin (20 by default). And the prospective trade must have a risk-to-reward of at least InpMinRR (1.0), measured as the 3×ATR take-profit distance divided by the 2×ATR stop distance. The final confirm gate is the regime: REGIME_CHOPPY and REGIME_COMPRESS reject the trade outright. The EA logs the exact reason for any rejection (HTF-EMA-disagree, RSI-side, ADX-low, RR-low, regime-blocked) so the strategy tester output is readable.
TryOpen() does the order. The position size comes from InpRiskPercent (0.5% default) applied to g_effectiveCap, which is min(InpCapitalCapAmount, equity) when a capital cap is set and just equity otherwise. CalcLot() converts the risk budget into lots via tickValue, tickSize, and the ATR-derived SL distance, and ClampLot() snaps the result to the broker's lot step and bounds. A portfolio-heat check refuses the trade if the sum of all open R-exposures would push total risk above MAX_PORTFOLIO_HEAT (8%). A OrderCalcMargin() pre-check ensures free margin is sufficient. The order is sent with trade.Buy or trade.Sell; on TRADE_RETCODE_REQUOTE or TRADE_RETCODE_PRICE_OFF or TRADE_RETCODE_TIMEOUT, the EA refreshes the quote and retries once. Critically, InpDryRun defaults to true — the EA logs the signal but does not send the order until the operator explicitly turns live trading on. This is the default for the published build, not an oversight.
Once a position is open, ManageOpenPositions() runs every tick to do the post-entry work. The same SL_ATR_MULT=2.0 and TP_ATR_MULT=3.0 baseline used at entry is re-evaluated. Three things happen on every tick. First, at the 1R mark (BE_TRIGGER_R=1.0), the stop is moved to entry plus a 5-point buffer — break-even is a one-shot ratchet, not a perpetual one. Second, at the same 1R mark, the EA attempts a partial close of PARTIAL_FRAC=0.5 (50%), as long as the partial volume is at or above the broker minimum lot and is strictly less than the full position. Third, an ATR trail of InpAtrTrailMult (3.0×) is applied bar by bar: the new stop is current - 3×ATR for longs and current + 3×ATR for shorts, with the requirement that it advances beyond the current stop and stays below/above the live price. Three more exits are also handled: a regime-flip exit that closes any position in clear profit (R ≥ 0.5) if the regime becomes Choppy or Compress, an opposite-signal exit that fires the moment the EMA crossover direction reverses, and a momentum-decay exit (MomentumDecay()) that closes when five consecutive closed bars show strictly shrinking body size and the most recent bar is against the position. A time-based exit at InpMaxBarsInTrade (200 bars) prevents zombie trades that get stuck mid-channel.
The capital cap deserves its own paragraph. With InpCapitalCapAmount=0 (the default), the cap is disabled and the EA risks off full equity — straightforward. When the operator sets a real value, every risk calculation in the EA uses min(cap, equity) as the denominator, so CalcLot() does not scale with a runaway account. This is a prop-firm-friendly feature: set the cap to the firm-allowed balance, and the EA's risk math will silently stop growing the position size once the account is past the cap. The 50 USD InpCapitalCapFloor is the corresponding lower guard: any account drop below that value blocks all new entries. Combined with the 3% daily and 6% weekly loss limits (also expressed as a percentage of effective capital), the EA has three layered equity guards, and the weekly loss is recomputed each tick from the deal history (Monday 00:00 server time onward), not from a separate PnL feed, so the EA cannot be fooled by deposits or withdrawals that happen mid-week.
OnTester() returns the optimisation score (netProfit × profitFactor) / (1 + equityDrawdownPercent), but only if the run has at least 30 trades (TESTER_MIN_TRADES=30); otherwise it returns 0 so that low-sample backtests do not get preferred. A run with no payoff is given PF=0.001 and a no-drawdown run is given DD=0.001 as a guard against divide-by-zero. The score is a robustness-first measure: a high-profit, high-drawdown run scores lower than a moderate-profit, low-drawdown run with the same number of trades. The EA also exposes a InpKillSwitch input that, when set to true, freezes new entries while still managing open positions — useful for pausing a live instance at the broker terminal without having to remove it.
For deployment, the source header notes the EA is portable to FX majors and other metals, but the default chart is XAUUSD on M5, with M5 through H1 as the working range. The 0.5% default risk per trade and 50 USD capital floor mean the EA is comfortable on a 100 USD account — the floor is hit only at the very tail of a losing streak. The session window of 7-to-20 server hour corresponds to the London–New York overlap plus the late-Asia wind-down, which is the right liquidity window for a crossover system on gold. A retail broker with no minimum-stop-policy and a tight spread on XAUUSD is the natural home; the spread guard exists precisely to keep the EA out of toxic fills when the spread widens.
Strategy Deep Dive
EX18003 allocates seven indicator handles in OnInit — iMA(10), iMA(50), iATR(14), iADX(14), iRSI(14), iBands(20, 2.0), and a H1 iMA(50) — and refuses to start with INIT_FAILED if any are invalid. On every new bar, ClassifyRegime() labels the market into one of seven states (Choppy, Range, Compress, Breakout, Weak, Strong, plus an EXPAND override when both ATR and BB-width percentiles are above 70 with ADX≥20) using PercentileOf() over a 100-bar history. NoTradeBlock() then walks ten guards — capital floor, spread>3× the rolling 50-tick average, server hour 7-20, Friday after 22, daily loss worse than -3%, weekly loss worse than -6%, cooldown after three consecutive losses, max concurrent positions, data quality, and broker trade disabled — and aborts the bar on any failure. Only then does SignalDirection() look for the closed-bar EMA(10)/EMA(50) cross, and ConfirmFilters() require the H1 EMA, RSI(14), ADX(14), and an R/R≥InpMinRR before TryOpen() sizes at 0.5% of effective capital (min of capital cap and equity) and sends the order with a one-time requote retry. ManageOpenPositions() runs every tick to apply break-even at 1R, a 50% partial close at 1R, the 3.0× ATR trail, and a stack of full exits — regime flip when in profit, opposite signal, momentum decay, and time-based at 200 bars.
Entries are generated only on a closed-bar EMA(10) over EMA(50) crossover. SignalDirection() reads the last two closed bars of the fast and slow EMAs and returns +1 when the fast closes above the slow on bar 1 after being at or below it on bar 2, or -1 on the inverse. ConfirmFilters() then refuses the trade unless four side-checks all agree: the H1 EMA(50) sits on the right side of the close, RSI(14) is above 50 for longs or below 50 for shorts, ADX(14) on the closed bar is at or above InpAdxMin (20), and the prospective 3×ATR-to-2×ATR R/R meets InpMinRR. The current regime must not be Choppy or Compress. InpDryRun defaults to true, so the EA logs the signal but does not send the order until the operator flips live trading on.
Five distinct exits. A one-shot break-even at 1R (entry plus 5 points) and a 50% partial close at the same 1R mark happen first, then an ATR trail of 3.0× ATR(14) ratchets the stop bar by bar. From there, a regime-flip exit closes the position if the regime becomes Choppy or Compress and the trade is in at least 0.5R of profit, an opposite-signal exit fires the moment the EMA crossover direction reverses, a momentum-decay exit closes when five consecutive closed bars show strictly shrinking bodies with the last bar against the position, and a time-based exit closes any trade that has run for InpMaxBarsInTrade (200) bars.
Initial stop is 2.0× ATR(14) from the entry price (SL_ATR_MULT), placed via trade.Buy/trade.Sell and widened to 1.2× the broker's stop level if the broker's minimum-stop policy is wider than the ATR distance. After entry, the stop is actively managed — moved to break-even (entry plus 5 points) at the 1R mark, then trailed at 3.0× ATR(14) behind price. There is no fixed-pip stop; every position's stop is recomputed from current volatility on every tick.
Take profit is set at 3.0× ATR(14) from entry (TP_ATR_MULT), giving a fixed 1.5:1 R/R relative to the 2.0× ATR stop. Half of the position is closed at the 1R mark via a 50% partial close (PARTIAL_FRAC=0.5), and the remainder rides the ATR trailing stop, so the realised payoff can be a small win, the full 1.5R, or anything in between depending on how price develops.
A $100 minimum account on XAUUSD M5, with the default 0.5% risk per trade and 50 USD capital floor leaving meaningful headroom for the 3% daily and 6% weekly loss limits. The 7-to-20 server session window covers the London–New York overlap and the late-Asia wind-down, which is the right liquidity window for an EMA crossover on gold. Pair it with a low-spread retail broker that respects the EA's spread guard, set InpCapitalCapAmount to the prop-firm balance if running a challenge, and flip InpDryRun to false only after the operator has confirmed the regime classifier and confirm filters match their market view. Best for traders who want a mechanical, regime-aware crossover with explicit cooldown, weekly, and portfolio-heat guards.
Strategy Logic
Pipsgrowth EX18003 TrendFollow — Strategy Logic Analysis (from .mq5 source)
Family: TrendFollow
Magic: 22218003
Version: 2.00
BRIEF:
Closed-bar EMA(fast/slow) crossover as the core signal, wrapped in the 12-layer Excellent Experts spec: ADX+ATR-pctile +BB-width regime gate, HTF EMA(50)+RSI confirm, spread/session /news no-trade filters, fixed-fractional sizing off effective capital, ATR trailing + break-even + partial TP, pyramid off by default, OnTester returns (net*PF)/(1+DD) gated to >=30 trades. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester
INDICATOR STACK:
- Standard
MT5indicators
KEY FUNCTIONS:
UpdateEffectiveCapital()UpdateRealizedPnL()ClassifyRegime()PercentileOf()SignalDirection()ConfirmFilters()NoTradeBlock()CountMyTrades()CountSymbolExposure()TryOpen()CalcLot()ClampLot()- ...and 10 more
INTERNAL CONSTANTS (34 total):
MA_METHOD_INP=MODE_EMA// MA method (fixedEMA)ATR_PERIOD= 14 //ATRperiodADX_PERIOD= 14 //ADXperiodRSI_PERIOD= 14 //RSIperiodBB_PERIOD= 20 // Bollinger periodBB_DEVIATION=2.0// Bollinger deviationHTF_TIMEFRAME=PERIOD_H1// Higher-timeframe trend TFHTF_EMA_PERIOD= 50 //HTFEMAperiodATR_PCTILE_LOOK= 100 //ATRpercentile lookbackBBW_PCTILE_LOOK= 100 //BB-width percentile lookbackSL_ATR_MULT=2.0// Initial SL =SL_ATR_MULT*ATRTP_ATR_MULT=3.0// Initial TP =TP_ATR_MULT*ATR(>=InpMinRR)BE_TRIGGER_R=1.0// Break-even trigger (R multiple)BE_OFFSET_POINTS= 5 // Break-even offset [points]PARTIAL_FRAC=0.5// Partial close fraction- ...and 19 more
INPUT PARAMETERS (19 total across 7 groups):
- [=== Identity ===]
InpMagicNumber=22218003// MagicNumber(thisEAonly) - [=== Identity ===]
InpTradeComment= "Psgrowth.com Expert_18003" // TradeComment - [=== Identity ===]
InpVersionTag= "v2.00" // Version Tag - [=== Risk & Sizing ===]
InpRiskPercent=0.5// Risk perTrade(% of effective capital) - [=== Risk & Sizing ===]
InpFixedLot=0.01// FixedLot(when Risk=0) [lot] - [=== Risk & Sizing ===]
InpDailyLossLimit=3.0// Daily LossLimit(% of effective capital) - [=== Risk & Sizing ===]
InpWeeklyLossLimit=6.0// Weekly LossLimit(% of effective capital) - [=== Risk & Sizing ===]
InpMaxConcurrent= 3 // Max ConcurrentTrades(thisEA, this symbol) - [=== Risk & Sizing ===]
InpCooldownLosses= 3 // Cooldown after N consecutive losses [trades] - [=== Capital Allocation Cap ===]
InpCapitalCapAmount=0.0// Capital CapAmount(real money $) [USD] - [=== Capital Allocation Cap ===]
InpCapitalCapFloor=50.0// Capital CapFloor(block entries below) [USD] - [=== Signal ===]
InpMAFast= 10 // FastEMAPeriod [bars] - [=== Signal ===]
InpMASlow= 50 // SlowEMAPeriod [bars] - [=== Regime / Confirm ===]
InpAdxMin= 20 // MinADXforStrongTrendconfirmation - [=== Regime / Confirm ===]
InpMinRR=1.0// Minimum Risk/Reward ratio - [=== Exit / Manage ===]
InpAtrTrailMult=3.0//ATRTrailing Multiplier [xATR] - [=== Exit / Manage ===]
InpMaxBarsInTrade= 200 // Max Bars inTrade(time exit) [bars] - [=== Dry-Run / Kill ===]
InpDryRun=true// Dry-Run (signals logged, no orders) - [=== Dry-Run / Kill ===]
InpKillSwitch=false//KILLSWITCH(closes nothing, blocks new)
// Pipsgrowth EX18003 TrendFollow — Execution Flow (from source analysis)
// Family: TrendFollow
// Closed-bar EMA(fast/slow) crossover as the core signal, wrapped in the 12-layer Excellent Experts spec: ADX+ATR-pctile +BB-width regime gate, HTF EMA(50)+RSI confirm, spread/session /news no-trade filters, fixed-fractional sizing off effective capital, ATR trailing + break-even + partial TP, pyramid off by default, OnTester returns (net*PF)/(1+DD) gated to >=30 trades. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester
ON_INIT:
Create indicator handles: standard set
Initialize state variables
Detect broker GMT offset
ON_TICK:
1. Refresh indicator buffers (closed-bar shift=1)
2. Manage existing positions:
- Break-even check
- ATR trailing stop
- Profit lock ratchet
- Time-based exit
- Opposite-signal exit
3. If new bar:
a. ClassifyRegime() — ADX/ATR/BB regime detection
b. NoTradeGate() checks:
- Market open + session filter
- Spread limit
- Cooldown after loss
- Consecutive loss limit
- Kill switch
- Max drawdown
- Max concurrent positions
- Daily/weekly loss limits
c. GenerateSignal() — strategy-specific entry logic
d. CheckConfirm() — HTF alignment + R:R + ADX minimum
e. Calculate position size from risk %
f. Execute with retry logic
g. Mark bar to prevent duplicates
ON_TESTER:
Custom fitness = weighted(RecoveryFactor, ROI, ProfitFactor, TradeCount, Sharpe, Drawdown)Optimization Profile
How to Install This EA on MT5
- 1Download the .mq5 file using the button above
- 2Open MetaTrader 5 on your computer
- 3Click File → Open Data Folder in the top menu
- 4Navigate to MQL5 → Experts and paste the .mq5 file there
- 5In MT5, right-click Expert Advisors in the Navigator panel → Refresh
- 6Drag the EA onto an H4 or Daily chart for best results
- 7Configure EMA periods, ADX threshold, and lot size in the dialog
- 8Enable Allow Algo Trading and click OK
EA Parameters
| Parameter | Default | Description |
|---|---|---|
| InpMagicNumber | 22218003 | Magic Number (this EA only) |
| InpTradeComment | "Psgrowth.com Expert_18003" | Trade Comment |
| InpVersionTag | "v2.00" | Version Tag |
| InpRiskPercent | 0.5 | Risk per Trade (% of effective capital) |
| InpFixedLot | 0.01 | Fixed Lot (when Risk=0) [lot] |
| InpDailyLossLimit | 3.0 | Daily Loss Limit (% of effective capital) |
| InpWeeklyLossLimit | 6.0 | Weekly Loss Limit (% of effective capital) |
| InpMaxConcurrent | 3 | Max Concurrent Trades (this EA, this symbol) |
| InpCooldownLosses | 3 | Cooldown after N consecutive losses [trades] |
| InpCapitalCapAmount | 0.0 | Capital Cap Amount (real money $) [USD] |
| InpCapitalCapFloor | 50.0 | Capital Cap Floor (block entries below) [USD] |
| InpMAFast | 10 | Fast EMA Period [bars] |
| InpMASlow | 50 | Slow EMA Period [bars] |
| InpAdxMin | 20 | Min ADX for StrongTrend confirmation |
| InpMinRR | 1.0 | Minimum Risk/Reward ratio |
| InpAtrTrailMult | 3.0 | ATR Trailing Multiplier [x ATR] |
| InpMaxBarsInTrade | 200 | Max Bars in Trade (time exit) [bars] |
| InpDryRun | true | Dry-Run (signals logged, no orders) |
| InpKillSwitch | false | KILL SWITCH (closes nothing, blocks new) |
#property copyright "Pipsgrowth.com"
#property link "https://pipsgrowth.com"
#property version "2.00"
#property strict
#property description "Pipsgrowth.com EX18003 CustomMetric_XAUUSD_5M — EMA crossover trend-following EA, full 12-layer stack."
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\DealInfo.mqh>
CTrade trade;
CPositionInfo position;
CSymbolInfo mysymbol;
CAccountInfo account;
COrderInfo orderinfo;
CDealInfo dealinfo;
//============================ INPUTS (22 total) ===========================
input group "=== Identity ==="
input long InpMagicNumber = 22218003; // Magic Number (this EA only)
input string InpTradeComment = "Psgrowth.com Expert_18003"; // Trade Comment
input string InpVersionTag = "v2.00"; // Version Tag
input group "=== Risk & Sizing ==="
input double InpRiskPercent = 0.5; // Risk per Trade (% of effective capital)
input double InpFixedLot = 0.01; // Fixed Lot (when Risk=0) [lot]
input double InpDailyLossLimit = 3.0; // Daily Loss Limit (% of effective capital)
input double InpWeeklyLossLimit= 6.0; // Weekly Loss Limit (% of effective capital)
input int InpMaxConcurrent = 3; // Max Concurrent Trades (this EA, this symbol)
input int InpCooldownLosses = 3; // Cooldown after N consecutive losses [trades]
input group "=== Capital Allocation Cap ==="
// InpCapitalCapEnabled removed — use InpCapitalCapAmount=0 to disable // Capital Cap Enabled
input double InpCapitalCapAmount = 0.0; // Capital Cap Amount (real money $) [USD]
input double InpCapitalCapFloor = 50.0; // Capital Cap Floor (block entries below) [USD]
input group "=== Signal ==="
input int InpMAFast = 10; // Fast EMA Period [bars]
input int InpMASlow = 50; // Slow EMA Period [bars]
input group "=== Regime / Confirm ==="
input int InpAdxMin = 20; // Min ADX for StrongTrend confirmation
input double InpMinRR = 1.0; // Minimum Risk/Reward ratio
input group "=== Exit / Manage ==="
input double InpAtrTrailMult = 3.0; // ATR Trailing Multiplier [x ATR]
input int InpMaxBarsInTrade = 200; // Max Bars in Trade (time exit) [bars]
input group "=== Dry-Run / Kill ==="
input bool InpDryRun = true; // Dry-Run (signals logged, no orders)
input bool InpKillSwitch = false; // KILL SWITCH (closes nothing, blocks new)
//============================ DEFINES (non-essential tunables) ===========
#define VER_TAG "v2.00"
#define MA_METHOD_INP MODE_EMA // MA method (fixed EMA)
#define ATR_PERIOD 14 // ATR period
#define ADX_PERIOD 14 // ADX periodFull source code available on download
Educational purposes only. Do NOT use with real money. Test on demo accounts only.
Clear Warning: Educational Purposes Only
Clear Warning: This Expert Advisor is for educational and testing purposes only. Do NOT use it with real money. Test only on demo accounts. Trading with real money involves substantial risk of capital loss. This does not constitute investment advice.
Recommended Brokers for This EA
These EAs run on MT5 — use a regulated broker with fast execution and tight spreads
Markets.com
Exness
IC Markets
Similar Expert Advisors
View All Expert AdvisorsMore Trend Following strategy EAs from our library
Pipsgrowth EX16080 Trend
Pipsgrowth.com EX16080 EURUSDTrendFollower — triple-EMA H4 trend follower, full 12-layer stack.
Pipsgrowth EX16081 Trend
Pipsgrowth.com EX16081 GoldTrendEA — XAUUSD H4 EMA cross with Fib targets, full 12-layer stack.
Pipsgrowth EX16033 Trend
Pipsgrowth.com EX16033 EA_Price_Action — price-action grid scalper, full 12-layer stack.
Community
Educational purposes only. Do NOT use with real money. Test on demo accounts only.