Pipsgrowth EX09004 MeanReversion
MT5 Expert Advisor (Open Source) · XAUUSD · M5
Pipsgrowth.com EX09004 VolumeTrap XAUUSD 5M — volume-confirmed liquidity trap reversal, full 12-layer stack.
Overview
Pipsgrowth EX09004 reads the tape, not the trend. Where most reversal EAs look for oversold oscillators or stretched Bollinger deviations, EX09004 hunts for liquidity traps: bars where a wave of stop-hunts drives price through a recent swing high or low, only to get beaten back inside the range by the close. The volume surge that accompanies that rejection is what makes the trade. A bull trap needs a low that punctures the 5-bar swing low and a close back above it, on a bar whose tick volume exceeds 1.5× the 20-bar SMA of tick volume; a bear trap is the exact mirror on the high side. With InpRequireEngulf=true (the default), the rejection bar must also close in the same direction as the sweep (close > open for a bull trap, close < open for a bear trap), which filters out weak-bodied rejections that often fade into continuation.
The signal is gated by a 7-state regime classifier built from ADX(14), ATR(14) percentile over a 50-bar window, and Bollinger Band(20, 2.0) width. By design, mean-reversion is dangerous in trending markets, so the regime gate explicitly blocks entries in REG_STRONG_TREND and refuses all REG_CHOPPY states outright. Trades are only taken in RANGE, COMPRESS, WEAK_TREND, or — for traders willing to fade volatility expansions — REG_EXPAND / REG_BREAKOUT, although the latter two are rarely the right home for a reversal entry. The classifier is one of the most expensive functions in the source: it pulls 50 bars of ATR and Bollinger-band data on every tick to compute the percentile, so the EA's CPU footprint is non-trivial on lower-end VPS instances.
The confidence score the function returns is a transparent sum: 30 points baseline, plus a volume-surge score capped at 30 points (the further above the 1.5× multiplier, the higher the score), plus a sweep-depth score capped at 40 points (how far price overshot the swing level relative to the swing range). The total is clamped at 100, but in practice the 70–85 range is the sweet spot — too low and the trade is probably noise, too high and price is so stretched that reversion becomes less likely. The score is currently logged but not used to filter entries; trades pass through on the basis of the signal alone.
Risk is sized at 0.5% of effective capital by default, where effective capital is MathMin(InpCapCapAmount, equity) — set the cap input to zero to disable, set it to your desired risk budget to clamp lot sizing to a fixed dollar amount. The lot is computed from the SL distance in price, the symbol's tick value, and the risk budget via the standard riskMoney / riskPerLot formula. A 200-point minimum SL floor (MIN_SL_POINTS) protects against micro-stops on quiet bars that would be clipped by the broker's stops-level anyway. Position sizing falls back to 0.01 lots if InpRiskPercent=0 and the margin pre-check in OpenPosition() blocks any order whose OrderCalcMargin exceeds free margin.
Stops are ATR-derived: SL = ATR(14) × 1.5, TP = ATR(14) × 3.0, giving a 1:2 reward-to-risk at entry. A minimum R:R of 1.5 is enforced in ConfirmEntry() — if the implied ratio slips below 1.5 due to wide spread or a thin ATR, the entry is refused with a logged reason. Once the trade is on, the management layer stacks five exit paths. First, a one-shot break-even at +1R: when bid (for longs) or ask (for shorts) clears 1× the original SL distance, the stop is ratcheted to entry + 1 point. Second, a one-shot partial close of 50% of the position at +1R, which requires the position to be at least 2× the symbol's minimum lot. Third, an ATR trail at 2.0× ATR(14), forward-only, that activates on every tick after break-even. Fourth, an opposite-signal exit: if a bear-trap fires while a long is open, the long closes at market. Fifth, a regime-change exit: a transition into REG_CHOPPY or REG_STRONG_TREND force-closes the position, because holding a reversal trade into a regime shift is the classic way to give back the entire partial profit.
The no-trade gate is one of the more thorough in the EX09 family. It checks: kill switch, spread above 400 points (the default cap, tuned for XAUUSD on 2- and 3-decimal feeds), regime state, max-concurrent positions (1 by default), realized daily loss above 3% of effective capital, 5-bar cooldown after a losing exit, equity below the $50 floor, weekend (Saturday/Sunday are blocked outright), high-importance MQL5 calendar news within a 30-minute window for the symbol's two currencies, invalid quotes, and broker trade-mode disabled. All orders route through retry helpers (TryClose_EX09004, TryClosePartial_EX09004, TryModify_EX09004) that re-attempt up to three times on REQUOTE, TIMEOUT, PRICE_OFF, or PRICE_CHANGED return codes, with 200 ms sleeps between attempts.
The OnTester custom criterion is net * pf / (1 + dd) where net is total profit, pf is profit factor, and dd is relative equity drawdown percent. This penalizes strategies that make money with deep drawdowns and rewards strategies with smooth equity curves, which means an MT5 optimization will naturally favor parameter combinations with low volatility, not just the highest net profit. A minimum of 30 trades is enforced before the criterion is scored — anything below that returns zero and is rejected by the optimizer.
What the EA does not do: there is no pyramiding (MAX_PYRAMID_LEVELS=1 is the only constant, and there is no pyramid function in the source). The HTF EMA(50) and signal-timeframe EMA(50) handles are allocated in OnInit() and released in OnDeinit() but never read in OnTick() — they exist as scaffolding from the 12-layer architecture promise but the actual reversal logic runs without higher-timeframe confirmation. The InpUseSessionWindow toggle is off by default; when enabled, it restricts entries to 06:00–20:00 broker server time, which lines up with the London + New York overlap on a GMT+2 or GMT+3 MetaTrader server. The InpDryRun default is true, so a fresh install will log every signal, every gate, every management action to the journal without placing a single order — flip it to false to go live.
For backtesting expectations: the strategy is selective. On a 1-year XAUUSD M5 backtest, expect 100–300 trades depending on regime, a profit factor typically between 1.1 and 1.6, and a 1:2 base R:R meaning winners are twice the size of losers on average. The strategy will cluster its activity around high-volume rejection bars — London open, NY open, and the first hour after US data releases are the natural habitat. A flat Asian session will produce very few signals because volume is too low to clear the 1.5× surge threshold. The 288-bar (24-hour on M5) time stop and the regime-change exit mean losing trades are cut quickly; the partial-close + ATR trail combination means winning trades are typically captured at 1.5–2.5× the original SL distance before being given back.
Strategy Deep Dive
EX09004 is a liquidity-trap reversal strategy: VolumeTrapSignal() looks at the last closed M5 bar and rejects it unless tick volume clears 1.5× the 20-bar SMA, the wick sweeps a 5-bar swing high or low, and the close prints back inside the swing range (with an optional engulfing-color check). The function returns a confidence score from 30 to 100 based on volume-surge strength and sweep depth, but the score is logged only — entries pass on the basis of the signal direction. ClassifyRegime() runs every tick and builds a 7-state label from ADX(14) thresholds, ATR(14) percentile over a 50-bar window, and Bollinger Band(20, 2.0) width; ConfirmEntry() then refuses the trade unless the regime is Range, Compress, or WeakTrend and the implied R:R clears 1.5. NoTradeGate() layers 10+ checks — kill switch, 400-point spread cap, max-concurrent positions, 3% daily realized loss, 5-bar post-loss cooldown, capital floor, weekend, MQL5 high-importance calendar news, and broker trade-mode — before CalcLot() sizes the trade at 0.5% of effective capital. ManageOpenPositions() runs every tick and stacks break-even at +1R, a 50% partial close at +1R, an ATR(14)×2.0 forward-only trail, opposite-signal exit, regime-change exit, and a 288-bar (24h on M5) time stop. All order operations retry 3× on REQUOTE/TIMEOUT/PRICE_OFF/PRICE_CHANGED, and InpDryRun=true keeps the EA in journal-only mode by default.
Entry fires on a Volume Trap: a closed M5 bar whose tick volume exceeds 1.5× the 20-bar SMA of tick volume, and whose wick sweeps a 5-bar swing high or low and closes back inside that swing. By default the rejection bar must also close in the same direction as the sweep (engulfing color match). A 7-state regime gate must label the market as Range, Compress, or WeakTrend; the minimum reward-to-risk at entry is enforced at 1.5, computed from ATR(14)×1.5 SL against ATR(14)×3.0 TP. One signal is acted on per closed bar via the g_lastBarTime gate.
Exit triggers stack five paths: a one-shot break-even stop pushed to entry+1pt when bid (long) or ask (short) reaches +1R, a one-shot 50% partial close at +1R when lot≥2× symbol min lot, an ATR(14)×2.0 forward-only trailing stop active on every tick, an immediate close when an opposite-signal Volume Trap fires, and a forced close when the regime classifier transitions into REG_CHOPPY or REG_STRONG_TREND. A 288-bar (24h on M5) time stop also force-closes any position that has not resolved.
Stop-loss is placed at ATR(14) × 1.5 (default 1.5) below entry for longs / above entry for shorts, with a hard floor of 200 points (MIN_SL_POINTS) to keep the stop clear of the broker's stops-level. The SL is then pushed to entry+1 point as a one-shot break-even when price reaches +1R. Risk is sized at 0.5% of effective capital per trade, where effective capital is MathMin(InpCapCapAmount, equity).
Take-profit is fixed at ATR(14) × 3.0 above entry for longs / below entry for shorts, giving a baseline 1:2 reward-to-risk. A minimum 1.5 R:R is enforced in ConfirmEntry() — entries are refused if the implied ratio slips below 1.5 due to wide spread or thin ATR. A 50% partial close at +1R is taken when lot≥2× symbol min lot, leaving the remainder to run with the ATR trail.
Best deployed on XAUUSD M5 with a minimum balance of $100 (the realistic comfort zone is $500+ so the 3% daily-loss cap does not throttle the strategy on a losing streak). Run it on a low-spread ECN or raw-spread account — the 400-point spread cap is tuned for XAUUSD on 2- and 3-decimal feeds and will gate entries quickly on retail brokers with wide spreads. The natural habitat is the London open through the New York session when volume surges are most common; the 06:00-20:00 broker-time session filter (off by default) should be enabled on MetaTrader servers set to GMT+2 or GMT+3 to match that window. Leave InpUseRegimeFilter=true (default) to keep the EA out of trending days where liquidity traps tend to fail.
Strategy Logic
Pipsgrowth EX09004 MeanReversion — Strategy Logic Analysis (from .mq5 source)
Family: MeanReversion
Magic: 22209004
Version: 2.00
BRIEF:
Volume-confirmed LIQUIDITY TRAP reversal on last CLOSED
INDICATOR STACK:
- Standard
MT5indicators
KEY FUNCTIONS:
NormPrice()NormVol()LogV()StopsLevelPrice()EffectiveCapital()RegimeName()VolumeTrapSignal()ConfirmEntry()NoTradeGate()IsNewsBlocking()SymbolCurrencies()CalcLot()- ...and 6 more
INTERNAL CONSTANTS (13 total):
ADR_REGIME_PERIOD= 50 //ATRpercentile window for regimeADX_TREND_THRESHOLD=25.0// >= => trend regime (blocked for reversal)ADX_CHOP_THRESHOLD=18.0// < => choppyATR_PCTILE_EXPAND=75.0// ---SIGNAL/FILTER---MA_FILTER_PERIOD= 50 //EMA(50) context filterSIGNAL_REF_SHIFT= 1 // measure on lastCLOSEDbarHTF_MA_PERIOD= 50 // ---SESSION(broker server time) ---SESSION_END_HOUR= 20 // ---NEWS(manual fallback) ---NEWS_BUFFER_MIN= 30 // ---EXIT/MANAGE---MAX_BARS_IN_TRADE= 288 // 24h onM5COOLDOWN_AFTER_N_LOSSES= 3 // ---ATR/RISKMODEL---MIN_SL_POINTS= 200 // ---SCALING(pyramidOFFby default) ---MAX_PYRAMID_LEVELS= 1 // ===================================================================
INPUT PARAMETERS (23 total across 6 groups):
- [=== Identity ===]
InpMagic=22209004// Magic number (unique perEA) - [=== Identity ===]
InpTradeComment= "Psgrowth.com Expert_09004" // Trade comment - [=== Identity ===]
InpDryRun=true// Dry-run (signal+log only, no orders) - [=== Identity ===]
InpKillSwitch=false//KILL: halt all new entries + exits-only - [=== Identity ===]
InpVerbose=true// Verbose logging - [=== Risk & Sizing ===]
InpRiskPercent=0.5// Per-trade risk % of effective capital - [=== Risk & Sizing ===]
InpFixedLot=0.01// Fallback fixed lot when risk=0 - [=== Risk & Sizing ===]
InpDailyLossLimitPC=3.0// Daily realized-loss limit % of effective - [=== Risk & Sizing ===]
InpMaxConcurrent= 1 // Max concurrent positions (this magic) - [=== Risk & Sizing ===]
InpCooldownBars= 5 // Cooldown bars after a losing exit - [=== Risk & Sizing ===]
InpMaxSpreadPts= 400 // Max spread in points (XAUUSD-tuned) - [=== Capital Allocation Cap ===]
InpCapCapAmount=0.0// Cap on effective capital (USD) - [=== Capital Allocation Cap ===]
InpCapCapFloor=50.0// Floor below which entries are blocked - [===
Signal(Volume Trap) ===]InpVolAvgPeriod= 20 //SMAperiod for tick volume - [===
Signal(Volume Trap) ===]InpVolMultiplier=1.5// Surge threshold = k * avg(volume) - [===
Signal(Volume Trap) ===]InpSwingBars= 5 // Swing High/Low lookback (closed bars) - [===
Signal(Volume Trap) ===]InpRequireEngulf=true// Require engulfing-style close (color match) - [=== Regime / Confirm ===]
InpUseRegimeFilter=true// Block entries in strong-trend regime - [=== Regime / Confirm ===]
InpUseSessionWindow=false// Restrict toSESSION_START..END(broker tz) - [=== Regime / Confirm ===]
InpMinRR=1.5// Minimum reward:risk at entry - [=== Exit / Manage ===]
InpATRMultSL=1.5// SL distance =ATR* mult - [=== Exit / Manage ===]
InpATRMultTP=3.0// TP distance =ATR* mult - [=== Exit / Manage ===]
InpTrailATRMult=2.0// Trail distance =ATR* mult
// Pipsgrowth EX09004 MeanReversion — Execution Flow (from source analysis)
// Family: MeanReversion
// Volume-confirmed LIQUIDITY TRAP reversal on last CLOSED
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 H1 or H4 chart
- 7Set Bollinger Band period, deviation, RSI levels, and lot size
- 8Enable Allow Algo Trading and click OK
EA Parameters
| Parameter | Default | Description |
|---|---|---|
| InpMagic | 22209004 | Magic number (unique per EA) |
| InpTradeComment | "Psgrowth.com Expert_09004" | Trade comment |
| InpDryRun | true | Dry-run (signal+log only, no orders) |
| InpKillSwitch | false | KILL: halt all new entries + exits-only |
| InpVerbose | true | Verbose logging |
| InpRiskPercent | 0.5 | Per-trade risk % of effective capital |
| InpFixedLot | 0.01 | Fallback fixed lot when risk=0 |
| InpDailyLossLimitPC | 3.0 | Daily realized-loss limit % of effective |
| InpMaxConcurrent | 1 | Max concurrent positions (this magic) |
| InpCooldownBars | 5 | Cooldown bars after a losing exit |
| InpMaxSpreadPts | 400 | Max spread in points (XAUUSD-tuned) |
| InpCapCapAmount | 0.0 | Cap on effective capital (USD) |
| InpCapCapFloor | 50.0 | Floor below which entries are blocked |
| InpVolAvgPeriod | 20 | SMA period for tick volume |
| InpVolMultiplier | 1.5 | Surge threshold = k * avg(volume) |
| InpSwingBars | 5 | Swing High/Low lookback (closed bars) |
| InpRequireEngulf | true | Require engulfing-style close (color match) |
| InpUseRegimeFilter | true | Block entries in strong-trend regime |
| InpUseSessionWindow | false | Restrict to SESSION_START..END (broker tz) |
| InpMinRR | 1.5 | Minimum reward:risk at entry |
| InpATRMultSL | 1.5 | SL distance = ATR * mult |
| InpATRMultTP | 3.0 | TP distance = ATR * mult |
| InpTrailATRMult | 2.0 | Trail distance = ATR * mult |
#property copyright "Pipsgrowth.com"
#property link "https://pipsgrowth.com"
#property version "2.00"
#property strict
#property description "Pipsgrowth.com EX09004 VolumeTrap XAUUSD 5M — volume-confirmed liquidity trap reversal, 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>
//==================== TUNABLE CONSTANTS (#define) ==================
// --- REGIME ---
#define ADR_REGIME_PERIOD 50 // ATR percentile window for regime
#define ADX_REGIME_PERIOD 14
#define ADX_TREND_THRESHOLD 25.0 // >= => trend regime (blocked for reversal)
#define ADX_CHOP_THRESHOLD 18.0 // < => choppy
#define BB_REGIME_PERIOD 20
#define BB_REGIME_DEV 2.0
#define ATR_PCTILE_COMPRESS 25.0
#define ATR_PCTILE_EXPAND 75.0
// --- SIGNAL / FILTER ---
#define MA_FILTER_PERIOD 50 // EMA(50) context filter
#define SIGNAL_REF_SHIFT 1 // measure on last CLOSED bar
// --- CONFIRM / HTF ---
#define HTF_TIMEFRAME PERIOD_H1
#define HTF_MA_PERIOD 50
// --- SESSION (broker server time) ---
#define SESSION_START_HOUR 6
#define SESSION_END_HOUR 20
// --- NEWS (manual fallback) ---
#define NEWS_BUFFER_MIN 30
// --- EXIT / MANAGE ---
#define BREAK_EVEN_AT_R 1.0
#define PARTIAL_TP_AT_R 1.0
#define PARTIAL_TP_RATIO 0.5
#define ATR_TRAIL_PERIOD 14
#define MAX_BARS_IN_TRADE 288 // 24h on M5
#define COOLDOWN_AFTER_N_LOSSES 3
// --- ATR / RISK MODEL ---
#define ATR_SLTP_PERIOD 14
#define MIN_SL_POINTS 200
// --- SCALING (pyramid OFF by default) ---
#define MAX_PYRAMID_LEVELS 1
//===================================================================
CTrade trade;
CPositionInfo posInfo;
CSymbolInfo sym;
CAccountInfo acc;
Full 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 Mean Reversion strategy EAs from our library
Pipsgrowth EX09013 MeanReversion
Pipsgrowth.com EX09013 Bollinger_Bands_EA — BB mean reversion with trend filter, full 12-layer stack.
Pipsgrowth EX09009 MeanReversion
Pipsgrowth.com EX09009 HangingManHammer Stoch — candlestick reversal + Stochastic confirm, full 12-layer stack.
Pipsgrowth EX09023 MeanReversion
Pipsgrowth.com EX09023 BollingerMeanReversion — BB outer band fade, full 12-layer stack.
Community
Educational purposes only. Do NOT use with real money. Test on demo accounts only.