P
PipsGrowth
Mean ReversionOpen Source – Free

Pipsgrowth EX09007 MeanReversion

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

Pipsgrowth.com EX09007 HangingManHammer MFI — candlestick reversal + MFI confirm, full 12-layer stack.

Overview

EX09007 looks for a very specific candle shape: a body in the upper third of the bar with a lower wick at least twice as long as the body, and a lower wick longer than the upper wick. That geometric definition is what most retail traders call a Hammer (bullish reversal) or a Hanging Man (bearish reversal) — but here it is computed in the SignalPattern() function on the just-closed M5 bar (shift=1), with a precise threshold: the body must sit in the upper third of the bar's range (bodyBot > high - range/3.0) and lowerWick >= 2.0 * bodySize. That last clause is what disqualifies a lot of "looks like a hammer" candles — the lower wick has to be at least double the body, not merely noticeable.

Pattern alone is not enough. The EA also reads a 5-period SMA on the same timeframe for trend context: a Hammer must close below the SMA(5) — meaning the bar printed in an existing micro-downtrend — and a Hanging Man must close above the SMA(5). That SMA gate ensures the EA is fading short-term momentum rather than buying strength. After the trend gate comes the third filter: the Money Flow Index with period 37. A Hammer must print with MFI below 40 (sell-pressure exhaustion), and a Hanging Man must print with MFI above 60 (buy-pressure exhaustion). The two inputs InpMFIBuyMax=40.0 and InpMFISellMin=60.0 are the literal thresholds; the confidence output of SignalPattern() is computed as 50 + |offset|*1.2 capped at 100, but it is logged only and not gating — only the pattern match plus the threshold comparisons actually matter for the entry decision.

A high-confidence pattern is not by itself enough to fire. The EA runs a full 7-state regime classifier via ClassifyRegime() using ADX(14), a 100-bar ATR(14) percentile, and a Bollinger-Band width z-score (period 20, deviation 2.0). The seven states are StrongTrend, WeakTrend, Range, Breakout, Compress, Expand, and Choppy. RegimeAllowsEntry() permits entries only in three of them: Range, Compress, and WeakTrend. StrongTrend, Breakout, Expand, and Choppy are blocked. The intent is straightforward — mean reversion only works when the market is not trending hard and not in a volatility expansion. A Hammer forming inside a StrongTrend regime is a continuation signal, not a reversal, and is ignored.

Before the order is even sized, three more confirmations must pass in ComputeConfirm(). The HTF EMA filter pulls a 50-period EMA on H1 (HTF_TIMEFRAME = PERIOD_H1): a Hammer is only confirmed if the M5 close is below the H1 EMA — a pullback context — and a Hanging Man only if the close is above it. That single cross-timeframe gate is what stops the EA from fading a clean H1 trend on a 5-minute "fake" Hammer. The spread gate allows a 35-point absolute cap (MAX_SPREAD_POINTS=35) or 3× the rolling 20-bar average spread, whichever is tighter, when InpMaxSpreadOverAvg=3. The R:R gate enforces tpDist / slDist >= 1.2 (the constant MIN_RR_RATIO) — a thin trade is never taken.

Risk math is straightforward. CalcLotByRisk() reads the SL distance in price, divides effective capital by tick_value / tick_size to get the per-lot risk, and sizes the order so that 0.5% * effective_capital is at risk per trade (InpRiskPercent=0.5). The lot is then clamped to the symbol's volume step and to InpMaxLots=5.0. The capital base is the minimum of equity and InpCapitalCapAmount (when the cap is non-zero), which is the EA's way of letting you cap exposure at a fixed dollar figure on a larger account — setting the cap to 0 disables it.

Five exit paths run on every tick through ManageOpenPosition(). First, a one-shot break-even at 1.0R (BE_TRIGGER_R=1.0): once profit equals the initial risk, the stop is moved to entry + 2 points. Second, a partial close at 1.0R (PARTIAL_TP_R=1.0): 50% of the position is closed (PARTIAL_FRACTION=0.5), with the heuristic that the lot must be at least twice the symbol's volume minimum — otherwise the partial is skipped to avoid a too-small residual. Third, an ATR(14) trailing stop at 2.5×ATR (TRAIL_ATR_MULT=2.5) with a 10-point step (TRAIL_STEP_POINTS=10), forward-only, that only ratchets in the profitable direction. Fourth, an opposite-pattern exit: if a Hammer prints against an existing long, the position is closed immediately, and vice versa. Fifth, a regime-change exit: if the classifier flips into StrongTrend, Breakout, or Expand — the states that block entries — the position is force-closed, because the mean-reversion thesis is no longer valid. A 60-bar time stop (MAX_BARS_IN_TRADE=60) layers on top of that stack, which is roughly 5 hours on the M5 default.

The no-trade system around all of this is one of the more comprehensive in the corpus. The NoTradeReason() function returns a string tag for the first failure and short-circuits: kill switch on, broker not allowing trades, terminal disconnected, equity below the 50-dollar floor (InpCapitalCapFloor=50.0), outside the 07:00-20:00 server-time session (SESSION_START_HOUR=7, SESSION_END_HOUR=20), weekend (Saturday or Sunday), current spread above 35 points, a ±30-minute window around each hour boundary treated as a generic news guard (NEWS_WINDOW_MIN=30), regime blocked, 5 trades already taken today (MAX_DAILY_TRADES=5), the 5-bar cooldown after a loss (COOLDOWN_BARS_AFTER_LOSS=5), or 1 position already open (InpMaxConcurrent=1). The session window is in broker server time, not auto-detected GMT — a user on a GMT+2 broker sees the live window at 05:00-18:00 UTC. The news guard is a primitive time-based proxy, not an MQL5 economic-calendar feed.

Risk management outside the trade is enforced after entries: a daily 3% loss of effective capital (InpDailyLossLimitPct=3.0) and a weekly 6% loss (InpWeeklyLossLimitPct=6.0) trigger a force-close of any open position via the RealizedPnLToday() and RealizedPnLThisWeek() history walkers. These walk the deal history from start-of-day and start-of-Monday to now, filtering by InpMagic and symbol, summing profit + swap + commission. The OnTester custom criterion multiplies net profit by profit factor and divides by 1 + drawdown_percent, with a 30-trade minimum to prevent over-fit curves from scoring well. Trade-execution transient errors are absorbed by a 1-retry loop with a 150ms sleep on REQUOTE, PRICE_OFF, PRICE_CHANGED, CONNECTION, and TIMEOUT retcodes; close operations are wrapped in a 3-retry 200ms loop that also covers PRICE_OFF and PRICE_CHANGED, but TryModify_EX09007 only retries on REQUOTE and TIMEOUT — a small gap where a price-change reject on a stop modification will not retry.

Two defaults deserve a callout. InpDryRun=true ships enabled — every order attempt is logged with the [DRYRUN] prefix and no live order is sent. That is a deliberate safe default for forward testing but it means the EA does nothing in live until the user flips the input. InpKillSwitch=false is the other binary that needs to be off for trading; turning it on hard-blocks all new entries regardless of conditions. The portfolio-heat cap of 6% (PORTFOLIO_HEAT_CAP=0.06) is estimated from CountOurPositions() * InpRiskPercent / 100.0, a crude but effective size-based proxy.

For backtests, expect this EA to fire on Gold in the 07:00-20:00 server window most often on bars that print the geometric pattern with MFI exhaustion — typically 1 to 3 times per London-NY overlap on a 5-minute chart, more on volatile days. The 60-bar time stop is a hard ceiling: a trade that hasn't paid by 5 hours closes regardless of MFI. The two combination gates that most often kill an otherwise valid pattern are the H1 EMA pullback requirement (which filters out "buy the breakout" patterns) and the regime classifier (which filters out the strongest trend days, where the Hammers print as continuation candles). A user wanting more trades should look at lowering MIN_RR_RATIO or widening the regime allowlist in RegimeAllowsEntry() — both reduce selectivity in measurable ways. The pyramid constants PYRAMID_MAX_LEVELS=5 and PYRAMID_ATR_SPACING=1.5 are defined but unused at runtime, because InpMaxConcurrent=1 forces a single open position; they are leftover scaffolding from a strategy variant.

Strategy Deep Dive

SignalPattern() runs on the closed M5 bar and returns +1 for a Hammer or -1 for a Hanging Man based on the geometric rule bodyBot > high - range/3 and lowerWick >= 2*bodySize && lowerWick > upperWick, then gates the call with the SMA(5) trend direction and the MFI(37) exhaustion threshold. The full OnTick() flow is: refresh symbol data, classify regime via ADX(14) + Bollinger-width z-score + ATR(14) percentile, walk all the no-trade checks (kill switch, capital floor, session, weekend, spread, news window, regime, daily-trade limit, cooldown, concurrent cap), pull the signal, compute the H1 EMA(50) pullback confirmation, size the lot via CalcLotByRisk() against 0.5% of effective capital, and submit through the 1-retry transient-error wrapper in SendOrder(). ManageOpenPosition() runs on every tick on top of the same flow, walking the BE → partial → ATR trail → opposite-signal → regime-change → time-stop stack. The full input surface is 18 user-tunable values across 7 input groups; the only binary that ships in a non-default state is InpDryRun=true, which logs orders as [DRYRUN] and sends nothing live until the user flips it.

Entry Signal

The EA enters long when a closed M5 bar matches the geometric Hammer pattern — body in the upper third of the bar's range with lower wick at least 2× the body size and a longer lower than upper wick — and the bar's close sits below the SMA(5), with MFI(37) below 40. The mirror short entry fires on a Hanging Man (same geometry) closing above the SMA(5) with MFI(37) above 60. The 7-state regime classifier must allow the entry (Range, Compress, or WeakTrend only), the H1 EMA(50) pullback gate must agree, and the live spread must clear the 35-point cap or 3× the rolling average.

Exit Signal

A 5-path exit stack runs every tick: one-shot break-even at 1.0R moves the stop to entry + 2 points, a 50% partial close at 1.0R is attempted (only if the residual would still be at least 2× the symbol's volume minimum), and an ATR(14)×2.5 trailing stop with a 10-point forward step ratchets behind price. The position is force-closed if the regime classifier flips into StrongTrend, Breakout, or Expand, if a candle of the opposite pattern prints, or after 60 M5 bars (roughly 5 hours). A 3% daily or 6% weekly loss of effective capital also force-closes via the deal-history walkers.

Stop Loss

Stop loss is ATR(14) × 1.8 on the closed bar at signal time, snapped outward to honor the symbol's stops level. With MIN_RR_RATIO=1.2 enforced on top via the confirm gate, the minimum distance is the ATR multiple — the EA will never size a tighter stop than that.

Take Profit

Take profit is ATR(14) × 3.0 from entry, giving a 1.67:1 R:R at signal time. The TP price is also snapped outward to respect the broker's stops level minimum, and a 50% partial close at 1.0R is attempted before the full TP can be hit.

Best For

Best on XAUUSD M5 during the broker-server 07:00-20:00 window, which on a GMT+2 broker is the 05:00-18:00 UTC London-NY overlap where MFI exhaustion patterns print most often. Minimum recommended balance is $100 with the default 0.5% risk, and InpMaxLots=5.0 caps the per-trade lot to keep the EA compatible with micro-lot accounts — raise InpMaxLots and lower InpRiskPercent proportionally for larger books. The EA needs a low-spread ECN or RAW account because the 35-point spread cap and 3× rolling-average filter will block entries during wide-spread events, and the user must remember to flip InpDryRun to false before live trading.

Strategy Logic

Pipsgrowth EX09007 MeanReversion — Strategy Logic Analysis (from .mq5 source)

Family: MeanReversion Magic: 22209007 Version: 2.00

BRIEF: Hanging Man (bearish) / Hammer (bullish) candlestick on last CLOSED bar + MFI confirmation (MFI<40 Buy / MFI>60 Sell). 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester

INDICATOR STACK:

  • Standard MT5 indicators

KEY FUNCTIONS:

  • Norm()
  • ClampVolume()
  • PointsToPrice()
  • StopsLevelPrice()
  • CopyBuf()
  • MFIVal()
  • MAVal()
  • ATRVal()
  • ADXVal()
  • HTFEMAVal()
  • GetBBWidthZ()
  • GetATRPctile()
  • ...and 28 more

INTERNAL CONSTANTS (36 total):

  • ATR_REG_PERIOD = 14 // ATR period for regime
  • ATR_PCTILE_LOOKBACK = 100 // ATR percentile window
  • BB_REG_PERIOD = 20 // Bollinger Band period (regime)
  • BB_REG_DEV = 2.0 // Bollinger Band deviation
  • ADX_REG_PERIOD = 14 // ADX period (regime)
  • HTF_TREND_PERIOD = 50 // HTF EMA period
  • HTF_TIMEFRAME = PERIOD_H1 // HTF timeframe for trend agreement
  • AVG_BODY_PERIOD = 12 // candle avg body period (pattern)
  • MA_TREND_PERIOD = 5 // short SMA for pattern trend context
  • MFI_PERIOD_DEFAULT = 37 // MFI oscillator period
  • MFI_VOL_TYPE = VOLUME_TICK // MFI applied volume type
  • REG_STRONG_ADX = 28 // ADX >= this => StrongTrend
  • REG_RANGE_ADX = 20 // ADX <= this => range-ish
  • REG_COMP_BBZ = 0.8 // BB-width zscore <= => Compress
  • REG_EXP_BBZ = 1.5 // BB-width zscore >= => Expand
  • ...and 21 more

INPUT PARAMETERS (21 total across 7 groups):

  • [=== Identity ===] InpMagic = 22209007 // Magic number (2220000 + 554)
  • [=== Identity ===] InpTradeComment = "Psgrowth.com Expert_09007" // Trade comment
  • [=== Risk & Sizing ===] InpRiskPercent = 0.5 // Risk per trade, % of effective capital
  • [=== Risk & Sizing ===] InpDailyLossLimitPct = 3.0 // Daily loss limit, % of effective capital
  • [=== Risk & Sizing ===] InpWeeklyLossLimitPct = 6.0 // Weekly loss limit, % of effective capital
  • [=== Risk & Sizing ===] InpMaxLots = 5.0 // Hard cap on lot size per trade
  • [=== Risk & Sizing ===] InpMaxConcurrent = 1 // Max concurrent positions (this symbol/magic)
  • [=== Risk & Sizing ===] InpSlippagePoints = 20 // Max slippage in points
  • [=== Capital Allocation Cap ===] InpCapitalCapAmount = 0.0 // Cap amount in REAL equity $
  • [=== Capital Allocation Cap ===] InpCapitalCapFloor = 50.0 // Floor below which entries are blocked
  • [=== Signal (Pattern + MFI) ===] InpMFIPeriod = 37 // MFI oscillator period
  • [=== Signal (Pattern + MFI) ===] InpMFIBuyMax = 40.0 // MFI upper bound to confirm Hammer (Buy)
  • [=== Signal (Pattern + MFI) ===] InpMFISellMin = 60.0 // MFI lower bound to confirm HangMan (Sell)
  • [=== Regime / Confirm ===] InpHTFBarAgree = 1 // 1=require HTF-EMA side agreement, 0=skip
  • [=== Regime / Confirm ===] InpMaxSpreadOverAvg = 3 // Max spread multiple over rolling avg (x), 0=off
  • [=== Exit / Manage ===] InpUseBreakEven = true // Enable break-even at BE_TRIGGER_R
  • [=== Exit / Manage ===] InpUsePartialTP = true // Enable partial TP at PARTIAL_TP_R
  • [=== Exit / Manage ===] InpUseATRTrail = true // Enable ATR trailing stop
  • [=== Exit / Manage ===] InpExitOnOppSignal = true // Exit on opposite candlestick pattern
  • [=== Dry-Run / Kill Switch ===] InpDryRun = true // Dry-run mode (no live orders)
  • [=== Dry-Run / Kill Switch ===] InpKillSwitch = false // Emergency kill switch (block all trading)
Pseudocode
// Pipsgrowth EX09007 MeanReversion — Execution Flow (from source analysis)
// Family: MeanReversion
// Hanging Man (bearish) / Hammer (bullish) candlestick on last CLOSED bar + MFI confirmation (MFI<40 Buy / MFI>60 Sell). 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

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
InpMagic22209007Magic number (2220000 + 554)
InpTradeComment"Psgrowth.com Expert_09007"Trade comment
InpRiskPercent0.5Risk per trade, % of effective capital
InpDailyLossLimitPct3.0Daily loss limit, % of effective capital
InpWeeklyLossLimitPct6.0Weekly loss limit, % of effective capital
InpMaxLots5.0Hard cap on lot size per trade
InpMaxConcurrent1Max concurrent positions (this symbol/magic)
InpSlippagePoints20Max slippage in points
InpCapitalCapAmount0.0Cap amount in REAL equity $
InpCapitalCapFloor50.0Floor below which entries are blocked
InpMFIPeriod37MFI oscillator period
InpMFIBuyMax40.0MFI upper bound to confirm Hammer (Buy)
InpMFISellMin60.0MFI lower bound to confirm HangMan (Sell)
InpHTFBarAgree11=require HTF-EMA side agreement, 0=skip
InpMaxSpreadOverAvg3Max spread multiple over rolling avg (x), 0=off
InpUseBreakEventrueEnable break-even at BE_TRIGGER_R
InpUsePartialTPtrueEnable partial TP at PARTIAL_TP_R
InpUseATRTrailtrueEnable ATR trailing stop
InpExitOnOppSignaltrueExit on opposite candlestick pattern
InpDryRuntrueDry-run mode (no live orders)
InpKillSwitchfalseEmergency kill switch (block all trading)
Source Code (.mq5)Open Source
Pipsgrowth_com_EX09007.mq5
#property copyright "Pipsgrowth.com"
#property link      "https://pipsgrowth.com"
#property version   "2.00"
#property strict
#property description "Pipsgrowth.com EX09007 HangingManHammer MFI — candlestick reversal + MFI confirm, 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 (NOT inputs) =================
#define ATR_REG_PERIOD        14              // ATR period for regime
#define ATR_PCTILE_LOOKBACK   100             // ATR percentile window
#define BB_REG_PERIOD         20              // Bollinger Band period (regime)
#define BB_REG_DEV            2.0             // Bollinger Band deviation
#define ADX_REG_PERIOD        14              // ADX period (regime)
#define HTF_TREND_PERIOD      50              // HTF EMA period
#define HTF_TIMEFRAME         PERIOD_H1       // HTF timeframe for trend agreement
#define AVG_BODY_PERIOD       12              // candle avg body period (pattern)
#define MA_TREND_PERIOD       5               // short SMA for pattern trend context
#define MFI_PERIOD_DEFAULT    37              // MFI oscillator period
#define MFI_VOL_TYPE          VOLUME_TICK      // MFI applied volume type
#define REG_STRONG_ADX        28               // ADX >= this => StrongTrend
#define REG_RANGE_ADX         20               // ADX <= this => range-ish
#define REG_COMP_BBZ          0.8              // BB-width zscore <= => Compress
#define REG_EXP_BBZ           1.5              // BB-width zscore >= => Expand
#define ATR_PCTILE_STRONG     80               // ATR percentile >= => high vol
#define ATR_PCTILE_LOW        20               // ATR percentile <= => low vol
#define SL_ATR_MULT           1.8              // SL = ATR(closed bar) * mult
#define TP_ATR_MULT           3.0              // TP = ATR(closed bar) * mult
#define TRAIL_ATR_MULT        2.5              // ATR trailing distance
#define TRAIL_STEP_POINTS     10               // trail step (points)
#define BE_TRIGGER_R          1.0              // break-even trigger at 1.0R
#define PARTIAL_TP_R          1.0              // partial TP at 1.0R
#define PARTIAL_FRACTION      0.5              // partial close 50%
#define MAX_BARS_IN_TRADE     60               // time-based exit (bars)
#define MAX_SPREAD_POINTS     35               // spread cap (points)
#define MAX_DAILY_TRADES      5                // max entries per day
#define COOLDOWN_BARS_AFTER_LOSS 5            // cooldown after loss
#define MIN_RR_RATIO          1.2              // min reward:risk
#define SESSION_START_HOUR    7                // server-time session start
#define SESSION_END_HOUR      20               // server-time session end
#define NEWS_WINDOW_MIN       30               // manual news window (min around HH:00)
#define PYRAMID_MAX_LEVELS    5                // pyramid hard cap
#define PYRAMID_ATR_SPACING   1.5              // pyramid ATR spacing
#define PORTFOLIO_HEAT_CAP    0.06             // max portfolio heat 6%
#define MAX_TRADE_RETRIES     1                // trade-send retry on transient
#define INP_VERSION_TAG       "v2.00 MeanRev HangHam/MFI"  // version tag (log only)

//================== INPUTS (18 total) ==============================
input group "=== Identity ==="
input long   InpMagic           = 22209007;                       // Magic number (2220000 + 554)
input string InpTradeComment    = "Psgrowth.com Expert_09007";          // Trade comment

input group "=== Risk & Sizing ==="
input double InpRiskPercent     = 0.5;      // Risk per trade, % of effective capital
input double InpDailyLossLimitPct = 3.0;    // Daily loss limit, % of effective capital

Full source code available on download

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

Tags:ex09007meanreversionpipsgrowthfreemt5xauusd

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_EX09007.mq5
File Size38.3 KB
Versionv2.00
PlatformMetaTrader 5
File Type.mq5 Source
StrategyMean Reversion
Risk LevelMedium Risk
Timeframes
M5H1
Currency Pairs
XAUUSD
Min. Deposit$100