Pipsgrowth EX16038 Trend
MT5 Expert Advisor (Open Source) · XAUUSD · M5, H1
Pipsgrowth.com EX16038 EX15_TrendRider_copy — multi-filter trend rider, full 12-layer stack.
Overview
EX16038 is a strict, multi-filter trend-rider for XAUUSD on M5 that demands five independent confirmations to align before any ticket hits the wire. The EA reads two EMA pairs in parallel — a 21/50 EMA on the working timeframe and a 21/50 EMA on a user-selected higher timeframe (defaults to H1 via the HigherTF_EMA=8 token that MapTimeframeInt translates to PERIOD_H1) — and only flags a buy when fast sits above slow on both timeframes and the corresponding sell setup is mirrored. That double-EMA alignment is the regime classifier: the EA treats a misaligned higher timeframe as a hard veto against taking the trade.
The rest of the EvaluateSignalOnClosedBar() routine layers four more confirmations on top of the EMA cross. ADX(14) must print at or above ADXMin=25, with +DI > -DI for buys and -DI > +DI for sells — that branch alone adds one point to whichever side's running score. RSI(14) must clear RSI_BuyMin=55 on the buy side or sink to RSI_SellMax=45 on the sell side, again adding one scoring point. The GetDonchian() helper then walks the 55 most recent closed bars, computes the highest high and lowest low, and accepts a buy only when the closed-bar close prints above the upper band or a sell when it prints below the lower band — the classic Donchian breakout filter, used here to suppress mean-reversion entries inside the channel. Finally, ATR(14) must clear ATRMinPoints=20 to add the volatility-floor point. The combined score can reach six, and the EA requires scoreBuy >= 5 with scoreSell <= 2 before a buy fires (mirrored for sells). The two conditions of OnlyTrendDirection=true (counter-trend signals disabled) and the EMA dual-timeframe alignment make this EA effectively a trend-only system with built-in mean-reversion suppression.
Entry execution lives in TryOpenDirection() and is gated by CanOpenNewEntry(). The gate runs four checks in order: the loss-streak pause timer (g_tradePauseUntil) must have elapsed, the total open position count must be below MaxOpenTrades=5, the current server hour must fall inside either London (8-17) or New York (13-22) when the session filter is on, and the spread must clear the dynamic cap. The spread cap is itself a moving target: UpdateSpreadStats() writes the current spread into a 512-element ring buffer, GetMedianSpread() runs an insertion sort and returns the median of the last SpreadMedianWindowSize=200 samples, and CheckSpreadCap() compares the live spread against SpreadCapMedianMultiplier=3.0 * median — the EA will not fire a new entry when the live spread is more than three times the recent median, which is its primary protection against broker-side spread spikes during news.
Position sizing runs through CalcLotsFromRisk(). When UseRiskPercentSizing=false (the default), the EA simply uses FixedLotSize=0.10. When the user flips the toggle on, the routine divides RiskPercentPerTrade/100 * balance by the per-lot risk measured in ticks — ticksInSL * g_tickValue where ticksInSL = slPoints * _Point / g_tickSize — and the resulting lots are normalized through ClampVolume() against the symbol's SYMBOL_VOLUME_STEP, _MIN, and _MAX. The risk math falls back to the fixed lot if any of the cached _tickSize, _tickValue, or balance inputs are non-positive, so a misconfigured broker or thin symbol won't crash the EA — it just reverts to the fixed lot.
SL and TP are fixed in points: StopLossPoints=300 and TakeProfitPoints=600 produce a 30/60 pip R:R on a 5-digit XAUUSD broker, with EnforceStopLevel=true causing RespectStopDistanceOK() to discard either stop if it falls inside the broker's SYMBOL_TRADE_STOPS_LEVEL. The EA ships with UseECNSafeOrderSend=true, which makes SendOrder() fire the market order without SL/TP first and then ModifySLTPByTicket() apply both levels after a short polling loop (10 attempts at 50ms) finds the new position — a workaround for brokers that reject distance-violating SL/TP on the initial fill. The same EnforceFreezeLevel=true flag also causes WithinFreezeLevel() to skip modify attempts within the broker's SYMBOL_TRADE_FREEZE_LEVEL, so trailing logic won't fight the broker near expiry.
The Dynamic Lock Profit ratchet is the EA's signature position-management feature. MaintainPositionsDLP() walks every open magic-symbol position once per tick and calls ApplyDynamicLockProfitToPosition(). The function reads the live bid (for buys) or ask (for sells), computes movedPts, takes steps = floor(movedPts / 150), and pushes the new SL to entry + (steps * 150 - 20) * g_point for buys or entry - (steps * 150 - 20) * g_point for sells. That is, every 150 points of favourable move the EA pulls the stop closer by 150 points minus a 20-point buffer. The ratchet only ever tightens — curSL==0 || targetSL > curSL for buys, mirrored for sells — and it respects both the freeze and stop levels before calling ModifySLTPByTicket(). At default settings the EA will start protecting profits once the trade is 150 points in the money and ratchet in 130-point increments thereafter.
Additions are also gated. GateAdditionalOK() checks that the same-direction count is zero (the initial position) before allowing the trade, and when AllowOnlyProfitableAdditions=true it then calls IsAllSameDirProfitableAtLeast() to verify that every same-direction open position has moved at least MinProfitPerTradeToAdd=5.0 points from entry. The build comment pattern is explicit: the first order tagged Initial BUY or Initial SELL, with subsequent entries tagged Add#1, Add#2, etc., and the g_nextAddIndexBuy/g_nextAddIndexSell counters increment each time.
Loss-streak handling lives in OnTradeTransaction(). Every DEAL_ADD that is a DEAL_ENTRY_OUT for this EA's magic/symbol pulls the profit+swap+commission P&L, and if it is negative it increments g_lossStreakCount and adds the absolute loss to g_lossStreakAmt. With PauseOnConsecutiveLosses=false and PauseOnLossAmount=false (both off by default) the EA never sets a pause — but if the user flips either toggle on, hitting PauseConsecutiveLossesCount=3 consecutive losses pushes g_tradePauseUntil 60 minutes into the future, and accumulated g_lossStreakAmt >= PauseLossAmount=100.0 USD does the same. Any winning exit zeroes both counters. The pause is checked at the top of CanOpenNewEntry() and is the only global entry veto.
Three TryClose_EX16038 / TryClosePartial_EX16038 / TryModify_EX16038 helper functions sit at the very bottom of the file as a 3-attempt REQUOTE / TIMEOUT / PRICE_OFF / PRICE_CHANGED retry wrapper around the standard CTrade class. They are defined but never called — every live close and modify path goes through SendOrder(), ModifySLTPByTicket(), or the polling loop inside SendOrder() with its own retry behaviour, so these helpers are dead code from the runtime perspective. They look like a leftover scaffold from a refactor that left the dedicated retry path behind.
The header advertises all twelve architecture layers — REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester. The first nine are visibly wired: the dual-EMA HTF alignment is the regime layer, EvaluateSignalOnClosedBar() is the signal/confirm combo, the CanOpenNewEntry gate is the no-trade layer, the fixed-lot / risk-percent paths are sizing, the DLP ratchet is the manage layer, and the fixed SL/TP with the close-on-fill polling is the exit path. The CAPITAL CAP layer — balance drawdown cap, equity stop, daily-loss limit — is not implemented: there is no balance ceiling, no equity stop, no daily or weekly loss limit, and no max-trades-per-day. EXIT happens entirely through SL/TP and the DLP ratchet — there is no reverse-signal close, no time-based exit, no break-even function. OnTester is described in the header but not present in the source. The EA also has a MapTimeframeInt() function declared four times in identical form, which is harmless because the linker dedupes it but does add to the file's noise.
For a first live run, default settings on a $100 ECN account will produce one 0.10 lot entry per closed bar inside the London or NY window, holding up to 5 positions in the same direction with the ratchet stepping in at every 150 points of favourable move. Spread spikes outside the rolling 3x median will gate entries but not exit live positions, so a sudden spread widening while a position is open will not trigger an early close. The Capital Cap layer being absent is the most material gap to be aware of: a long sequence of losing trades will keep opening new positions until MaxOpenTrades=5 is hit, with the only interruption being a manual pause toggle flip or a session boundary.
Strategy Deep Dive
EX16038 runs seven indicator handles in parallel from OnInit: two EMA pairs (21/50 on the working TF and the same pair on a user-selected higher TF), ADX(14), RSI(14), and ATR(14), and processes a strict 6-point scoring system on every closed bar inside EvaluateSignalOnClosedBar(). The five conditions that earn points are: dual-timeframe EMA alignment (worth 2), ADX >= 25 with DI direction, RSI threshold, Donchian(55) breakout, and ATR(14) >= 20 points — a buy only fires when the buy score hits 5 and the sell score stays at 2 or less, mirrored for sells. OnTick updates a 200-tick spread ring buffer, then calls MaintainPositionsDLP() to walk every open position through the ApplyDynamicLockProfitToPosition() ratchet, and only on a new bar does it evaluate signals and gate through CanOpenNewEntry() (loss-pause timer + MaxOpenTrades + London/NY window + 3x spread median) before calling TryOpenDirection() for the chosen side. Additions to the same direction are blocked unless every same-direction open position has moved at least MinProfitPerTradeToAdd=5.0 points in the money.
Buy entry requires: 21 EMA above 50 EMA on the working timeframe AND on the higher timeframe (default H1), ADX(14) ≥ 25 with +DI > -DI, RSI(14) ≥ 55, closed-bar close above the 55-bar Donchian upper band, and ATR(14) ≥ 20 points — the combined score must reach 5 out of 6 with the opposite side at 2 or less. Sell entry is the mirrored set with -DI > +DI, RSI(14) ≤ 45, and close below the Donchian lower band. Both sides also must clear the live-spread cap (≤ 3× the 200-tick median), fall inside London (8-17) or NY (13-22) when the session filter is enabled, and respect the one-entry-per-bar latch.
Positions exit only via the fixed SL (300 points) and TP (600 points) on a 5-digit XAUUSD broker, or when the Dynamic Lock Profit ratchet pulls the SL close enough to hit. There is no reverse-signal close, no time-based exit, and no break-even function. The DLP ratchet steps in at 150 points of favorable move and tightens by 130 points per step (150 - 20 buffer), but it only ever tightens the existing stop.
Every position opens with a fixed SL of 300 points (30 pips on 5-digit XAUUSD) unless the broker's SYMBOL_TRADE_STOPS_LEVEL discards it, in which case the EA sends the position without a server-side stop and lets the DLP ratchet and TP handle protection. The Dynamic Lock Profit ratchet only ever tightens the existing stop — it never widens.
Take profit is fixed at 600 points (60 pips on 5-digit XAUUSD), giving a 1:2 risk-to-reward against the 300-point stop. There is no multi-level TP, no basket TP, and no per-bar TP ratchet — the only TP management is the single fixed level set on entry.
XAUUSD on M5 (also works on H1) with a low-spread ECN broker — the 3× median spread cap is the primary execution gate, and 5-digit XAUUSD is the only symbol tested. Recommended balance: $100 minimum (the 0.10 fixed lot × 300-point stop = $3 per pip risk per slot, and the EA can run up to 5 same-direction positions). The default London 8-17 / NY 13-22 window is the high-liquidity gold session, so the EA should be left running through both sessions for the best hit rate on the dual-EMA breakout signals. Risk profile: MEDIUM — the strict scoring keeps signals rare, but the absence of a capital cap layer means a long losing streak will keep opening new positions until the 5-position cap or the manual pause toggle is hit.
Strategy Logic
Pipsgrowth EX16038 Trend — Strategy Logic Analysis (from .mq5 source)
Family: Trend
Magic: 22216038
Version: 2.00
BRIEF:
EX15 Trend Rider — multi-filter trend confirmation EA with MTF EMA alignment, ADX, RSI, and Donchian breakout. Dynamic Lock Profit ratchet, initial/additional trade gating, pause guards, session and spread-cap filters, ECN-safe execution. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester
INDICATOR STACK:
- Standard
MT5indicators
KEY FUNCTIONS:
Log()NormalizePrice()IsWithinTradingSession()UpdateSpreadStats()GetMedianSpread()CheckSpreadCap()IsNewBar()CountOpenPositions()CountAllOpenPositions()OwnsPosition()IsAllSameDirProfitableAtLeast()CopyVal()- ...and 19 more
INTERNAL CONSTANTS (0 total):
INPUT PARAMETERS (32 total across 8 groups):
- [===
CORE===]InpTradeComment= "Psgrowth.com Expert_16038" // ---DYNAMICLOCKPROFIT(step-ratchet) - [===
DYNAMICLOCKPROFIT===]LockProfitStepPoints= 150 // step size in points - [===
DYNAMICLOCKPROFIT===]LockProfitBufferPoints= 20 // buffer (points) subtracted from cumulative step - [===
INITIALvsADDITIONAL===]MaxOpenTrades= 5 // total across directions - [===
INITIALvsADDITIONAL===]AllowOnlyProfitableAdditions=true// gate additions when ALL same-dir trades >=MinProfitPerTradeToAdd - [===
INITIALvsADDITIONAL===]MinProfitPerTradeToAdd=5.0// points - [===
PAUSEGUARDS===]PauseConsecutiveLossesMinutes= 60 // Pause by loss amount (deposit currency) across the current loss streak - [===
PAUSEGUARDS===]PauseLossAmount=100.0// e.g., 100USD - [===
PAUSEGUARDS===]PauseLossAmountMinutes= 60 // ---RISK&TRADE - [===
RISK&TRADE===]UseRiskPercentSizing=false// iftrue, compute volume from risk % - [===
RISK&TRADE===]RiskPercentPerTrade=1.0// % of balance risked per trade - [===
RISK&TRADE===]FixedLotSize=0.10// used ifUseRiskPercentSizing==false - [===
RISK&TRADE===]StopLossPoints= 300 // SL in points - [===
RISK&TRADE===]TakeProfitPoints= 600 // TP in points - [===
RISK&TRADE===]MaxSlippagePoints= 5 // deviation forOrderSend - [===
RISK&TRADE===]EnableSpreadCapFilter=true// cap current spread - [===
RISK&TRADE===]SpreadMedianWindowSize= 200 // window for rolling median - [===
RISK&TRADE===]SpreadCapMedianMultiplier=3.0// cap = multiplier * median spread - [===
RISK&TRADE===]LimitOneEntryPerBar=true// only 1 new entry per bar - [===
SIGNALS&FILTERS===]HigherTF_EMA= 8 //Timeframe(1=M1,2=M5,3=M15,4=M30,5=H1,6=H4,7=D1) //MTFconfirmation TF - [===
SIGNALS&FILTERS===] RSI_BuyMin = 55 // >= forBUY - [===
SIGNALS&FILTERS===] RSI_SellMax = 45 // <= forSELL - [===
SIGNALS&FILTERS===]DonchianPeriod= 55 // breakout filter - [===
SIGNALS&FILTERS===] ATRPeriod = 14 // low-vol guard - [===
SIGNALS&FILTERS===] ATRMinPoints = 20 // minimalATRin points to allow entries - [===
SIGNALS&FILTERS===]OnlyTrendDirection=true// iftrue, disables counter-trend signals - [===
SESSIONS===] NYEndHour = 22 // ---BROKER&EXECUTION - [===
BROKER&EXECUTION===]UseECNSafeOrderSend=true// send without SL/TP first if needed - [===
BROKER&EXECUTION===]EnforceFreezeLevel=true// avoid modify if within freeze - [===
BROKER&EXECUTION===]EnforceStopLevel=true// avoid SL/TP too close - [===
BROKER&EXECUTION===]AllowNetting=true// if netting,EAwill manage single net position per symbol - [===
BROKER&EXECUTION===]EnableVerboseLogs=true// structured debug logs
// Pipsgrowth EX16038 Trend — Execution Flow (from source analysis)
// Family: Trend
// EX15 Trend Rider — multi-filter trend confirmation EA with MTF EMA alignment, ADX, RSI, and Donchian breakout. Dynamic Lock Profit ratchet, initial/additional trade gating, pause guards, session and spread-cap filters, ECN-safe execution. 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 H4 or Daily chart for best results
- 7Configure EMA periods, ADX threshold, and lot size in the dialog
- 8Enable Allow Algo Trading and click OK
EA Parameters
| Parameter | Default | Description |
|---|---|---|
| InpTradeComment | "Psgrowth.com Expert_16038" | --- DYNAMIC LOCK PROFIT (step-ratchet) |
| LockProfitStepPoints | 150 | step size in points |
| LockProfitBufferPoints | 20 | buffer (points) subtracted from cumulative step |
| MaxOpenTrades | 5 | total across directions |
| AllowOnlyProfitableAdditions | true | gate additions when ALL same-dir trades >= MinProfitPerTradeToAdd |
| MinProfitPerTradeToAdd | 5.0 | points |
| PauseConsecutiveLossesMinutes | 60 | Pause by loss amount (deposit currency) across the current loss streak |
| PauseLossAmount | 100.0 | e.g., 100 USD |
| PauseLossAmountMinutes | 60 | --- RISK & TRADE |
| UseRiskPercentSizing | false | if true, compute volume from risk % |
| RiskPercentPerTrade | 1.0 | % of balance risked per trade |
| FixedLotSize | 0.10 | used if UseRiskPercentSizing==false |
| StopLossPoints | 300 | SL in points |
| TakeProfitPoints | 600 | TP in points |
| MaxSlippagePoints | 5 | deviation for OrderSend |
| EnableSpreadCapFilter | true | cap current spread |
| SpreadMedianWindowSize | 200 | window for rolling median |
| SpreadCapMedianMultiplier | 3.0 | cap = multiplier * median spread |
| LimitOneEntryPerBar | true | only 1 new entry per bar |
| HigherTF_EMA | 8 | Timeframe (1=M1,2=M5,3=M15,4=M30,5=H1,6=H4,7=D1) // MTF confirmation TF |
| RSI_BuyMin | 55 | >= for BUY |
| RSI_SellMax | 45 | <= for SELL |
| DonchianPeriod | 55 | breakout filter |
| ATRPeriod | 14 | low-vol guard |
| ATRMinPoints | 20 | minimal ATR in points to allow entries |
| OnlyTrendDirection | true | if true, disables counter-trend signals |
| NYEndHour | 22 | --- BROKER & EXECUTION |
| UseECNSafeOrderSend | true | send without SL/TP first if needed |
| EnforceFreezeLevel | true | avoid modify if within freeze |
| EnforceStopLevel | true | avoid SL/TP too close |
| AllowNetting | true | if netting, EA will manage single net position per symbol |
| EnableVerboseLogs | true | structured debug logs |
#property copyright "Pipsgrowth.com"
#property link "https://pipsgrowth.com"
#property version "2.00"
#property strict
#property description "Pipsgrowth.com EX16038 EX15_TrendRider_copy — multi-filter trend rider, full 12-layer stack."
#include <Trade\Trade.mqh>
//--- ===================================================================
//--- INPUTS (Grouped)
//--- ===================================================================
//--- CORE
ENUM_TIMEFRAMES MapTimeframeInt(int tf)
{
switch(tf)
{
case 1: return PERIOD_M1;
case 2: return PERIOD_M5;
case 3: return PERIOD_M15;
case 4: return PERIOD_M30;
case 5: return PERIOD_H1;
case 6: return PERIOD_H4;
case 7: return PERIOD_D1;
default: return PERIOD_H1;
}
}
ENUM_TIMEFRAMES g_HigherTF_EMA = PERIOD_H1;
input group "=== CORE ==="
input int MagicNumber = 22216038;
input string InpTradeComment = "Psgrowth.com Expert_16038";
//--- DYNAMIC LOCK PROFIT (step-ratchet)
ENUM_TIMEFRAMES MapTimeframeInt(int tf)
{
switch(tf)
{
case 1: return PERIOD_M1;
case 2: return PERIOD_M5;
case 3: return PERIOD_M15;
case 4: return PERIOD_M30;
case 5: return PERIOD_H1;
case 6: return PERIOD_H4;
case 7: return PERIOD_D1;
default: return PERIOD_H1;
}
}
ENUM_TIMEFRAMES g_HigherTF_EMA = PERIOD_H1;
input group "=== DYNAMIC LOCK PROFIT ==="
input bool EnableDynamicLockProfit = true;
input int LockProfitStepPoints = 150; // step size in points
input int LockProfitBufferPoints = 20; // buffer (points) subtracted from cumulative step
//--- INITIAL vs ADDITIONAL
ENUM_TIMEFRAMES MapTimeframeInt(int tf)
{
switch(tf)
{
case 1: return PERIOD_M1;
case 2: return PERIOD_M5;
case 3: return PERIOD_M15;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 Trend Following strategy EAs from our library
Pipsgrowth EX16080 Trend
Pipsgrowth.com EX16080 EURUSDTrendFollower — triple-EMA H4 trend follower, full 12-layer stack.
Pipsgrowth EX16081 Trend
Pipsgrowth.com EX16081 GoldTrendEA — XAUUSD H4 EMA cross with Fib targets, full 12-layer stack.
Pipsgrowth EX16033 Trend
Pipsgrowth.com EX16033 EA_Price_Action — price-action grid scalper, full 12-layer stack.
Community
Educational purposes only. Do NOT use with real money. Test on demo accounts only.