P
PipsGrowth
Mean ReversionOpen Source – Free

Pipsgrowth EX13004 RSI_MA

MT5 Expert Advisor (Open Source) · XAUUSD · M5, H1

Pipsgrowth.com EX13004 marsi_ea — MA + RSI mean-reversion with dynamic lot sizing, full 12-layer stack.

Overview

Pipsgrowth EX13004 is a bias-aware mean-reversion EA that buys short-term oversold dips inside an uptrend and sells short-term overbought rallies inside a downtrend — never the other way around. The whole strategy lives in two condition checks inside OnTick():

  • Long signal: bid > ma[0] AND rsi[0] < rsiOversold (default 30)
  • Short signal: bid < ma[0] AND rsi[0] > rsiOverbought (default 70)

The MA is doing the trend-filtering work, the RSI is doing the timing work. A plain RSI(14) < 30 buy is rejected when price is below the SMA, because that pattern usually means the trend is breaking down rather than reverting. A plain RSI(14) > 70 sell is rejected when price is above the SMA, for the mirror reason. The result is a strategy that only fades extremes it disagrees with — long dips in uptrends, short rallies in downtrends — and never fights a trend by buying breakdowns or selling breakouts.

Indicator stack

The EA only opens two native indicator handles in OnInit():

  • maHandle = iMA(_Symbol, PERIOD_CURRENT, maPeriod=14, 0, MODE_SMA, PRICE_CLOSE)
  • rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, rsiPeriod=14, PRICE_CLOSE)

Both are released in OnDeinit(). Two buffers are copied at the start of every tick (CopyBuffer(handle, 0, 0, 2, buf)) to read the current and previous bar in a single call. That is the entire market data dependency — no ADX, no ATR, no Bollinger Bands, no HTF-EMA, no regime classifier. The strategy makes its decisions off a moving-average trend bias and an RSI timing trigger, period.

Position sizing — calculateLot()

OnTick() calls calculateLot() once per bar, before checking signals. The formula is the textbook risk-percent lot:

lot = (balance * riskPercent / 100) / (stopLoss * valuePerPoint)

where valuePerPoint = tickValue / tickSize. With the defaults — 10% risk percent, 100-pip stop on XAUUSD M5 — the EA sizes each new order so that a full stop-out costs 10% of account balance. The result is NormalizeDouble'd to two decimals and returned. If tickValue or tickSize come back as 0 (rare, but the EA handles it explicitly), calculateLot() falls back to 0.10 lots and prints a warning instead of dividing by zero.

The helpers TryBuy_EX13004() and TrySell_EX13004() then snap that lot to the broker's SYMBOL_VOLUME_STEP, clamp to [SYMBOL_VOLUME_MIN, SYMBOL_VOLUME_MAX], and run an OrderCalcMargin() check against ACCOUNT_MARGIN_FREE before the first send. If margin is short, the helper logs [EX13004] Buy: insufficient margin and returns false without sending.

Order execution and retry

The order loop in OnTick() is structured as a 3-attempt for loop with Sleep(500) between attempts and slippage widening by 5 points per retry (10 → 15 → 20). The price is re-quoted at the top of each attempt by SymbolInfoDouble(SYMBOL_ASK) (for buys) or SYMBOL_BID (for sells). If TryBuy_EX13004 / TrySell_EX13004 returns true, the function returns immediately. If all three attempts fail, OnTick() prints EX13004: Buy failed after 3 attempts err=%d and waits for the next tick.

Inside the helpers themselves, the retry policy is the standard Pipsgrowth signature: 3 attempts, 200ms Sleep, retry on TRADE_RETCODE_REQUOTE, TRADE_RETCODE_TIMEOUT, TRADE_RETCODE_PRICE_OFF, TRADE_RETCODE_PRICE_CHANGED; break the loop on any other retcode. trade.Buy() and trade.Sell() are called with the explicit SL and TP — there is no order-then-modify step, no virtual SL/TP layer.

Trade management — what does not happen is the point

This EA has no break-even lock, no trailing stop, no partial take-profit, no time-based exit, no opposite-signal exit. The SL and TP are set on the order ticket at entry and left there until either the broker hits them or the position is closed. With the defaults that's a 100-pip stop and a 300-pip target — a 3:1 reward-to-risk ratio. The reasoning is the opposite of EX13001 or EX13003: this strategy treats each entry as an independent mean-reversion bet with a fixed structural stop and a fixed structural target, not as a position to be actively managed through a multi-stage exit.

Single-position discipline

The first two lines of OnTick() enforce a strict one-position-at-a-time rule:

UpdateDailyCounters_EX13004(); if(PositionSelect(_Symbol)) return; if(!IsSafeToTrade_EX13004()) return;

If any position on the current symbol is already open, OnTick() returns before copying buffers, before computing lot size, before checking signals. No pyramiding, no hedging, no grid, no basket, no martingale. The EA either has a position on XAUUSD or it does not. That single line of code is the entire risk-on-risk-off mechanism at the strategy level.

The hardening stack — 8-condition IsSafeToTrade_EX13004()

The other pre-signal gate is IsSafeToTrade_EX13004(), which blocks entries when any of the following is true:

  1. Capital cap reached — equity >= InpCapAmount (default disabled at 0)
  2. Capital floor breached — equity < InpCapFloor (default 50)
  3. Equity drawdown — equity < 95% of the g_initialBalance recorded at OnInit
  4. Daily realized loss — g_realizedToday <= -effCap * 3%
  5. Weekly realized loss — g_realizedWeek <= -effCap * 6% (2× the daily limit)
  6. Cooldown active — g_consecLosses >= 3 AND TimeCurrent() < g_cooldownUntil
  7. Daily trade count — g_tradesToday >= 50
  8. Session / market — !IsMarketOpen_EX13004() OR !InActiveSession_EX13004() OR (InpNewsFilter AND IsNewsTime_EX13004())

Each of g_realizedToday, g_realizedWeek, g_tradesToday, g_consecLosses, and g_cooldownUntil is updated by OnTradeTransaction() on every TRADE_TRANSACTION_DEAL_ADD for deals whose magic matches 22213004 and whose entry is DEAL_ENTRY_OUT. Realized PnL is the sum of DEAL_PROFIT + DEAL_SWAP + DEAL_COMMISSION — i.e. swap and commission are baked in, not added on top. UpdateDailyCounters_EX13004() zeros the daily counter at the calendar day rollover (built from StringToTime of the formatted server date).

Session control and GMT detection

The session filter is the standard Pipsgrowth London-or-NY window translated from broker server time to true GMT. DetectGMTOffset_EX13004() scans up to 100 H1 bars for the first weekend gap > 2 hours, then back-computes the broker's GMT offset from the bar's hour field — when InpServerGMTOffset = 0, auto-detect runs at OnInit(). The result is stored in g_gmtOffset and used by ServerToGMT_EX13004() to translate TimeCurrent() into true GMT before the session check.

The default session window is London 7–16 GMT ∪ New York 12–21 GMT, with InpAvoidAsia = true blocking the 0–7 GMT Asian window. The InpNewsFilter is off by default but can be flipped on to skip 15 minutes around the London and NY open hours. IsMarketOpen_EX13004() adds a hard weekend guard: closed all Saturday, closed Sunday before 22 GMT, closed Friday from 21 GMT.

OnTester fitness function

The backtest scoring formula at the bottom of the file is the same (net * pf) / (1 + dd) shape used across the family, with a hard floor of 30 trades — anything below 30 trades returns 0.0, so the EA is not optimisable on a handful of lucky entries. Without enough trades the score is undefined for the strategy's purposes.

What you actually get when you run it

XAUUSD on M5 is the working configuration. The EA holds at most one position at a time and either rides to the 300-pip take-profit, gets stopped at the 100-pip stop, or sits flat waiting for the next valid signal. Most days produce 0–2 trades. The 95% equity floor means a single bad run can take the EA out of the market permanently until you reset it. The 3% daily / 6% weekly loss caps and the 30-minute cooldown after 3 consecutive losses are the active brakes — under a steady drawdown the EA throttles itself rather than grinding.

Because the strategy depends on price returning to (or toward) the 14-period SMA after an extreme RSI reading, it works best when the intraday trend is mild but the short-term oscillations are large. In a flat, ranging session with both London and NY active, you will see the most frequent clean hits. In a strong directional session, the bias filter will reject most signals and the EA will sit on its hands — which is the intended behaviour, not a bug.

Strategy Deep Dive

Two indicator handles — iMA(14, MODE_SMA, PRICE_CLOSE) for trend bias and iRSI(14, PRICE_CLOSE) for timing — feed two CopyBuffer(handle, 0, 0, 2, ...) reads at the top of OnTick(). The strategy then checks a single line of conditions: long if bid > ma[0] && rsi[0] < 30, short if bid < ma[0] && rsi[0] > 70. Lot size is computed by calculateLot() as balance * 10% / (stopLoss * tickValue/tickSize) then snapped to the broker volume step inside TryBuy_EX13004() / TrySell_EX13004(), which also runs an OrderCalcMargin margin check. The order loop retries 3 times with 500ms sleep and slippage widening 10 → 15 → 20 points. No break-even, no trailing, no partial close — the 100/300 pip SL/TP placed on the order ticket is the only exit. PositionSelect(_Symbol) at the top of OnTick() enforces strict one-position-at-a-time, and the 8-condition IsSafeToTrade_EX13004() gate blocks entries on cap breach, floor breach, 95% equity drawdown, 3% daily loss, 6% weekly loss, 3-consec-loss cooldown, 50-trade-per-day ceiling, or non-London/NY session. OnTradeTransaction() keeps the g_realizedToday, g_realizedWeek, g_tradesToday, g_consecLosses, and g_cooldownUntil ledger up to date by reading DEAL_PROFIT + DEAL_SWAP + DEAL_COMMISSION on every magic-matching DEAL_ENTRY_OUT deal. DetectGMTOffset_EX13004() scans 100 H1 bars for the first weekend gap to back-compute broker GMT at OnInit(). OnTester() returns (net * pf) / (1 + dd) for runs of 30+ trades, 0 otherwise.

Entry Signal

A long entry fires when bid > ma[0] (price above the 14-period SMA) AND rsi[0] < rsiOversold (default 30). A short entry fires when bid < ma[0] AND rsi[0] > rsiOverbought (default 70). The MA bias filter means a plain oversold reading is rejected when price is below the SMA, so the EA only fades dips it agrees with — long dips in uptrends, short rallies in downtrends.

Exit Signal

Exit is fully delegated to the broker-side SL and TP set on the order ticket at entry. There is no break-even lock, no trailing stop, no partial take-profit, no time-based exit, and no opposite-signal exit. The position is closed by whichever of the two levels is hit first, or by trade.PositionClose if a manual intervention closes it from outside.

Stop Loss

A fixed 100-pip stop-loss (stopLoss = 100 default) is placed on the order ticket at entry. The distance is calculated by PipSize(), which returns _Point * 10 for 5-digit and 3-digit symbols (so XAUUSD with 2 decimals effectively sees 100 points = 100 raw price units on the chart) and _Point for the rest. No break-even, no trailing, no ATR-based adjustment.

Take Profit

A fixed 300-pip take-profit (takeProfit = 300 default) is set on the order ticket at entry, giving a 3:1 reward-to-risk ratio against the 100-pip stop. The TP is placed at entry and never moved — there is no ratchet, no partial close, no profit-lock.

Best For

Best on XAUUSD M5 (the family works M5H1) during the London and New York session overlap with the broker server clock confirmed against true GMT — the EA auto-detects offset at OnInit but if your broker is on ECN/RAW, set InpServerGMTOffset manually to skip the scan. Recommended balance $1,000–$5,000 (the documented minimum is $100, but the 10% risk-percent and 5.0 hard lot cap are designed for accounts where 0.100.50 lots is the natural size). The strategy is meant to sit on its hands in strong trends, so the most productive environments are range-bound sessions where the 14-SMA stays roughly flat and RSI oscillates between 30 and 70.

Strategy Logic

Pipsgrowth EX13004 RSI_MA — Strategy Logic Analysis (from .mq5 source)

Family: RSI_MA Magic: 22213004 Version: 2.00

BRIEF: MA + RSI mean-reversion EA. Buys when price is above the SMA and RSI is oversold; sells when price is below the SMA and RSI is overbought. Dynamic lot sizing from risk percent with fixed SL/TP. Full 12-layer stack: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester

INDICATOR STACK:

  • Standard MT5 indicators

KEY FUNCTIONS:

  • OnTradeTransaction()
  • calculateLot()
  • PipSize()
  • EffectiveCapital_EX13004()
  • DetectGMTOffset_EX13004()
  • ServerToGMT_EX13004()
  • IsMarketOpen_EX13004()
  • InActiveSession_EX13004()
  • IsNewsTime_EX13004()
  • IsSafeToTrade_EX13004()
  • UpdateDailyCounters_EX13004()
  • TryBuy_EX13004()
  • ...and 1 more

INTERNAL CONSTANTS (0 total):

INPUT PARAMETERS (18 total across 3 groups):

  • [=== Identity ===] InpTradeComment = "Psgrowth.com Expert_13004" // Trade Comment
  • [=== Identity ===] MagicNumber = 22213004 // Magic Number
  • [=== Hardening: Risk Management ===] InpDailyLossLimitPct = 3.0 // Daily loss limit (% of effective capital)
  • [=== Hardening: Risk Management ===] InpMaxLot = 5.0 // Hard lot cap per trade
  • [=== Hardening: GMT Sessions ===] InpServerGMTOffset = 0 // Server GMT offset hours (0=auto-detect)
  • [=== Hardening: GMT Sessions ===] InpLondonStartHour = 7 // London session start (GMT)
  • [=== Hardening: GMT Sessions ===] InpLondonEndHour = 16 // London session end (GMT)
  • [=== Hardening: GMT Sessions ===] InpNYStartHour = 12 // New York session start (GMT)
  • [=== Hardening: GMT Sessions ===] InpNYEndHour = 21 // New York session end (GMT)
  • [=== Hardening: GMT Sessions ===] InpAvoidAsia = true // Avoid Asian session
  • [=== Hardening: GMT Sessions ===] InpAsiaStartHour = 0 // Asian session start (GMT)
  • [=== Hardening: GMT Sessions ===] InpAsiaEndHour = 7 // Asian session end (GMT)
  • [=== Hardening: GMT Sessions ===] InpNewsFilter = false // Avoid trading near news session opens
  • [=== Hardening: GMT Sessions ===] InpNewsFilterMinutes = 15 // Minutes to avoid around news
  • [=== Hardening: GMT Sessions ===] InpMaxTradesPerDay = 50 // Maximum trades per day
  • [=== Hardening: GMT Sessions ===] InpMinEquityPercent = 95.0 // Stop trading if equity < this % of initial balance
  • [=== Hardening: GMT Sessions ===] InpCooldownMinutes = 30 // Cooldown minutes after consec losses
  • [=== Hardening: GMT Sessions ===] InpMaxConsecLosses = 3 // Max consecutive losses before cooldown
Pseudocode
// Pipsgrowth EX13004 RSI_MA — Execution Flow (from source analysis)
// Family: RSI_MA
// MA + RSI mean-reversion EA. Buys when price is above the SMA and RSI is oversold; sells when price is below the SMA and RSI is overbought. Dynamic lot sizing from risk percent with fixed SL/TP. Full 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

Optimized Brokers:
ExnessIC Markets
Optimized Symbols:
XAUUSD
Optimized Timeframes:
M5H1

How to Install This EA on MT5

  1. 1Download the .mq5 file using the button above
  2. 2Open MetaTrader 5 on your computer
  3. 3Click File → Open Data Folder in the top menu
  4. 4Navigate to MQL5 → Experts and paste the .mq5 file there
  5. 5In MT5, right-click Expert Advisors in the Navigator panel → Refresh
  6. 6Drag the EA onto an H1 or H4 chart
  7. 7Set Bollinger Band period, deviation, RSI levels, and lot size
  8. 8Enable Allow Algo Trading and click OK

EA Parameters

ParameterDefaultDescription
InpTradeComment"Psgrowth.com Expert_13004"Trade Comment
MagicNumber22213004Magic Number
InpDailyLossLimitPct3.0Daily loss limit (% of effective capital)
InpMaxLot5.0Hard lot cap per trade
InpServerGMTOffset0Server GMT offset hours (0=auto-detect)
InpLondonStartHour7London session start (GMT)
InpLondonEndHour16London session end (GMT)
InpNYStartHour12New York session start (GMT)
InpNYEndHour21New York session end (GMT)
InpAvoidAsiatrueAvoid Asian session
InpAsiaStartHour0Asian session start (GMT)
InpAsiaEndHour7Asian session end (GMT)
InpNewsFilterfalseAvoid trading near news session opens
InpNewsFilterMinutes15Minutes to avoid around news
InpMaxTradesPerDay50Maximum trades per day
InpMinEquityPercent95.0Stop trading if equity < this % of initial balance
InpCooldownMinutes30Cooldown minutes after consec losses
InpMaxConsecLosses3Max consecutive losses before cooldown
Source Code (.mq5)Open Source
Pipsgrowth_com_EX13004.mq5
#property copyright "Pipsgrowth.com"
#property link      "https://pipsgrowth.com"
#property version   "2.00"
#property strict
#property description "Pipsgrowth.com EX13004 marsi_ea — MA + RSI mean-reversion with dynamic lot sizing, full 12-layer stack."
#include <Trade\Trade.mqh>
#include <Trade/Trade.mqh>
//input parameters
input group "=== Identity ==="
input string InpTradeComment = "Psgrowth.com Expert_13004"; // Trade Comment
input ulong  MagicNumber     = 22213004;                    // Magic Number

input group "=== Indicator Parameters ==="
input int maPeriod =14;
input int rsiPeriod=14;
input double rsiOverbought=70.0;
input double rsiOversold=30.0;

input group "=== Risk Management ==="
input double riskPercent=10.0;
input double stopLoss=100;
input double takeProfit=300;
input double slippage=10;

input group "=== Hardening: Risk Management ==="
input double InpDailyLossLimitPct = 3.0;   // Daily loss limit (% of effective capital)
input double InpMaxLot           = 5.0;   // Hard lot cap per trade

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;      // Server GMT offset hours (0=auto-detect)
input int    InpLondonStartHour    = 7;      // London session start (GMT)
input int    InpLondonEndHour      = 16;     // London session end (GMT)
input int    InpNYStartHour        = 12;     // New York session start (GMT)
input int    InpNYEndHour          = 21;     // New York session end (GMT)
input bool   InpAvoidAsia          = true;   // Avoid Asian session
input int    InpAsiaStartHour      = 0;      // Asian session start (GMT)
input int    InpAsiaEndHour        = 7;      // Asian session end (GMT)
input bool   InpNewsFilter         = false;  // Avoid trading near news session opens
input int    InpNewsFilterMinutes  = 15;     // Minutes to avoid around news
input int    InpMaxTradesPerDay    = 50;     // Maximum trades per day
input double InpMinEquityPercent   = 95.0;   // Stop trading if equity < this % of initial balance
input int    InpCooldownMinutes    = 30;     // Cooldown minutes after consec losses
input int    InpMaxConsecLosses    = 3;      // Max consecutive losses before cooldown

//Indicator Handles
int maHandle;
int rsiHandle;
//Trading Object
CTrade trade;

//--- Hardening globals
double   g_initialBalance = 0.0;
int      g_gmtOffset = 0;
int      g_consecLosses = 0;
datetime g_cooldownUntil = 0;

Full source code available on download

Educational purposes only. Do NOT use with real money. Test on demo accounts only.

Tags:ex13004rsi_mapipsgrowthfreemt5xauusd

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

Community

Sign in to contributeSign In

Educational purposes only. Do NOT use with real money. Test on demo accounts only.

File NamePipsgrowth_com_EX13004.mq5
File Size16.7 KB
Versionv2.00
PlatformMetaTrader 5
File Type.mq5 Source
StrategyMean Reversion
Risk LevelMedium Risk
Timeframes
M5H1
Currency Pairs
XAUUSD
Min. Deposit$100