Pipsgrowth EX09024 MeanReversion
MT5 Expert Advisor (Open Source) · XAUUSD · M5, H1
Pipsgrowth.com EX09024 RSIMeanReversion — RSI extremes mean-reversion with static SL/TP, full 12-layer stack.
Overview
EX09024 RSIMeanReversion is a deliberate exercise in subtraction. Where most of the EX09 family composes two or three indicators into a multi-stage decision, EX09024 takes one oscillator — RSI with InpRSIPeriod=14 — and two threshold-cross rules. That is the entire signal stack. Buy when the previous bar's RSI was below InpOversold=25 and the current bar's RSI has crossed back to 25 or above. Sell when the previous bar's RSI was above InpOverbought=75 and the current bar has crossed back to 75 or below. The rest of the file is risk and safety scaffolding, not signal generation.
The cross requirement is what separates EX09024 from a plain "RSI < 25" oversold-buy. EX09024 only fires on the bar where RSI exits the extreme zone, not on the bar where RSI is still deep in it. A long signal needs rsi[1] < 25 AND rsi[0] >= 25 — both legs have to be true on the same pair of bars. A short signal mirrors that: rsi[1] > 75 AND rsi[0] <= 75. The 25/75 defaults are deliberately tighter than the conventional 30/70, which means fewer signals but a higher expectation that momentum has actually rolled over. The two RSI values are read straight from the buffer at OnTick: CopyBuffer(hRSI, 0, 1, 2, rsi) returns a two-element array of bar 1 and bar 0 in that order, and the code indexes rsi[1] and rsi[0] directly without copying to a struct.
Everything runs on a single indicator handle, hRSI, allocated in OnInit as iRSI(_Symbol, PERIOD_CURRENT, InpRSIPeriod, PRICE_CLOSE). OnInit refuses to start if the handle returns INVALID_HANDLE, if InpMagicNumber is zero, if InpLotSize is non-positive, if InpCapFloor >= InpCapAmount when a cap is configured, if InpMaxTradesPerDay is non-positive, or if InpMaxLot is non-positive — each with a Print() and a return of INIT_PARAMETERS_INCORRECT. The OnTick body is roughly fifteen lines of actual signal logic; the rest of the function is the TryBuy_EX09024 / TrySell_EX09024 retry wrappers.
Position management is the simplest the EX09 family offers. Once a position opens, EX09024 sets a hard stop at InpStopLoss = 40 × _Point × 10 = 400 points (on XAUUSD that is 40 pips / $4.00 at 0.10 lot) and a hard take-profit at InpTakeProfit = 40 × _Point × 10 = 400 points. The R:R is 1:1 by design. There is no trailing stop, no break-even ratchet, no partial close, no time-based exit, no opposite-signal close, no basket TP. The exit is whichever side hits first: SL or TP. EX09024 is a strategy that depends on the win-rate of the entry, not on money management after entry.
Lot sizing is fixed at InpLotSize = 0.10. TryBuy_EX09024 and TrySell_EX09024 both clamp the requested lot to the symbol's min/max/step — MathFloor(lots/step)*step, then floored to minLot and capped to maxLot — and both pre-check margin via OrderCalcMargin against ACCOUNT_MARGIN_FREE before the first send. If margin is insufficient, the function returns false immediately with a print, and the outer 3-attempt loop never runs. The retry loop itself is 3 attempts on REQUOTE, TIMEOUT, PRICE_OFF, or PRICE_CHANGED at 200ms Sleep intervals; any other retcode is a hard fail and the loop breaks. The order is sent with CTrade::Buy / CTrade::Sell, which uses the broker's default filling mode via the CTrade class (FOK, IOC, or RETURN are broker-dependent).
EX09024 enforces single-position discipline through two distinct layers. The first is HasTrade(), a scan of PositionsTotal() that returns true if any open position has POSITION_MAGIC matching InpMagicNumber=22209024 and POSITION_SYMBOL matching _Symbol. If HasTrade() is true, OnTick returns immediately and no new entries can fire while a position is open. The second is a one-trade-per-bar guard via the module-level lastBar datetime. On every tick, OnTick reads iTime(_Symbol, PERIOD_CURRENT, 0) and compares to lastBar; if the current bar timestamp equals the last processed bar, the tick is skipped. The bar gate means at most one entry attempt per new bar even if multiple valid cross signals somehow form within the same candle. There is no time-stop on the open position — if the candle does not exit the extreme by the time the bar closes, the signal is gone, but the open trade still has to wait for SL or TP.
The IsSafeToTrade_EX09024 gate is the full EX09 hardening stack, applied as nine sequential checks. (1) Capital cap reached — if InpCapAmount > 0 and equity >= InpCapAmount, no trading. (2) Capital floor — if InpCapFloor > 0 and equity < InpCapFloor, no trading. (3) Initial equity guard — if equity < 95% of g_initialBalance, no trading. (4) Daily loss limit — realized P&L <= -3% of effective capital. (5) Weekly loss limit — realized P&L <= -6% (3% × 2) of effective capital. (6) Consecutive-loss cooldown — if g_consecLosses >= 3, block for 30 minutes from g_cooldownUntil. (7) Daily trade cap — g_tradesToday < 50. (8) Market-open check — closed Friday after 21:00 GMT, all of Saturday, Sunday before 22:00 GMT. (9) Session filter — only London 7–16 GMT and New York 12–21 GMT count, and Asia 0–7 GMT is explicitly avoided when InpAvoidAsia is true (the default). An optional news filter, off by default (InpNewsFilter=false), blocks ±15 minutes around the London and NY session open hours if enabled.
The on-trade bookkeeping uses OnTradeTransaction to scan DEAL_ADD events. For every new deal, the code selects the deal, checks DEAL_MAGIC matches this EA's magic and DEAL_ENTRY = DEAL_ENTRY_OUT, and accumulates DEAL_PROFIT + DEAL_SWAP + DEAL_COMMISSION into g_realizedToday, g_realizedWeek, and g_tradesToday. If the deal P&L is negative, g_consecLosses increments and g_cooldownUntil is set to TimeCurrent() + 30 × 60 seconds. UpdateDailyCounters_EX09024 runs at the top of every tick and resets g_tradesToday, g_consecLosses, g_realizedToday when the calendar day rolls over (compared via StringToTime on a year.month.day string). Weekly is not auto-reset in the same loop — it is reset implicitly when the strategy tester or terminal restarts the EA, and the limit applies to the running week only.
GMT handling is via DetectGMTOffset_EX09024, which walks H1 bars looking for a >2-hour gap (the weekend), then computes the offset as (hour of first post-gap bar) - 22, normalized to [-12, 12]. If InpServerGMTOffset is non-zero, that hardcoded value overrides the auto-detect. ServerToGMT_EX09024 subtracts g_gmtOffset × 3600 from the server time, and all session checks operate on that converted time. This is what makes the London 7–16 / NY 12–21 logic correct across brokers with different server timezones (IC Markets GMT+0, GMT+2 ECN, GMT+3 Pepperstone, etc.).
The OnTester formula is the same shape as the rest of the EX09 family: net profit × profit factor / (1 + relative equity DD %), with a 30-trade minimum and a guard that returns 0 if profit factor is non-positive or relative drawdown is non-positive. For strategy tester genetic optimization, the inputs that actually move the result are InpRSIPeriod, InpOverbought, InpOversold, InpStopLoss, InpTakeProfit, and InpLotSize. The remaining 18 inputs are session, risk-cap, and hardening controls that don't change between optimization runs unless you re-test across brokers.
Honest read on the 12-layer header: the comment block claims REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester — but in this file, only SIGNAL, ENTRY, NO-TRADE, CAPITAL CAP, RISK, SIZING, EXIT (via the static SL/TP at order send), and OnTester have actual code. There is no regime classifier (no ADX, no trend filter, no HTF check), no CONFIRM module (the cross IS the confirm), no MANAGE module (no BE, no trail, no partial), and no SCALING module (no pyramid, no martingale, no grid, no adds). This is a deliberate choice — EX09024 is the EX09 family member for traders who want the signal in plainest possible form, paired with the full safety/risk stack.
What to expect in backtest: XAUUSD on M5 with a 1:1 R:R depends on the bar-structure of gold. Gold's typical M5 range during London–NY overlap runs roughly 30–80 points; a 40-point stop is roughly half an average M5 range, so the SL will get hit more often than the TP on a single random distribution, and the strategy needs the RSI cross signal to be selective enough to push win-rate above 50% to clear breakeven after spread. On H1, the same 40-point SL/TP becomes much smaller relative to a typical 200–400 point range, which favors the strategy — the 1:1 R:R becomes a smaller ask against a wider distribution of outcomes. Brokers with sub-point XAUUSD spreads (ECN or RAW) materially help because the entry happens at a level where RSI is already bouncing, and a wide spread eats into the room. $100 micro-lot, 0.10 fixed, runs cleanly on the minimum deposit.
Strategy Deep Dive
EX09024 collapses the EX09 family signal stack to a single oscillator: RSI(14) with default 25/75 thresholds, evaluated as a cross condition on the previous and current bar. OnTick reads exactly two RSI values from the hRSI handle, runs the two threshold-cross checks, and either calls TryBuy_EX09024 or TrySell_EX09024 with a fixed InpLotSize=0.10 lot. Each entry helper clamps the lot to the symbol's min/max/step, pre-checks margin via OrderCalcMargin, and runs a 3-attempt retry loop on REQUOTE / TIMEOUT / PRICE_OFF / PRICE_CHANGED at 200ms intervals. The HasTrade() function scans PositionsTotal() and returns true on any open position with the matching magic, which means EX09024 can only hold one position at a time. A module-level lastBar datetime acts as a one-trade-per-bar guard: a new entry only fires on the first tick of each new bar, even if both legs of the cross would otherwise be valid. The full IsSafeToTrade_EX09024 nine-gate stack — capital cap, capital floor, 95% initial-equity guard, 3% daily loss, 6% weekly loss, 3-loss-30-minute cooldown, 50-trades-per-day, market-open, and London/NY session with optional Asia-avoid — runs before any signal check. OnTradeTransaction accumulates realized P&L from DEAL_ADD events into g_realizedToday, g_realizedWeek, and g_consecLosses, with the cooldown timer auto-armed after three consecutive losses. OnTester returns net profit × profit factor / (1 + relative equity DD %), with a 30-trade minimum.
Long entry fires when rsi[1] < InpOversold=25 AND rsi[0] >= 25 (RSI crossed back up from oversold on the most recent bar). Short entry mirrors with rsi[1] > 75 AND rsi[0] <= 75. The cross requirement means the bar that actually triggers must show RSI exiting the extreme zone, not still inside it. Both signals require HasTrade()==false (no open position on this magic) and a fresh bar timestamp, so at most one entry per new bar.
Position stays open until either the static stop or the static target is filled, whichever hits first. There is no trailing stop, no break-even ratchet, no partial close, no time-based exit, no opposite-signal close, and no basket TP. The 1:1 R:R is intentional — EX09024 expects the entry signal's win-rate to carry the strategy.
Static InpStopLoss=40 multiplied by _Point*10 = 400 points on XAUUSD (40 pips / $4.00 at 0.10 lot), set at the order send and never modified. There is no break-even shift, no trailing, and no in-trade widening.
Static InpTakeProfit=40 multiplied by _Point*10 = 400 points on XAUUSD (40 pips / $4.00 at 0.10 lot), set at the order send. EX09024 is a 1:1 R:R strategy by design — no scaling-out, no trailing target, no partial close.
Traders who want the plainest possible mean-reversion signal — single indicator, two threshold-cross rules — on XAUUSD M5 or H1. Minimum recommended balance: $100 at 0.10 fixed lot. Best paired with a low-spread ECN or RAW broker on gold (sub-point spreads materially help the 1:1 R:R). Run during the London (7–16 GMT) and New York (12–21 GMT) session overlap; the Asia 0–7 GMT block is on by default. Do not run through high-impact news windows if InpNewsFilter is enabled, or expect a higher consec-loss cooldown hit-rate during thin pre-session periods.
Strategy Logic
Pipsgrowth EX09024 MeanReversion — Strategy Logic Analysis (from .mq5 source)
Family: MeanReversion
Magic: 22209024
Version: 2.00
BRIEF:
RSI mean-reversion EA that buys when RSI crosses back up from oversold and sells when RSI crosses back down from overbought. Uses fixed lot size with static SL/TP in points and one-trade-per-bar guard. Simple and effective for range markets. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester
INDICATOR STACK:
- Standard
MT5indicators
KEY FUNCTIONS:
OnTradeTransaction()HasTrade()EffectiveCapital_EX09024()DetectGMTOffset_EX09024()ServerToGMT_EX09024()IsMarketOpen_EX09024()InActiveSession_EX09024()IsNewsTime_EX09024()IsSafeToTrade_EX09024()UpdateDailyCounters_EX09024()TryBuy_EX09024()TrySell_EX09024()
INTERNAL CONSTANTS (0 total):
INPUT PARAMETERS (1 total across 1 groups):
- [=== Identity ===]
InpTradeComment= "Psgrowth.com Expert_09024" // Trade comment
// Pipsgrowth EX09024 MeanReversion — Execution Flow (from source analysis)
// Family: MeanReversion
// RSI mean-reversion EA that buys when RSI crosses back up from oversold and sells when RSI crosses back down from overbought. Uses fixed lot size with static SL/TP in points and one-trade-per-bar guard. Simple and effective for range markets. 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 |
|---|---|---|
| InpTradeComment | "Psgrowth.com Expert_09024" | Trade comment |
#property copyright "Pipsgrowth.com"
#property link "https://pipsgrowth.com"
#property version "2.00"
#property strict
#property description "Pipsgrowth.com EX09024 RSIMeanReversion — RSI extremes mean-reversion with static SL/TP, full 12-layer stack."
#include <Trade\Trade.mqh>
input group "=== Identity ==="
input int InpMagicNumber = 22209024;
input string InpTradeComment = "Psgrowth.com Expert_09024"; // Trade comment
input group "=== Strategy ==="
input double InpLotSize = 0.10;
input int InpRSIPeriod = 14;
input int InpOverbought = 75;
input int InpOversold = 25;
input group "=== Risk Management ==="
input int InpStopLoss = 40;
input int InpTakeProfit = 40;
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 hRSI; 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);
hRSI=iRSI(_Symbol,PERIOD_CURRENT,InpRSIPeriod,PRICE_CLOSE);
if(hRSI==INVALID_HANDLE) return INIT_FAILED;
if(InpMagicNumber==0) { Print("EX09024: Magic must be non-zero"); return INIT_PARAMETERS_INCORRECT; }
if(InpLotSize<=0) { Print("EX09024: LotSize must be > 0"); return INIT_PARAMETERS_INCORRECT; }
if(InpCapAmount > 0.0 && InpCapFloor>=InpCapAmount) { Print("EX09024: CapFloor must be < CapAmount"); return INIT_PARAMETERS_INCORRECT; }
if(InpMaxTradesPerDay<=0) { Print("EX09024: MaxTradesPerDay must be > 0"); return INIT_PARAMETERS_INCORRECT; }
if(InpMaxLot<=0) { Print("EX09024: MaxLot must be > 0"); return INIT_PARAMETERS_INCORRECT; }
g_initialBalance=AccountInfoDouble(ACCOUNT_BALANCE);
g_gmtOffset=DetectGMTOffset_EX09024();
PrintFormat("EX09024 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 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.