P
PipsGrowth
OtherOpen Source – Free

Pipsgrowth EX15003 SMC-OrderBlock

MT5 Expert Advisor (Open Source) · XAUUSD · M5

Pipsgrowth.com EX15003 LiquidityTrap_Safe_XAUUSD_5M — safe liquidity sweep rejection EA, full 12-layer stack.

Overview

EX15003 maps where institutional liquidity pools are most likely to sit on XAUUSD's 5-minute chart, and waits for a price rejection to fire off those pools before it commits capital. It is the most defensively wired member of the SMC-OrderBlock family in the EX15 lineup — the full twelve-layer stack (regime detection, signal generation, entry, confirmation, no-trade gating, capital cap, risk, sizing, management, exit, scaling, and OnTester) is actually plumbed into the code rather than merely claimed in the header. The trading idea rests on the SMC observation that price does not move in straight lines — it sweeps obvious liquidity resting above prior swing highs and below prior swing lows, and only then reverses. The EA's job is to identify those liquidity pools, wait for a wick or engulfing candle to form at the level, and trade the rejection with the higher-timeframe trend as a filter.

Zone detection. The signal engine runs on every new M5 bar. DetectSwingPivot() walks each closed bar at InpSignalShift=1 and checks two bars to the left and two bars to the right: if the bar is a strict high (no neighbor on either side matching it), it is registered as a swing-high liquidity pool; if it is a strict low, it is a swing-low pool. Each new pool is pushed into the global g_zones[] array via AddZone(), which also draws a horizontal OBJ_HLINE on the chart in crimson (for upper pools) or sea green (for lower pools), so the trader can see the levels visually. The array is capped at 64 simultaneous zones; new zones are skipped if they fall within 50 points (ZONE_BUFFER_POINTS) of an existing zone on the same side, and each zone expires 24 hours after its creation time (the InpZoneAgeHours input). This means the EA always trades a finite, age-bounded library of candidate levels — never stale ones from a week ago.

Entry trigger. A zone becomes a candidate the moment price trades into its reaction band. The band thickness is InpZoneThicknessPts=80 points on either side of the pivot. When ask for a buy-side zone (or bid for a sell-side zone) crosses into the band, the EA calls ConfirmAll(), which enforces three independent gates: (1) CheckHTFTrend() — the H1 close must be above the H1 EMA50 for a buy, below for a sell (InpRequireHTF=true); (2) CheckEngulfing() — the current bar's body must engulf the previous bar's body in the trade direction (InpRequireEngulfing=true); (3) CheckSurge() — the bar's directional body move must be at least 0.10% of open (SURGE_PCT=0.0010). If all three gates pass, the trade is sent. Two more sub-checks run: PyramidAllowed() for scaling-in eligibility, and SideCount(buy)<=ZONE_MAX_SYMBOL_SIDE=1 so the EA never holds two positions in the same direction on the same symbol at the same time. Once a zone fires, it is consumed: g_zones[i].active=false and the chart line is removed.

The regime classifier. This is the part of the EA that decides whether the current volatility environment is even worth trading. CalcRegime() reads 200 bars of ATR(14), ADX(14), and Bollinger Bands(20, 2.0) width, then ranks the current values into percentiles. Seven outcomes are possible: R_STRONG_TREND (ADX >= 28), R_WEAK_TREND (ADX 20-28), R_RANGE (ATR-percentile <= 25 and no strong ADX), R_COMPRESS (ATR-percentile <= 25 AND BB-width-percentile <= 25), R_EXPAND (both >= 80), R_BREAKOUT (ATR-percentile >= 80, BB-width not extreme), and R_CHOPPY (the fallback when nothing else matches). RegimeAllowsEntry() returns true only for STRONG_TREND, WEAK_TREND, BREAKOUT, and EXPAND — in other words, the EA only fires when the market is actually moving. If regime is RANGE, R_COMPRESS, or R_CHOPPY, entries are blocked at the no-trade gate, and (if InpExitOnRegimeFlip=true, the default) existing positions are closed by ManageRegimeExit().

Risk and sizing. Position size is computed by CalcLotByRisk() against a hard-SL distance. The user specifies risk as a percentage of effective capital: InpRiskPercent=0.5% by default. Effective capital is EffCapital(), which returns MathMin(InpCapAmount, equity) if a capital cap is set (InpCapAmount>0.0), or full equity otherwise. The 0.5% risk figure, applied to the current ATR-derived SL distance, gives the lots the EA requests; ClampVolume() then snaps to the symbol's volume step, floor, and ceiling. If the risk-percent calc fails for any reason, the EA falls back to InpFixedLot=0.01. Before sending the order, SendEntry() calls OrderCalcMargin() to compute the margin requirement and refuses if the account's free margin is insufficient. A retry-on-requote/timeout branch inside SendEntry() re-attempts the order once with no specified price (letting the broker fill at market) before giving up.

The no-trade gate. This is the most heavily-armored part of the EA. NoTradeReason() returns the first failing condition it finds, in this order: kill-switch (InpKillSwitch), capital below InpCapFloor=50.0, current spread > InpMaxSpreadPts=60.0 points, current spread > 2x the 50-bar rolling average (RollingSpreadAvg()), off-session (hour outside 7-21 server time, or weekend), disallowed regime, cooldown active, daily loss >= InpDailyLossPct=3.0% of effective capital, weekly loss >= InpWeeklyLossPct=6.0%, daily trade count >= MAX_DAILY_TRADES=8, concurrent positions >= InpMaxConcurrent=3, and ATR-not-available. The order matters: a daily-loss breach blocks new entries even if everything else is green, which is exactly the defensive behavior the SMC family is meant to deliver.

Trade management. Once a position is open, four management functions run on every tick. ManageBreakEven() ratchets the stop to entry+5 points once the trade reaches +1R. ManagePartial() closes 50% of the position at TP1, defined as ATR(14) * PARTIAL_ATR_MULT=2.7 (~+1.5R). ManageTrail() activates an ATR-trail of ATR(14) * TRAIL_ATR_MULT=2.5 once the position reaches +1.2R. ManageRegimeExit() closes everything if the regime classifier re-evaluates to RANGE, COMPRESS, or CHOPPY. ManageOppositeExit() closes the trade if the H1 EMA50 flips against the position direction (a long is closed if H1 close falls below H1 EMA50; a short is closed if H1 close rises above). All modify/close calls go through the TryModify_EX15003 / TryClose_EX15003 / TryClosePartial_EX15003 retry helpers, which each make up to 3 attempts with 100-200ms backoff on REQUOTE / TIMEOUT / PRICE_OFF / PRICE_CHANGED — so a brief requote doesn't drop the trailing-stop modification.

Pyramiding. PyramidAllowed() allows up to PYR_MAX_LEVELS=3 positions in the same direction, but only if all existing positions in that direction are at >= +0.5R, the regime is not R_CHOPPY or R_COMPRESS, and the spread is below the cap. Pyramid lots are parent_lot * PYR_LOT_FACTOR=0.5, and the spacing between pyramids is ATR(14) * PYR_ATR_SPACING_MULT=1.5. The effect: the EA can add two more entries on a clean trend continuation, each smaller and further out, but it cannot pyramid into a loss.

OnTester. A custom criterion: (net_profit * profit_factor) / (1.0 + relative_drawdown_pct), requiring at least 30 trades before it returns a non-zero score. The DD term in the denominator penalizes high-drawdown passes even if they made money — which is consistent with the "Safe" framing of the variant.

OnInit / OnDeinit. OnInit creates the seven indicator handles (ATR, ADX, BB, RSI, EMA20, EMA50, H1 EMA50), aborts with INIT_FAILED if any returns INVALID_HANDLE, and sets magic, deviation (20 points), and filling mode. OnDeinit releases all seven handles and deletes the chart objects. The InpDryRun=true default means the EA's order-send path is short-circuited until the user explicitly sets it to false — the EA logs [DRY-RUN] BUY lot=0.0X ... instead of actually opening positions. This is the right default for a Safe variant: it lets a trader attach the EA to a chart, watch the logs and the liquidity lines, and confirm the signal engine is firing as expected before any capital is at risk.

Strategy Deep Dive

At the close of every M5 bar, the EA walks the last 200 bars to compute a regime state from ATR-percentile, ADX(14), and Bollinger Band width — and only fires signals when the regime is StrongTrend, WeakTrend, Breakout, or Expand. The signal engine builds a rolling list of swing-pivot liquidity pools (fractals with a 2-bar L/R lookback), drawn on the chart as horizontal lines, and a candidate trade triggers when price dips into the pool's 80-point reaction band with an engulfing candle, a 0.10% body surge, and H1 trend agreement. The seven native indicator handles (ATR, ADX, BB, RSI, EMA20, EMA50, H1 EMA50) are created in OnInit and released in OnDeinit; per-tick management (BE, partial TP, trail, regime-exit, HTF-exit) runs on every tick, while the no-trade gate and entry decisions run only on new-bar closes. The OnTester criterion is (net * PF) / (1 + DD%), requiring 30+ trades, so optimizer passes that look profitable on raw profit but drawdown heavily are penalized.

Entry Signal

When price trades into a swing-pivot liquidity pool's reaction band (default 80 points thick on each side), the EA fires a buy or sell — but only if the closed M5 bar shows an engulfing pattern, a 0.10% directional body surge, and the H1 close is on the correct side of the H1 EMA50. The signal then passes through a regime classifier (ADX, ATR-percentile, BB-width) and a no-trade stack that includes spread cap, daily-loss cap, session window, and cooldown gates.

Exit Signal

Exits are managed on a layered basis: stop moves to break-even+5 points at +1R, half the position is closed at +1.5R (TP1), an ATR-trail kicks in at +1.2R, and the remaining half is closed either at TP (~2R) or earlier if the regime classifier flips to Range/Compress/Choppy or the H1 EMA50 crosses against the position direction.

Stop Loss

Hard stop is set at ATR(14, M5) * 1.8 from entry, capped at 4000 points as a safety ceiling. The level is broker-attached at entry, and is later ratcheted to break-even+5 points at +1R by ManageBreakEven().

Take Profit

Initial take-profit is ATR(14, M5) * 3.6 (~2R, with a MIN_RR=1.8 gate inside SendEntry()). Half the position is taken at +1.5R via ManagePartial(), and the rest is closed by TP, trailing stop, regime-flip exit, or H1 EMA50 opposite-flip exit.

Best For

Best deployed on XAUUSD M5 with a broker that publishes tight spreads (60-point cap, ~1.5 pips on a 4-digit or ~0.6 pips on a 5-digit feed) and supports ECN-style filling. Minimum recommended balance: $100, but the EA's InpCapAmount input lets the trader allocate a fixed equity slice to this strategy alone (e.g. $1,000 out of a $10,000 account). The 7-21 server-time session window and the regime classifier are tuned to capture London open and the New York morning — the highest-volatility window for gold — while filtering out the Asian dead-zone. The default 0.5% risk-per-trade and 3% daily-loss cap make it appropriate for a MEDIUM-risk allocation; the user should keep InpDryRun=true for the first sessions to confirm zone and regime behavior matches their broker's session clock.

Strategy Logic

Pipsgrowth EX15003 SMC-OrderBlock — Strategy Logic Analysis (from .mq5 source)

Family: SMC-OrderBlock Magic: 22215003 Version: 2.00

BRIEF: Safe Liquidity Trap EA mapping swing liquidity pools (high/low sweeps), waiting for price rejection surge at the zone with engulfing + HTF trend alignment, gated by ADX/ATR-percentile/ BB-width regime. Capital-allocation-cap, ATR hard SL, BE, partial TP, ATR-trail, regime-change exit. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester

INDICATOR STACK:

  • Standard MT5 indicators

KEY FUNCTIONS:

  • EffCapital()
  • TodayRealizedPnL()
  • PositionsThisMagic()
  • SideCount()
  • NormalizePrice()
  • StopsLevelPoints()
  • FreezeLevelPoints()
  • ClampVolume()
  • SpreadPoints()
  • RollingSpreadAvg()
  • CalcRegime()
  • RegimeAllowsEntry()
  • ...and 26 more

INTERNAL CONSTANTS (29 total):

  • MAX_ZONES = 64 // max simultaneous zones tracked
  • ZONE_BUFFER_POINTS = 50.0 // zone proximity dedupe (points)
  • ZONE_MAX_SYMBOL_SIDE = 1 // max entries per side per symbol
  • LOOKBACK_BARS = 200 // bars used for ATR-pctile / BB-width history
  • SL_ATR_MULT = 1.8 // hard SL = ATR(M5,14) * mult
  • TP_ATR_MULT = 3.6 // initial TP = ATR(M5,14) * mult (2R)
  • BE_TRIGGER_R = 1.0 // break-even at +1R
  • BE_OFFSET_POINTS = 5 // BE locks entry + N points
  • PARTIAL_PCT = 50 // partial TP closes 50% at TP1 = +1.5R
  • PARTIAL_ATR_MULT = 2.7 // ATR multiple for partial-TP1 distance
  • TRAIL_ATR_MULT = 2.5 // ATR trailing distance
  • TRAIL_TRIGGER_R = 1.2 // start trailing at +1.2R
  • ATR_PCTILE_LO = 25 // range/compress threshold (percentile)
  • ATR_PCTILE_HI = 80 // breakout/expand threshold
  • BB_WIDTH_PCTILE_LO = 25 // Bollinger width low percentile
  • ...and 14 more

INPUT PARAMETERS (21 total across 7 groups):

  • [=== Identity ===] InpMagic = 22215003 // Magic number
  • [=== Identity ===] InpTradeComment = "Psgrowth.com Expert_15003" // Order comment
  • [=== Identity ===] InpSignalShift = 1 // Signal bar shift (1=closed bar)
  • [=== Identity ===] InpDryRun = true // Dry-run: skip real sends
  • [=== Risk & Sizing ===] InpRiskPercent = 0.5 // Risk per trade (% of effective_capital)
  • [=== Risk & Sizing ===] InpDailyLossPct = 3.0 // Max daily loss (% of effective_capital)
  • [=== Risk & Sizing ===] InpWeeklyLossPct = 6.0 // Max weekly loss (%)
  • [=== Risk & Sizing ===] InpMaxConcurrent = 3 // Max concurrent positions (this symbol/magic)
  • [=== Risk & Sizing ===] InpFixedLot = 0.01 // Fallback fixed lot
  • [=== Capital Allocation Cap ===] InpCapAmount = 0.0 // Cap amount (real money equity $)
  • [=== Capital Allocation Cap ===] InpCapFloor = 50.0 // Floor below which no new entries
  • [=== Signal (Liquidity Sweep) ===] InpSwingBars = 2 // Swing pivot L/R bars
  • [=== Signal (Liquidity Sweep) ===] InpZoneAgeHours = 24 // Max zone age (hours)
  • [=== Signal (Liquidity Sweep) ===] InpZoneThicknessPts = 80.0 // Entry reaction band thickness (points)
  • [=== Confirm & Regime ===] InpRequireHTF = true // Require HTF(H1) EMA50 agreement
  • [=== Confirm & Regime ===] InpRequireEngulfing = true // Require engulfing candle confirm
  • [=== Confirm & Regime ===] InpMaxSpreadPts = 60.0 // Max spread (points)
  • [=== Exit / Manage ===] InpUseTrail = true // Enable ATR trailing
  • [=== Exit / Manage ===] InpUsePartial = true // Enable partial TP at TP1
  • [=== Exit / Manage ===] InpExitOnRegimeFlip = true // Exit on regime flip to Range/Choppy
  • [=== System ===] InpKillSwitch = false // KILL SWITCH (block everything)
Pseudocode
// Pipsgrowth EX15003 SMC-OrderBlock — Execution Flow (from source analysis)
// Family: SMC-OrderBlock
// Safe Liquidity Trap EA mapping swing liquidity pools (high/low sweeps), waiting for price rejection surge at the zone with engulfing + HTF trend alignment, gated by ADX/ATR-percentile/ BB-width regime. Capital-allocation-cap, ATR hard SL, BE, partial TP, ATR-trail, regime-change exit. 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:
M5

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 a chart matching the recommended timeframe
  7. 7Configure parameters according to the table on this page
  8. 8Enable Allow Algo Trading and click OK

EA Parameters

ParameterDefaultDescription
InpMagic22215003Magic number
InpTradeComment"Psgrowth.com Expert_15003"Order comment
InpSignalShift1Signal bar shift (1=closed bar)
InpDryRuntrueDry-run: skip real sends
InpRiskPercent0.5Risk per trade (% of effective_capital)
InpDailyLossPct3.0Max daily loss (% of effective_capital)
InpWeeklyLossPct6.0Max weekly loss (%)
InpMaxConcurrent3Max concurrent positions (this symbol/magic)
InpFixedLot0.01Fallback fixed lot
InpCapAmount0.0Cap amount (real money equity $)
InpCapFloor50.0Floor below which no new entries
InpSwingBars2Swing pivot L/R bars
InpZoneAgeHours24Max zone age (hours)
InpZoneThicknessPts80.0Entry reaction band thickness (points)
InpRequireHTFtrueRequire HTF(H1) EMA50 agreement
InpRequireEngulfingtrueRequire engulfing candle confirm
InpMaxSpreadPts60.0Max spread (points)
InpUseTrailtrueEnable ATR trailing
InpUsePartialtrueEnable partial TP at TP1
InpExitOnRegimeFliptrueExit on regime flip to Range/Choppy
InpKillSwitchfalseKILL SWITCH (block everything)
Source Code (.mq5)Open Source
Pipsgrowth_com_EX15003.mq5
#property copyright "Pipsgrowth.com"
#property link      "https://pipsgrowth.com"
#property version   "2.00"
#property strict
#property description "Pipsgrowth.com EX15003 LiquidityTrap_Safe_XAUUSD_5M — safe liquidity sweep rejection EA, 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>

CTrade         trade;
CPositionInfo  pos;
CSymbolInfo    sym;
CAccountInfo   acc;

//================== CONSTANTS (non-input tunables) ==================
#define MAX_ZONES              64      // max simultaneous zones tracked
#define ZONE_BUFFER_POINTS     50.0   // zone proximity dedupe (points)
#define ZONE_MAX_SYMBOL_SIDE   1      // max entries per side per symbol
#define LOOKBACK_BARS          200     // bars used for ATR-pctile / BB-width history
#define SL_ATR_MULT            1.8     // hard SL = ATR(M5,14) * mult
#define TP_ATR_MULT            3.6     // initial TP = ATR(M5,14) * mult (2R)
#define BE_TRIGGER_R           1.0     // break-even at +1R
#define BE_OFFSET_POINTS       5       // BE locks entry + N points
#define PARTIAL_PCT            50      // partial TP closes 50% at TP1 = +1.5R
#define PARTIAL_ATR_MULT       2.7     // ATR multiple for partial-TP1 distance
#define TRAIL_ATR_MULT         2.5     // ATR trailing distance
#define TRAIL_TRIGGER_R        1.2     // start trailing at +1.2R
#define ATR_PCTILE_LO          25      // range/compress threshold (percentile)
#define ATR_PCTILE_HI          80      // breakout/expand threshold
#define BB_WIDTH_PCTILE_LO     25      // Bollinger width low percentile
#define BB_WIDTH_PCTILE_HI     80      // Bollinger width high percentile
#define ADX_STRONG             28.0    // ADX >= this => StrongTrend
#define ADX_WEAK               20.0    // ADX >= this => WeakTrend
#define HTF_PERIOD             PERIOD_H1
#define HTF_EMA_PERIOD         50
#define FAST_EMA               20
#define SLOW_EMA               50
#define RSI_PERIOD             14
#define ATR_PERIOD             14
#define ADX_PERIOD             14
#define BB_PERIOD              20
#define BB_DEV                 2.0
#define SURGE_PCT              0.0010  // 0.10% body surge
#define MAX_SL_POINTS          4000    // cap SL distance (points) safety
#define MIN_RR                 1.8     // min reward:risk to send
#define COOLDOWN_BARS          3       // bars to wait after a loss
#define MAX_DAILY_TRADES       8       // per-symbol daily trade cap
#define SESSION_START_HOUR     7       // broker server time
#define SESSION_END_HOUR       21      // broker server time
#define PYR_MAX_LEVELS         3       // hard cap on pyramid levels
#define PYR_ATR_SPACING_MULT   1.5     // spacing between pyramid entries
#define PYR_LOT_FACTOR         0.5     // pyramid lots = parent * factor
#define ROLLING_SPREAD_BARS    50      // bars used to baseline spread avg

//================== INPUTS (12-22, grouped) =========================
input group "=== Identity ==="

Full source code available on download

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

Tags:ex15003smc-orderblockpipsgrowthfreemt5xauusd

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_EX15003.mq5
File Size34.2 KB
Versionv2.00
PlatformMetaTrader 5
File Type.mq5 Source
StrategyOther
Risk LevelMedium Risk
Timeframes
M5
Currency Pairs
XAUUSD
Min. Deposit$100