Pipsgrowth EX09003 MeanReversion
MT5 Expert Advisor (Open Source) · XAUUSD · M5
Pipsgrowth.com EX09003 CycleSwing XAUUSD 5M — CCI ±100 + Stochastic cross mean-reversion, full 12-layer stack.
Overview
Pipsgrowth EX09003 CycleSwing is a counter-cyclical XAUUSD EA that fades Commodity Channel Index extremes after a confirming Stochastic turn. The thesis is mechanical: when CCI has pushed beyond its oversold band (-100) or overbought band (+100) and the Stochastic main line crosses its signal back inside the middle band (below 50 for longs, above 50 for shorts), the cycle is assumed to be reverting, and the EA enters in the direction of the snap-back. With magic 22209003, version 2.00, and the suggested pair being XAUUSD on M5, the EA is purpose-tuned for a fast-fade model on gold where the bulk of profitable cycle reversals happen in 1-3 hour bursts.
The signal layer is the CycleSwingSignal() function, which reads two closed-bar values of CCI(14) and Stochastic(14,3,3) and checks for a band-cross plus a main/signal cross in the same direction. The depth of the prior excursion feeds a confidence value between 10 and 100 — a deeper CCI excursion under -100 before the cross yields a higher reading, on the logic that the more stretched the cycle, the stronger the snap-back. Buy and sell are exact mirrors: a long requires cciPrv < -100 && cciNow > -100 together with stochMain crosses above stochSignal while stochMain < 50; a short requires the opposite around +100. Reads on the live bar (shift 0) are not used — the EA only acts on fully closed bars, which avoids the most common source of false CCI re-entries.
Before any signal can fire, it has to clear a 7-state regime classifier. The ClassifyRegime() function uses ADX(14), ATR(14), and Bollinger Bands(20, 2.0) to label the current market as one of StrongTrend, WeakTrend, Range, Breakout, Compress, Expand, or Choppy. The classification depends on three things: ADX relative to 18 (chop) and 25 (trend), the ATR percentile over a 50-bar window, and the current Bollinger width against its recent average. For mean-reversion, only Range, Compress, and WeakTrend are tradeable. StrongTrend, Breakout, Expand, and Choppy all block entries by default — the explicit comment in ConfirmEntry() is "avoid fighting strong trend." This filter is the single largest determinant of when EX09003 trades at all; in a trending week, expect very few signals.
There is also a higher-timeframe confirmation. The EA pulls a 50-period EMA on H1 and refuses to enter if price is more than 3 × ATR(14) away from that EMA. The point is to allow counter-trend scalps on mean-reversion pairs only when the broader structure is not actively trending — price hugging the H1 EMA is a permissive condition, while price 3 ATRs above the EMA in a 1H uptrend is a no-trade. If you disable the regime filter (the InpUseRegimeFilter input), only the Choppy regime still blocks. The session window is opt-in via InpUseSessionWindow and, when enabled, restricts entries to broker-server hours 06:00-20:00, which roughly covers the Asia→London handover into the New York pre-open. It is off by default.
The no-trade gate adds a half-dozen mechanical checks. A kill switch (InpKillSwitch) halts entries instantly. Spread must be under 400 points (the cap is XAUUSD-tuned — at 2-decimal gold, 400 points is $0.40, so a wide retail spread will gate entries). A realized-daily-loss check sums DEAL_PROFIT+SWAP+COMMISSION for closed deals with this magic today and refuses new entries once the cumulative realized loss hits 3% of effective capital. After a losing close, a 5-bar cooldown (≈25 minutes on M5) blocks re-entry. A capital floor of $50 stops the EA from trading on depleted accounts. Weekend hours are blocked. A high-importance news check uses CalendarValueHistory against the two currencies of the chart symbol (XAU and USD), and refuses entries inside a ±30-minute window around red-flag events. Finally, a SYMBOL_TRADE_MODE_FULL check makes sure the broker has not disabled trading on the symbol.
Position sizing is risk-percent driven. With InpRiskPercent = 0.5 as the default and the 1.5 × ATR(14) stop distance, the EA computes the risk per lot from tick_value and tick_size, divides 0.5% of effective capital by that risk, and falls back to 0.01 lot if either side returns zero. A 200-point hard floor (MIN_SL_POINTS) is applied to the SL distance before sizing so the lot cannot blow up in a low-ATR environment. Effective capital itself is governed by an opt-in cap: setting InpCapCapAmount > 0 means the EA pretends the account only has that many dollars for risk purposes, which is useful for staged scaling.
Once in, management is handled by ManageOpenPositions(), which runs every tick. Six distinct events are handled: (a) a one-shot break-even at +1R, moving the stop to open + 1 point once price has travelled one ATR-multiple in favor; (b) a one-shot partial close at +1R, offloading 50% of the position (only if the remaining volume is at least the broker's minimum lot); (c) an ATR trail at 2.0 × ATR(14) behind price, only ratcheting forward; (d) an opposite-signal exit that closes the trade if a fresh signal in the other direction fires; (e) a time-based exit at MAX_BARS_IN_TRADE = 288 bars (24 hours on M5); and (f) a regime-choppy exit that closes the position immediately if the classifier transitions to Choppy. All three retry helpers (TryClose_EX09003, TryClosePartial_EX09003, TryModify_EX09003) re-attempt on REQUOTE/TIMEOUT/PRICE_OFF/PRICE_CHANGED with a 200ms sleep (100ms for modify).
The default state out of the box is dry-run: InpDryRun = true means the EA logs every signal, every regime label, every gating decision, and every simulated fill, but does not send orders. The intended workflow is to attach the EA to a chart, watch the verbose log for several days across different sessions and regimes, confirm that the trade frequency, regime gating, and SL/TP distances match expectations, and then flip InpDryRun to false. The EA also ships with a custom OnTester() criterion: net * profit_factor / (1 + relative_drawdown), which means the Strategy Tester will rank parameter sets that combine net profit and profit factor while penalising drawdown, with a hard floor of 30 trades and a positive PF before the score is non-zero.
What this EA is not: it is not a trend-follower, not a grid, not a martingale, and not a pyramider. MAX_PYRAMID_LEVELS = 1 and there are no lot multipliers. It is a tight, single-position, regime-gated cycle-fader designed for XAUUSD on M5, and its edge comes from the regime filter and the HTF EMA distance gate refusing trades in the wrong structural context. The minimum recommended balance is $100, with the broader expectation that anything below $250 will see the 3% daily-loss cap hit on a bad day before the EA's edge can play out across many trades. Pair it with an ECN or raw-spread account so the 400-point spread cap is rarely the gating factor.
Strategy Deep Dive
Every tick, EX09003 classifies the regime using ADX(14), ATR(14), and Bollinger Bands(20, 2.0), refusing to act in StrongTrend, Breakout, Expand, or Choppy conditions where mean-reversion is unreliable. The CycleSwingSignal() function then watches for CCI(14) to cross back over the ±100 bands while Stochastic(14,3,3) main line crosses its signal inside the middle band, scoring confidence by the depth of the prior CCI excursion. The 50-EMA on H1 acts as a structural guard — entries are blocked if price is more than 3×ATR(14) from that line, preventing counter-trend fades that fight a stronger higher-timeframe trend. The no-trade gate layers spread, daily realized loss, post-loss cooldown, capital floor, news, and weekend checks on top. When all gates clear, OpenPosition() sizes the lot to 0.5% risk of effective capital and sends a market order with ATR-derived SL and TP, after which ManageOpenPositions() handles break-even, partial close, ATR trail, opposite-signal exit, time-based exit, and regime-choppy exit on every subsequent tick.
Long entry when CCI(14) crosses back up over -100 AND Stochastic main crosses above signal with main below 50; short entry is the mirror on the +100 overbought band cross. The signal must clear the regime filter (RANGE, COMPRESS, or WEAK_TREND only), the HTF EMA distance gate (price within 3×ATR(14) of the H1 50-EMA), the minimum 1.5 reward-to-risk at entry, and the per-bar no-trade gate covering spread, daily realized loss, post-loss cooldown, capital floor, news, and weekend.
Positions close on a fresh opposite-direction signal, on a regime transition into Choppy, or on a time-based exit at 288 bars (24 hours on M5). A one-shot break-even ratchet moves the stop to entry+1 point at +1R, a one-shot partial close releases 50% of the position at +1R (only if the residual is at least the broker's minimum lot), and an ATR trail at 2.0×ATR(14) behind price ratchets forward-only.
Stop loss is placed at entry ± 1.5 × ATR(14), with a hard floor of 200 points (XAUUSD at 2 decimals) to prevent runaway lots in low-volatility environments. Once price has moved 1R in favor, a one-shot break-even ratchet lifts the stop to entry + 1 point (or entry - 1 point for shorts).
Take profit is placed at entry ± 1.5 × ATR(14) — a 1:1 reference that the confirm layer bumps up to a minimum 1.5 R:R using the actual TP/SL distances. A 50% partial close fires at +1R to lock in scratch-free profit, with the remainder managed by the ATR trail, the time-based exit, or the regime-choppy exit.
Best deployed on XAUUSD M5 with a minimum recommended balance of $100 (the realistic comfort zone is $500 and up so the 3% daily-loss cap does not throttle the strategy on a bad day). Run it on a low-spread ECN or raw-spread account — the 400-point spread cap is tuned for XAUUSD at 2 decimals ($0.40) and will gate entries quickly on a retail broker with wide spreads. Keep the regime filter on (the default) to keep the EA out of trend and breakout days, and leave the session window off unless your broker's server clock aligns with the 06:00-20:00 active window you actually want. Risk level is MEDIUM; the EA expects to be wrong often but to make the cycle-fade pay-off on a meaningful subset of trades.
Strategy Logic
Pipsgrowth EX09003 MeanReversion — Strategy Logic Analysis (from .mq5 source)
Family: MeanReversion
Magic: 22209003
Version: 2.00
BRIEF:
Cycle-swing mean-reversion: CCI ±100 band cross + Stochastic main/signal cross. BUY when CCI crosses back up over -100 AND Stoch main > sig AND Stoch main < 50; SELL mirror over +100. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester
INDICATOR STACK:
- Standard
MT5indicators
KEY FUNCTIONS:
NormPrice()NormVol()LogV()StopsLevelPrice()EffectiveCapital()RegimeName()CycleSwingSignal()ConfirmEntry()NoTradeGate()IsNewsBlocking()SymbolCurrencies()CalcLot()- ...and 6 more
INTERNAL CONSTANTS (15 total):
ADR_REGIME_PERIOD= 50 //ATRpercentile window for regimeADX_TREND_THRESHOLD=25.0// >= => trend regimeADX_CHOP_THRESHOLD=18.0// < => choppyATR_PCTILE_COMPRESS=25.0// < pctl => compressATR_PCTILE_EXPAND=75.0// > pctl => expandCCI_OB_LEVEL=100.0// overbought bandSTOCH_MID_LEVEL=50.0// mid threshold (room to revert)HTF_MA_PERIOD= 50 // ---SESSION(broker server time) ---SESSION_START_HOUR= 6 // Asia->Europe handover (broker tz)SESSION_END_HOUR= 20 // ---NEWS(manual fallback ifCalendarValueHistoryunavailable) ---NEWS_BUFFER_MIN= 30 // ---EXIT/MANAGE---MAX_BARS_IN_TRADE= 288 // 24h onM5COOLDOWN_AFTER_N_LOSSES= 3 // ---ATR/RISKMODEL---MIN_SL_POINTS= 200 // hard floor for SL distance (XAUUSD-tuned)MAX_PYRAMID_LEVELS= 1 // 1 = no pyramid
INPUT PARAMETERS (22 total across 6 groups):
- [=== Identity ===]
InpMagic=22209003// Magic number (unique perEA) - [=== Identity ===]
InpTradeComment= "Psgrowth.com Expert_09003" // 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 - [=== Cycle Signal ===]
InpCCIPeriod= 14 //CCIperiod (cycle amplitude) - [=== Cycle Signal ===]
InpStochK= 14 // Stochastic %K - [=== Cycle Signal ===]
InpStochD= 3 // Stochastic %D(slowing) - [=== Regime / Confirm ===]
InpUseRegimeFilter=true// Block entries outside Range/Compress/WeakTrend - [=== 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=1.5// TP distance =ATR* mult (MR uses tighter TP) - [=== Exit / Manage ===]
InpTrailATRMult=2.0// Trail distance =ATR* mult
// Pipsgrowth EX09003 MeanReversion — Execution Flow (from source analysis)
// Family: MeanReversion
// Cycle-swing mean-reversion: CCI ±100 band cross + Stochastic main/signal cross. BUY when CCI crosses back up over -100 AND Stoch main > sig AND Stoch main < 50; SELL mirror over +100. 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 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 | 22209003 | Magic number (unique per EA) |
| InpTradeComment | "Psgrowth.com Expert_09003" | 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 |
| InpCCIPeriod | 14 | CCI period (cycle amplitude) |
| InpStochK | 14 | Stochastic %K |
| InpStochD | 3 | Stochastic %D (slowing) |
| InpUseRegimeFilter | true | Block entries outside Range/Compress/WeakTrend |
| 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 | 1.5 | TP distance = ATR * mult (MR uses tighter TP) |
| 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 EX09003 CycleSwing XAUUSD 5M — CCI ±100 + Stochastic cross mean-reversion, 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
#define ADX_CHOP_THRESHOLD 18.0 // < => choppy
#define BB_REGIME_PERIOD 20
#define BB_REGIME_DEV 2.0
#define ATR_PCTILE_COMPRESS 25.0 // < pctl => compress
#define ATR_PCTILE_EXPAND 75.0 // > pctl => expand
// --- SIGNAL (original 1247 cycle swing) ---
#define CCI_APPLIED_PRICE PRICE_TYPICAL
#define STOCH_MA_METHOD MODE_SMA
#define STOCH_PRICE_FIELD STO_LOWHIGH
#define CCI_OS_LEVEL -100.0 // oversold band
#define CCI_OB_LEVEL 100.0 // overbought band
#define STOCH_MID_LEVEL 50.0 // mid threshold (room to revert)
// --- CONFIRM / HTF ---
#define HTF_TIMEFRAME PERIOD_H1
#define HTF_MA_PERIOD 50
// --- SESSION (broker server time) ---
#define SESSION_START_HOUR 6 // Asia->Europe handover (broker tz)
#define SESSION_END_HOUR 20
// --- NEWS (manual fallback if CalendarValueHistory unavailable) ---
#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 // hard floor for SL distance (XAUUSD-tuned)
// --- SCALING (pyramid OFF by default) ---
#define MAX_PYRAMID_LEVELS 1 // 1 = no pyramid
//===================================================================
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.