Pipsgrowth EX09023 MeanReversion
MT5 Expert Advisor (Open Source) · XAUUSD · M5, H1
Pipsgrowth.com EX09023 BollingerMeanReversion — BB outer band fade, full 12-layer stack.
Overview
Pipsgrowth EX09023 BollingerMeanReversion fades outer Bollinger Band touches on a single-instrument basis. The strategy is built around a deliberately small signal stack: a single iBands(20, 2.0, PRICE_CLOSE) handle, no confirmation indicator, and no regime classifier. When the bid reaches or pierces the lower band, the EA buys with the BB middle as the profit target. When the bid reaches or pierces the upper band, the EA sells with the BB middle as the profit target. SL is fixed at 30 pips; lot is fixed at 0.10; one position at a time. The whole design is essentially a minimum-viable mean-reversion loop, and the article below walks through every actual code path so traders can verify the claim before going live.
The header in the source comment advertises a 12-layer stack: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester. Of those twelve, only seven have actual logic. SIGNAL and ENTRY (the BB-touch trigger), NO-TRADE (an 8-gate IsSafeToTrade), CAPITAL CAP (InpCapAmount / InpCapFloor), RISK (3% daily loss limit, 5.0 max lot), SIZING (fixed lot 0.10), EXIT (the SL plus a dynamic BB-middle TP), and OnTester are implemented. REGIME (no classifier), CONFIRM (no second-stage filter), MANAGE (no trailing, no break-even, no partial close), and SCALING (no pyramid, no martingale, no grid) are missing. That is not an oversight — the EA's stance is that any extra layer would dilute a clean fade, and the header is intentionally left as a marketing-style aspirational list rather than a contract.
The entry logic lives in OnTick. The tick handler runs UpdateDailyCounters_EX09023 (rolls g_tradesToday, g_consecLosses, g_realizedToday to zero on a new calendar day), then checks HasTrade() to enforce single-position control. HasTrade scans PositionsTotal from the top, looking for any open position with magic 22209023 on the chart symbol; if one is found, the tick returns immediately. The current bar's open time is read; if it matches the lastBar timestamp, the tick returns — signal evaluation only runs on bar close, not on every tick. The 8-gate IsSafeToTrade_EX09023 must clear, then the EA copies buffer 1 (upper), buffer 2 (lower), and buffer 0 (middle) from the BB handle for bar 1, the just-closed bar. If bid <= lower[0], a buy loop runs three times: each iteration recomputes OrderCalcMargin for ORDER_TYPE_BUY at the current ASK, checks ACCOUNT_MARGIN_FREE, and calls TryBuy_EX09023; between iterations the loop sleeps 500ms. The mirror logic fires on bid >= upper[0] via TrySell_EX09023. Both Try functions accept the BB middle as the TP argument.
A subtle but important design choice is in the TP calculation. The source declares input int InpTakeProfit = 20 and computes a local double tp = InpTakeProfit * _Point * 10, but that local is never passed to TryBuy or TrySell. The TP argument sent in the call is mid[0] — the BB middle band, recomputed every tick from CopyBuffer. The InpTakeProfit input is dead code. The reason is consistent with a mean-reversion philosophy: the EA is not trying to capture a fixed pip target, it is trying to ride the touch back to the statistical mean. On a ranging day mid[0] could be 50 pips away; on a trending day it could be 5 pips or 200 pips. The fixed 30-pip SL is the safety net; the TP is the equilibrium. There is no way to override this through the inputs — the InpTakeProfit value is purely cosmetic.
Position management is intentionally absent. There is no ManageTrailingStop() call, no break-even function, no partial close at 1R, no time stop, and no reverse-signal exit. A position opened by the BB touch closes only when the SL is hit, when price reaches the BB middle band, or when the broker force-closes (margin call, weekend gap, manual close, etc.). The OnTradeTransaction handler updates g_realizedToday, g_realizedWeek, g_tradesToday, and g_consecLosses from the deal stream — it does not move stops. The deliberate omission of in-trade management is what makes the 7-of-12 layer claim honest. EX09023 is for traders who want a one-shot BB fade with deterministic behaviour, not an adaptive exit scheme.
The 8-gate IsSafeToTrade_EX09023 walks in this strict order. (1) If InpCapAmount > 0 and equity >= InpCapAmount, return false — the soft dollar cap. (2) If InpCapFloor > 0 and equity < InpCapFloor, return false — the floor. (3) If g_initialBalance > 0 and equity < g_initialBalance * 0.95, return false — the 5% drawdown gate. (4) EffectiveCapital = min(CapAmount, equity) or full equity; if g_realizedToday <= -EffectiveCapital * 0.03, return false — the 3% daily loss limit. (5) Same check on g_realizedWeek at 2x (i.e., 6% weekly loss limit). (6) If consec losses >= 3 and current time < g_cooldownUntil (set 30 minutes after the third loss), return false — the cooldown gate. (7) If g_tradesToday >= 50, return false — the daily trade cap. (8) IsMarketOpen, InActiveSession, optional news filter. The session logic uses London 7-16 and New York 12-21 GMT, with an InpAvoidAsia toggle that blocks Asia-only bars (Asian hours are blocked only when London and NY are not also active, so the London-Asia overlap is still allowed). The news filter is time-based — 15 minutes around the London and NY session open hours, not the MQL5 economic calendar feed — and is OFF by default. DetectGMTOffset_EX09023 walks H1 bars for a 3+ hour gap and uses the gap to compute the server-to-GMT offset, falling back to InpServerGMTOffset if non-zero.
Order execution is a two-layer retry. The outer layer lives in OnTick: three attempts spaced 500ms apart, each with an OrderCalcMargin pre-check. If TryBuy or TrySell returns true, the tick returns. The inner layer lives inside TryBuy/TrySell: three attempts spaced 200ms apart, with a hard floor on retcode — only REQUOTE, TIMEOUT, PRICE_OFF, and PRICE_CHANGED trigger a retry; every other retcode hard-breaks. Lot is floor-rounded to the symbol's volume step, then clamped to [minLot, maxLot]. There is no deviation or slippage parameter, which means the EA uses the broker's default fill policy. On brokers with slow execution or wide requotes, the retry budget can be exhausted in milliseconds and a viable signal can be missed.
OnTester returns (STAT_PROFIT * STAT_PROFIT_FACTOR) / (1.0 + STAT_EQUITY_DDREL_PERCENT), with a 30-trade minimum and a guard against pf<=0 or dd<=0. This is a profit-per-unit-of-drawdown score; it rewards raw profit scaled by profit factor and penalised by drawdown. The 30-trade minimum is a hard cutoff — backtests with fewer than 30 closed trades return 0 and the optimizer will discard that parameter set. There is no multi-objective score and no walk-forward helper in the source.
In a backtest, expect 30-200 closed trades per symbol per year depending on the symbol's volatility and how often the BB outer band is touched. The XAUUSD M5 default is the natural fit: BB(20, 2.0) outer bands touch frequently on gold's intraday range, and the BB-middle dynamic TP gives the EA room to capture mean reversion on London and New York sessions. The 0.10 lot default and 30-pip SL are sized for a moderate account; with minDeposit $100 (per the metadata), most users will want to either reduce the lot or run a larger account. For traders who want a minimal BB fade with clean reporting, deterministic behaviour, and no surprise complexity, EX09023 is the family member to pick. For traders who want a pyramid, a regime switch, a multi-confirmation stack, or hedging-account-specific behaviour, look at EX09013, EX09015, EX09020, or EX09021 instead.
Strategy Deep Dive
Pipsgrowth EX09023 BollingerMeanReversion runs on a single iBands(20, 2.0, PRICE_CLOSE) handle — no confirmation indicator, no regime classifier, no second-stage filter, and no HTF context lookup. On every bar close, OnTick checks single-position control via HasTrade() and runs the 8-gate IsSafeToTrade_EX09023 (cap reached / floor / 95% initial equity / 3% daily / 6% weekly / consec-3-loss cooldown / 50 trades per day / market-open + London-NY session + optional news filter) before evaluating a band touch. The 12-layer header in the source is aspirational — only SIGNAL+ENTRY+NO-TRADE+CAPITAL CAP+RISK+SIZING+EXIT+OnTester have actual code; REGIME, CONFIRM, MANAGE, and SCALING are missing by design. Order execution is a 500ms-outer + 200ms-inner two-layer retry on REQUOTE/TIMEOUT/PRICE_OFF/PRICE_CHANGED; on any other retcode the order hard-breaks, and there is no slippage parameter, so the EA uses the broker's default fill policy. There is no in-trade management — no trailing, no break-even, no partial close, no time stop, no reverse-signal exit — a position closes only at SL, at the dynamic BB-middle TP, or on broker force-close. OnTester scores (STAT_PROFIT * STAT_PROFIT_FACTOR) / (1.0 + STAT_EQUITY_DDREL_PERCENT) with a hard 30-trade minimum.
A buy fires when bid <= lower band of iBands(20, 2.0, PRICE_CLOSE) on the just-closed bar; a sell fires when bid >= upper band. The TP is set to the BB middle band (the InpTakeProfit input is defined but unused — the EA always targets the statistical mean, not a fixed pip target). Single-position control via HasTrade() blocks a new entry if a magic-22209023 position is already open on the chart symbol.
A position closes only when its SL is hit, when price reaches the BB middle band (the dynamic TP), or when the broker force-closes (margin call, weekend gap, manual close). No trailing, no break-even, no partial close, no time stop, and no reverse-signal exit are implemented. The OnTradeTransaction handler updates daily/weekly/consec-loss counters from the deal stream but does not move stops.
Fixed stop loss of 30 pips (InpStopLoss * _Point * 10 = 30 * 0.01 * 10 on a 2-digit XAUUSD broker, 30 * 0.001 * 10 on a 5-digit broker) is applied to every entry. There is no global drawdown cap beyond the IsSafeToTrade 95% initial-balance equity floor and the 3% daily / 6% weekly loss limits.
The TP is the BB middle band (mid[0]) — dynamic, not a fixed pips target. The InpTakeProfit = 20 input is computed locally as tp but never passed to TryBuy or TrySell; the EA always rides the band-touch back to the statistical mean, which can be anywhere from 5 to 200+ pips depending on volatility.
Minimum recommended balance: $100 (matches the metadata's MEDIUM riskLevel, but the 0.10 fixed lot at the 30-pip SL implies ~$30 per-trade risk on XAUUSD at 2-digit pricing, so most users will want to either size the lot down or run a larger account). XAUUSD on M5 is the natural fit — BB(20, 2.0) outer bands touch frequently on gold's intraday range, and the BB-middle dynamic TP gives the EA room to capture mean reversion on the London (7-16 GMT) and New York (12-21 GMT) sessions. A low-spread broker is preferred because the EA has no deviation parameter and uses the broker's default fill policy; wide requotes will hard-break rather than retry. For traders who want a minimal BB fade with no in-trade management, no pyramid, and no surprise complexity, EX09023 is the cleanest member of the family; for multi-confirmation, regime switching, or scaling, look at EX09013, EX09015, EX09020, or EX09021 instead.
Strategy Logic
Pipsgrowth EX09023 MeanReversion — Strategy Logic Analysis (from .mq5 source)
Family: MeanReversion
Magic: 22209023
Version: 2.00
BRIEF:
Bollinger Band mean reversion EA that fades outer band touches with fixed SL/TP and single-position control, using the 12-layer stack: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester
INDICATOR STACK:
- Standard
MT5indicators
KEY FUNCTIONS:
OnTradeTransaction()HasTrade()EffectiveCapital_EX09023()DetectGMTOffset_EX09023()ServerToGMT_EX09023()IsMarketOpen_EX09023()InActiveSession_EX09023()IsNewsTime_EX09023()IsSafeToTrade_EX09023()UpdateDailyCounters_EX09023()TryBuy_EX09023()TrySell_EX09023()
INTERNAL CONSTANTS (0 total):
INPUT PARAMETERS (0 total across 0 groups):
// Pipsgrowth EX09023 MeanReversion — Execution Flow (from source analysis)
// Family: MeanReversion
// Bollinger Band mean reversion EA that fades outer band touches with fixed SL/TP and single-position control, using the 12-layer stack: 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
#property copyright "Pipsgrowth.com"
#property link "https://pipsgrowth.com"
#property version "2.00"
#property strict
#property description "Pipsgrowth.com EX09023 BollingerMeanReversion — BB outer band fade, full 12-layer stack."
#include <Trade\Trade.mqh>
input group "=== Identity ==="
input int InpMagicNumber = 22209023;
input string InpTradeComment = "Psgrowth.com Expert_09023";
input group "=== Trading ==="
input double InpLotSize = 0.10;
input int InpStopLoss = 30;
input int InpTakeProfit = 20;
input group "=== Signal ==="
input int InpBBPeriod = 20;
input double InpBBDev = 2.0;
input group "=== Hardening: Risk Management ==="
input double InpDailyLossLimitPct = 3.0;
input double InpMaxLot = 5.0;
input group "=== Capital Allocation Cap ==="
// InpCapEnabled removed — use InpCapAmount=0 to disable
input double InpCapAmount = 0.0;
input double InpCapFloor = 50.0;
input group "=== Hardening: GMT Sessions ==="
input int InpServerGMTOffset = 0;
input int InpLondonStartHour = 7;
input int InpLondonEndHour = 16;
input int InpNYStartHour = 12;
input int InpNYEndHour = 21;
input bool InpAvoidAsia = true;
input int InpAsiaStartHour = 0;
input int InpAsiaEndHour = 7;
input bool InpNewsFilter = false;
input int InpNewsFilterMinutes = 15;
input int InpMaxTradesPerDay = 50;
input double InpMinEquityPercent = 95.0;
input int InpCooldownMinutes = 30;
input int InpMaxConsecLosses = 3;
CTrade trade; int hBB; datetime lastBar=0;
double g_initialBalance=0; int g_gmtOffset=0; int g_consecLosses=0;
datetime g_cooldownUntil=0; double g_realizedToday=0; double g_realizedWeek=0;
int g_tradesToday=0; datetime g_lastTradeDate=0;
int OnInit() {
trade.SetExpertMagicNumber(InpMagicNumber);
hBB=iBands(_Symbol,PERIOD_CURRENT,InpBBPeriod,0,InpBBDev,PRICE_CLOSE);
if(hBB==INVALID_HANDLE) return INIT_FAILED;
if(InpMagicNumber==0) { Print("EX09023: Magic must be non-zero"); return INIT_PARAMETERS_INCORRECT; }
if(InpLotSize<=0) { Print("EX09023: LotSize must be > 0"); return INIT_PARAMETERS_INCORRECT; }
if(InpCapAmount > 0.0 && InpCapFloor>=InpCapAmount) { Print("EX09023: CapFloor must be < CapAmount"); return INIT_PARAMETERS_INCORRECT; }
if(InpMaxTradesPerDay<=0) { Print("EX09023: MaxTradesPerDay must be > 0"); return INIT_PARAMETERS_INCORRECT; }
if(InpMaxLot<=0) { Print("EX09023: MaxLot must be > 0"); return INIT_PARAMETERS_INCORRECT; }
g_initialBalance=AccountInfoDouble(ACCOUNT_BALANCE);
g_gmtOffset=DetectGMTOffset_EX09023();
PrintFormat("EX09023 init OK magic=%d GMT=%d",InpMagicNumber,g_gmtOffset);
return INIT_SUCCEEDED;
}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 EX09009 MeanReversion
Pipsgrowth.com EX09009 HangingManHammer Stoch — candlestick reversal + Stochastic confirm, full 12-layer stack.
Pipsgrowth EX09007 MeanReversion
Pipsgrowth.com EX09007 HangingManHammer MFI — candlestick reversal + MFI confirm, full 12-layer stack.
Pipsgrowth EX09013 MeanReversion
Pipsgrowth.com EX09013 Bollinger_Bands_EA — BB mean reversion with trend filter, full 12-layer stack.
Community
Educational purposes only. Do NOT use with real money. Test on demo accounts only.