Pipsgrowth EX10012 Momentum-Scalper
MT5 Expert Advisor (Open Source) · XAUUSD · M5
Pipsgrowth.com EX10012 MomentumArb XAUUSD 5M — momentum burst arbitrage scalper, full 12-layer stack.
Overview
Pipsgrowth EX10012 is a single-position momentum-burst scalper for XAUUSD on the M5 timeframe, and its entire design rotates around one specific question: was the previous closed bar unusually large? The EA does not try to predict the next bar. Instead, the ComputeSignal() function inspects the last closed bar (shift=1) and checks whether its body — the absolute distance between open and close — exceeds the 14-period Average True Range multiplied by a configurable threshold (the InpBurstThreshold input, defaulting to 2.0). If yes, the EA classifies the bar as a momentum burst and records its direction. A confidence score is also produced: the ratio of body size to threshold feeds into a capped linear scale (strength - 1) * 50 + 50, with a ceiling of 100. The first burst bar to print at 1.5× ATR or higher lands at confidence 75, while a 2.0× bar reaches 100. This single fact — closed-bar body >= 2× ATR — is the only entry trigger. There is no cross, no crossover, no zone-retest logic layered on top.
Before that burst is allowed to become a trade, the EA routes it through a regime classifier (ClassifyRegime()) that divides the current market into seven labelled states: StrongTrend, WeakTrend, Range, Breakout, Compress, Expand, and Choppy. Classification is a two-step process. First, the 14-period ADX is checked: values at or above 28 mark a strong or expanding trend, and values between 18 and 28 mark a weak trend. Below 18 the market is treated as non-trending, and the decision falls to a 20-bar Bollinger Band width ratio: the current band width divided by the average width over the last 20 bars. Width below 75% of the average is labelled Compress (a squeeze, expected to precede a burst), width above 130% is labelled Range, and width in between is labelled Choppy (no trade). The ATR percentile over a 100-bar lookback contributes to differentiating StrongTrend (low percentile) from Expand (high percentile, ADX also >= 28). The classifier writes a bitfield — g_regimeFlags — with bits 1=trendOK, 2=rangeOK, 4=burstOK. The no-trade gate then refuses entries unless either bit 1 (trend) or bit 4 (burst) is set; Compress and Expand set the burst bit, StrongTrend and WeakTrend set the trend bit, and Choppy/Range are refused.
If the regime gate passes, three independent confirmations are applied in ConfirmDir(). First, the EA reads an H1 EMA(50) — the higher-timeframe trend filter — and refuses long entries when the bid sits below the EMA and short entries when the bid sits above it. This is the only HTF check; unlike dual-EMA cross-timeframe EAs in this family, EX10012 uses a single-EMA trend agreement. Second, the 14-period RSI on the M5 chart must agree: RSI(1) >= 50 for longs, <= 50 for shorts. Third, the MACD(12,26,9) histogram sign must match the trade direction; this is a soft filter — if the MACD buffer fails to load, the trade is allowed. All three checks can be disabled individually via the InpRequireRegime, InpRequireHTF, and InpRequireRSI toggles, which is useful for stress-testing how much of the EA's edge actually depends on each layer.
The stop-loss distance is computed from the same 14-period ATR that powers the burst detector: slDist = ATR(1) * InpSignalATRMult, defaulting to 2× ATR. The take-profit is set at slDist * InpTP_R (default 2.0R), so a 2× ATR stop pairs with a 4× ATR target. The minimum-reward-risk sanity check enforces InpTP_R >= 1.5 (the MIN_RR_RATIO define) — values below that print a skip message and refuse the entry. Position sizing is percentage-based by default: ComputeLots() reads the effective capital (capped by InpCapitalCapAmount if set, otherwise the live account equity), multiplies it by InpRiskPercent (default 0.5%), and divides by the per-lot loss at the chosen stop distance. The result is normalised to the symbol's volume step and clamped to min/max lot. A InpFixedLotMode toggle bypasses the percentage calculation and uses the symbol's minimum volume instead, which is the right setting when running on a sub-$1000 micro account or when validating behaviour without risking real capital.
Management of an open position is layered into four exit conditions, all running inside the per-tick ManagePositions() loop. The first is break-even: once the trade has moved 1R in profit (BE_TRIGGER_R), the stop is moved to entry plus 0.2R of locked profit (BE_LOCK_R). The second is a 50% partial close at +1R (PARTIAL_TP_R and PARTIAL_PCT=50); the partial is only sent if the remaining volume after the partial would still be at least 1.5× the symbol's minimum lot. The third is an ATR trailing stop: once the trade is up at least 0.8R (TRAIL_TRIGGER_R), the stop ratchets behind price at a distance of ATR(1) * 2.5 (the TRAIL_ATR_MULT define), and the new stop is only accepted if it actually improves on the existing one — there is no widening. The fourth exit is time-based: if a position has been open for 60 bars (five hours on M5, the MAX_BARS_IN_TRADE define), the EA force-closes it. A fifth escape hatch fires if the regime classifier labels the current state as Choppy — the EA closes the position immediately on the next tick, treating the trade as invalidated.
The risk stack around the entry is straightforward. NoTrade() evaluates seven distinct gates before allowing a signal to fire. Capital must be above the InpCapitalCapFloor (default $50). The current spread must be below InpMaxSpread (250 points — about 25 pips on a 5-digit gold quote, deliberately loose for an EA designed to fire on bursts). Daily realised loss must be below 3% of effective capital, weekly below 6% (InpDailyLossLimitPercent, InpWeeklyLossLimitPercent). The cooldown window (COOLDOWN_BARS=3, M5 = 15 minutes) only opens after InpCooldownLosses consecutive losses, detected by walking the last 10 deals from the deal stream inside UpdateLossStreak(). The deal history scan is limited to a 7-day window (TimeCurrent() - 7*86400). A position-count cap (InpMaxConcurrent, default 1) prevents pyramiding. The session gate blocks weekend trading entirely, refuses entries after 22:00 server time on Friday, and refuses entries before 02:00 on Monday.
There is no on-the-fly order retry beyond a single pass on TRADE_RETCODE_REQUOTE or TRADE_RETCODE_TIMEOUT. TryClose_EX10012, TryClosePartial_EX10012, and TryModify_EX10012 each loop three times on requote/timeout/price-off/price-changed responses with a 200ms sleep (100ms for modify), and they accept both TRADE_RETCODE_DONE and TRADE_RETCODE_DONE_PARTIAL as success. Filling mode is auto-selected from SYMBOL_FILLING_MODE in FOK → IOC → RETURN order. Slippage deviation is hardcoded to 20 points (MAX_SLIPPAGE_POINTS). The InpDryRun input defaults to true, so the EA will print the would-be trade — regime label, direction, confidence score — but never send an order; you must explicitly flip it to false to go live. The InpKillSwitch input, when set to true, halts every activity on the next tick and acts as a panic button for the operator.
Custom backtest grading is the last piece of the system. OnTester() returns (net * profit_factor) / (1 + drawdown_pct) provided the strategy executed at least 30 trades, has a positive profit factor, and a positive drawdown. Below 30 trades the criterion returns 0, which is the strategy-tester way of saying 'insufficient sample'. The OnTester formula is the same one used by other EAs in the Momentum-Scalper family, so the backtest rank of EX10012 is directly comparable to the other EX10 variants in MT5's optimisation pass — but EX10012's edge comes specifically from the burst-vs-regime interaction, not from a slow pullback or a state-dispatched signal, so the parameter ranges that produce meaningful wins will differ noticeably from its siblings.
The realistic operating picture: a single M5 chart on XAUUSD, on a low-spread ECN broker, with $100 minimum capital, sized at 0.5% per trade. Expect a low trade count per day — a 2× ATR burst on the M5 of gold is a real event, not a frequent one, and the regime gate will further prune trades during compressed or choppy phases. Most of the time the EA will be in a holding pattern, waiting for a bar that is clearly larger than its recent volatility. When one prints, the position opens and is actively managed: break-even ratchet, partial close, trail, time exit, and regime-change exit all run on every subsequent tick. The trade exits on its own terms, not on the operator's, and the input set is small enough to be walked through in a single MT5 strategy-tester optimisation pass without combinatorial explosion.
Strategy Deep Dive
Each tick the EA first refreshes the deal-stream realised PnL for the day and week windows, then runs UpdateLossStreak() to detect consecutive-loss cooldown triggers from the last 10 deals inside a 7-day history window. ManagePositions() walks every open position on this symbol/magic and applies the four-layer exit stack (break-even at +1R, partial 50% at +1R, ATR(14)×2.5 trail from +0.8R, 60-bar time exit, plus a Choppy-regime force-close) before any new signal is considered. The regime classifier then consumes 100 bars of ATR(14) history, the 14-period ADX, and the 20-bar Bollinger width ratio to label the market StrongTrend/WeakTrend/Range/Breakout/Compress/Expand/Choppy, storing a bitfield used by the no-trade gate. If the gate clears, ComputeSignal() inspects bar 1's body against the 2× ATR threshold (the InpBurstThreshold input) and emits a direction plus confidence. ConfirmDir() then demands H1 EMA(50) price agreement, M5 RSI(14) directional agreement, and MACD histogram sign alignment before OpenTrade() sizes the position at 0.5% of effective capital per default and sends the order through MT5's CTrade wrapper. InpDryRun=true is the default, so the EA prints the would-be entry but never sends until you flip the toggle.
The EA looks for a momentum burst on the last closed M5 bar: bar-1 body (|close - open|) must be ≥ ATR(14) × InpBurstThreshold (default 2.0). When that condition fires, ComputeSignal() records the bar's direction (+1 bullish, -1 bearish) and a confidence score derived from the body-to-threshold ratio. The burst is then gated by ClassifyRegime() (must be StrongTrend, WeakTrend, Compress, or Expand — i.e. trendOK or burstOK bit set) and confirmed by HTF H1 EMA(50) price agreement, M5 RSI(14) direction (≥50 long / ≤50 short), and MACD(12,26,9) histogram sign. A single 2× ATR burst on gold is a real event, so the EA trades rarely and only on bars that are unambiguously large.
Exits run inside ManagePositions() on every tick: a 1R move triggers break-even (stop moved to entry + 0.2R locked profit), a 1R move also fires a 50% partial close (only if remaining volume ≥ 1.5× min lot), and from +0.8R an ATR(14)×2.5 trailing stop ratchets behind price. A hard time exit closes the position after 60 M5 bars (5 hours). Additionally, if ClassifyRegime() relabels the current state as Choppy, the EA force-closes the position on the next tick, treating the trade as invalidated by the regime shift.
Initial stop-loss distance is ATR(14) on bar 1 multiplied by InpSignalATRMult (default 2.0), so on a typical XAUUSD M5 ATR of 200 points the stop sits ~400 points from entry. The floor is the broker's stop-level × 1.2, and the stop can later be ratcheted by the break-even logic at +1R and the ATR trail at +0.8R. A daily 3% and weekly 6% loss cap on effective capital also limits aggregate exposure, and 3 consecutive losses trigger a 3-bar (15-minute M5) cooldown.
Take-profit is computed as slDist × InpTP_R (default 2.0R), so a 2× ATR stop pairs with a 4× ATR target. The minimum acceptable R-multiple is 1.5 (MIN_RR_RATIO define); a value below that causes the EA to skip the entry. The same TP is also where the 50% partial close fires at +1R, leaving the remainder to run to the full target or to the trailing stop.
Run on a single XAUUSD M5 chart with a low-spread ECN broker (typical gold spread under 25 points) and at least $100 in account equity — the $50 capital-cap floor kicks in below that. The conservative 0.5% per-trade risk and the wide 250-point spread cap mean the EA tolerates less-than-ideal broker conditions better than a typical scalper, but the strategy depends on real volatility bursts on gold, so a server set to GMT+0/GMT+2/GMT+3 (London or New York overlap) is the natural home. Because the EA defaults to InpDryRun=true, you should expect to validate it in dry-run for at least a week of live-tick data before flipping the switch — the regime classifier and the 2× ATR body threshold behave very differently across quiet Asian sessions and active US sessions, and the backtester does not capture that distinction.
Strategy Logic
Pipsgrowth EX10012 Momentum-Scalper — Strategy Logic Analysis (from .mq5 source)
Family: Momentum-Scalper
Magic: 22210012
Version: 2.00
BRIEF:
Detects a bar whose body exceeds ATR*threshold (momentum burst) on the last CLOSED bar, gated by ADX/ATR-percentile/BB- width regime, HTF trend, RSI/MACD confirm, full risk/capital- cap, ATR trail, break-even, partial TP. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester
INDICATOR STACK:
- Standard
MT5indicators
KEY FUNCTIONS:
NormPrice()NormVolume()StopsLevelPoints()FillingMode()EffectiveCapital()RealizedPnL()DayStart()WeekStart()ClassifyRegime()ComputeSignal()ConfirmDir()NoTrade()- ...and 9 more
INTERNAL CONSTANTS (25 total):
ATR_PERIOD= 14 //ATRperiod (signal + trail)ATR_PCTILE_LOOKBACK= 100 // Bars forATRpercentileBB_PERIOD= 20 // Bollinger period (regime width)BB_DEVIATION=2.0// Bollinger deviation (regime width)ADX_PERIOD= 14 //ADXperiod (regime)RSI_PERIOD= 14 //RSIperiod (confirm)MACD_FAST= 12 //MACDfastEMAMACD_SLOW= 26 //MACDslowEMAMACD_SIGNAL= 9 //MACDsignalSMAHTF_EMA_PERIOD= 50 //HTFtrendEMAperiodHTF_TIMEFRAME=PERIOD_H1//HTFtrend timeframeBURST_LOOKBACK= 1 // Use shift=1 (last closed bar)MIN_RR_RATIO=1.5// Minimum reward:riskBE_TRIGGER_R=1.0// Break-even at +1RBE_LOCK_R=0.2// BE locks +0.2R- ...and 10 more
INPUT PARAMETERS (22 total across 7 groups):
- [=== Identity ===]
InpMagicNumber=22210012// Magic number (per-EAisolation) - [=== Identity ===]
InpTradeComment= "Psgrowth.com Expert_10012" // Trade comment - [=== Identity ===]
InpATRPeriodSig= 14 //ATRperiod for burst signal (bars) - [=== Risk & Sizing ===]
InpRiskPercent=0.5// Risk per trade (% of effective capital) - [=== Risk & Sizing ===]
InpDailyLossLimitPercent=3.0// Daily loss limit (% of effective capital) - [=== Risk & Sizing ===]
InpWeeklyLossLimitPercent=6.0// Weekly loss limit (% of effective capital) - [=== Risk & Sizing ===]
InpMaxConcurrent= 1 // Max concurrent positions (this symbol/magic) - [=== Risk & Sizing ===]
InpCooldownLosses= 3 // Cooldown after N consecutive losses - [=== Risk & Sizing ===]
InpFixedLotMode=false// Use fixed lot (bypass % risk) - [=== Capital Allocation Cap ===]
InpCapitalCapAmount=0.0// Cap amount ($ real money equity) - [=== Capital Allocation Cap ===]
InpCapitalCapFloor=50.0//Floor($); below = block new entries - [=== Signal ===]
InpBurstThreshold=2.0// Body >=ATR* threshold (burst trigger) - [=== Signal ===]
InpSignalATRMult= 2 //ATRmultiplier for SL distance - [=== Regime / Confirm ===]
InpRequireRegime=true// Require regime gate (ADX/ATR-pct/BB-width) - [=== Regime / Confirm ===]
InpRequireHTF=true// RequireHTFEMAagreement - [=== Regime / Confirm ===]
InpRequireRSI=true// RequireRSIdirectional confirm - [=== Exit / Manage ===]
InpTP_R=2.0// Take profit in R multiples - [=== Exit / Manage ===]
InpUseBreakEven=true// Enable break-even - [=== Exit / Manage ===]
InpUsePartialTP=true// Enable partial TP - [=== Execution / Safety ===]
InpMaxSpread= 250 // Max allowed spread (points) - [=== Execution / Safety ===]
InpDryRun=true// Dry-run: no real order sends - [=== Execution / Safety ===]
InpKillSwitch=false// Kill switch: stop ALL activity
// Pipsgrowth EX10012 Momentum-Scalper — Execution Flow (from source analysis)
// Family: Momentum-Scalper
// Detects a bar whose body exceeds ATR*threshold (momentum burst) on the last CLOSED bar, gated by ADX/ATR-percentile/BB- width regime, HTF trend, RSI/MACD confirm, full risk/capital- cap, ATR trail, break-even, partial TP. 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 from the Navigator onto any chart (M1 or M5 recommended)
- 7In the EA dialog, enable Allow Algo Trading and set your lot size
- 8Click OK — the EA will begin trading automatically
EA Parameters
| Parameter | Default | Description |
|---|---|---|
| InpMagicNumber | 22210012 | Magic number (per-EA isolation) |
| InpTradeComment | "Psgrowth.com Expert_10012" | Trade comment |
| InpATRPeriodSig | 14 | ATR period for burst signal (bars) |
| InpRiskPercent | 0.5 | Risk per trade (% of effective capital) |
| InpDailyLossLimitPercent | 3.0 | Daily loss limit (% of effective capital) |
| InpWeeklyLossLimitPercent | 6.0 | Weekly loss limit (% of effective capital) |
| InpMaxConcurrent | 1 | Max concurrent positions (this symbol/magic) |
| InpCooldownLosses | 3 | Cooldown after N consecutive losses |
| InpFixedLotMode | false | Use fixed lot (bypass % risk) |
| InpCapitalCapAmount | 0.0 | Cap amount ($ real money equity) |
| InpCapitalCapFloor | 50.0 | Floor ($); below = block new entries |
| InpBurstThreshold | 2.0 | Body >= ATR * threshold (burst trigger) |
| InpSignalATRMult | 2 | ATR multiplier for SL distance |
| InpRequireRegime | true | Require regime gate (ADX/ATR-pct/BB-width) |
| InpRequireHTF | true | Require HTF EMA agreement |
| InpRequireRSI | true | Require RSI directional confirm |
| InpTP_R | 2.0 | Take profit in R multiples |
| InpUseBreakEven | true | Enable break-even |
| InpUsePartialTP | true | Enable partial TP |
| InpMaxSpread | 250 | Max allowed spread (points) |
| InpDryRun | true | Dry-run: no real order sends |
| InpKillSwitch | false | Kill switch: stop ALL activity |
#property copyright "Pipsgrowth.com"
#property link "https://pipsgrowth.com"
#property version "2.00"
#property strict
#property description "Pipsgrowth.com EX10012 MomentumArb XAUUSD 5M — momentum burst arbitrage scalper, full 12-layer stack."
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
//================================================================
// NON-INPUT CONSTANTS (everything operator doesn't need to touch)
//================================================================
#define ATR_PERIOD 14 // ATR period (signal + trail)
#define ATR_PCTILE_LOOKBACK 100 // Bars for ATR percentile
#define BB_PERIOD 20 // Bollinger period (regime width)
#define BB_DEVIATION 2.0 // Bollinger deviation (regime width)
#define ADX_PERIOD 14 // ADX period (regime)
#define RSI_PERIOD 14 // RSI period (confirm)
#define MACD_FAST 12 // MACD fast EMA
#define MACD_SLOW 26 // MACD slow EMA
#define MACD_SIGNAL 9 // MACD signal SMA
#define HTF_EMA_PERIOD 50 // HTF trend EMA period
#define HTF_TIMEFRAME PERIOD_H1 // HTF trend timeframe
#define BURST_LOOKBACK 1 // Use shift=1 (last closed bar)
#define MIN_RR_RATIO 1.5 // Minimum reward:risk
#define BE_TRIGGER_R 1.0 // Break-even at +1R
#define BE_LOCK_R 0.2 // BE locks +0.2R
#define PARTIAL_TP_R 1.0 // Partial TP at +1R
#define PARTIAL_PCT 50 // Partial close percent
#define TRAIL_ATR_MULT 2.5 // ATR trailing multiplier
#define TRAIL_TRIGGER_R 0.8 // Trail kicks in at +0.8R
#define MAX_BARS_IN_TRADE 60 // Time-based exit (bars)
#define COOLDOWN_BARS 3 // Bars between entries
#define REGIME_MIN_ADX 18.0 // Min ADX for trend trade
#define REGIME_BREAKOUT_ADX 28.0 // ADX >= this = strong/expanding
#define SPREAD_ROLL_WINDOW 50 // Bars for rolling spread avg
#define MAX_SLIPPAGE_POINTS 20 // Max slippage deviation (points)
//================================================================
// INPUTS (count: 19 — within 12-22 hard cap)
//================================================================
input group "=== Identity ==="
input int InpMagicNumber = 22210012; // Magic number (per-EA isolation)
input string InpTradeComment = "Psgrowth.com Expert_10012"; // Trade comment
input int InpATRPeriodSig = 14; // ATR period for burst signal (bars)
input group "=== Risk & Sizing ==="
input double InpRiskPercent = 0.5; // Risk per trade (% of effective capital)
input double InpDailyLossLimitPercent = 3.0; // Daily loss limit (% of effective capital)
input double InpWeeklyLossLimitPercent = 6.0;// Weekly loss limit (% of effective capital)
input int InpMaxConcurrent = 1; // Max concurrent positions (this symbol/magic)
input int InpCooldownLosses = 3; // Cooldown after N consecutive losses
input bool InpFixedLotMode = false; // Use fixed lot (bypass % risk)
input group "=== Capital Allocation Cap ==="
// InpCapitalCapEnabled removed — use InpCapitalCapAmount=0 to disable // Enable capital cap
input double InpCapitalCapAmount = 0.0; // Cap amount ($ real money equity)
input double InpCapitalCapFloor = 50.0; // Floor ($); below = block new entriesFull 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 Scalping strategy EAs from our library
Pipsgrowth EX14020 Scalper
Pipsgrowth.com EX14020 AIXAUUSDScalper — AI-assisted XAUUSD scalper, full 12-layer stack.
Pipsgrowth EX10006 Momentum-Scalper
Pipsgrowth.com EX10006 USDJPY Scalper — USDJPY pullback momentum scalper, full 12-layer stack.
Pipsgrowth EX14021 Scalper
Pipsgrowth.com EX14021 EURUSDScalper — BB + MACD divergence scalper, full 12-layer stack.
Community
Educational purposes only. Do NOT use with real money. Test on demo accounts only.