P
PipsGrowth
Trend FollowingOpen Source – Free

Pipsgrowth EX18065 TrendFollow

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

Pipsgrowth.com EX18065 MAwithRetest_EA — MA Crossover + Pullback Retest, full 12-layer stack.

Overview

Pipsgrowth EX18065 TrendFollow is a pullback-entry trend EA built around the idea that a moving-average cross only tells you the trend direction — the actual entry happens on the next retest of the slow MA, after price has pulled back to the line and bounced. Instead of chasing the crossover bar (which usually enters mid-extension and gets stopped on the inevitable pullback), the EA waits for the pullback to actually arrive and then triggers when price touches the slow MA, the trigger candle closes in the trend direction, and a short RSI filter confirms the bounce is not overbought or oversold. The default MA pair is a 21-period EMA against a 55-period EMA on the working timeframe, with the MA method itself configurable (EMA, SMA, SMMA, LWMA).

The signal logic is the only part of the EA that fires intrabar. ComputeSignal() reads the previous two closed bars of the fast and slow MAs, the most recent RSI(14) value, and the current ATR(14). It then checks three things at once: (1) the MA stack must be bullish (fast > slow) for longs or bearish (fast < slow) for shorts, (2) the previous bar's close must come within ATR × InpRetestATRMult (default 0.5) of the slow MA — this is the 'touched the slow line' condition, and (3) the trigger candle must close in the trend direction (close > open for long, close < open for short). The RSI gate is a directional bias filter, not an extreme: long entries require RSI >= 45 (a configured InpRSIBuyMin), short entries require RSI <= 55 (InpRSISellMax). When all four conditions line up, the EA assigns a confidence score in the 50–100 range based on how cleanly the price tested the slow MA and how decisively RSI leans the trend direction, then arms an entry for the next tick on that bar.

The regime layer, computed once per bar in ComputeRegime(), runs a 6-state classifier on the previous bar's ADX(14), ATR(14) percentile, and Bollinger Band width. The thresholds are explicit: ADX >= 25 with an ATR-percentile > 60 puts the market in STRONG_TREND; the same ADX with ATR-percentile <= 60 is WEAK_TREND; ADX < 25 with ATR-percentile >= 80 is EXPAND (volatility breakout conditions); ATR-percentile <= 20 with a Bollinger-width ratio below 3.0 is COMPRESS; ATR-percentile <= 40 (with everything else moderate) is RANGE; and anything else falls into CHOPPY. Entries are blocked in CHOPPY and COMPRESS, so the EA refuses to fire a pullback trade when the slow MA is just being whipped around — the exact environment where the retest entry would get stopped out.

The confirmation step requires the higher-timeframe MA to agree. ConfirmEntry() reads an H1 EMA(55) (the InpHTF input defaults to 8 which maps to PERIOD_H1, and the period matches the slow MA on the working TF) and refuses a long if the previous H1 close is below the H1 EMA, or a short if it is above. The spread cap of 50 points (InpMaxSpreadPoints) is re-verified at this stage, not just at the risk layer, to catch the case where spread blew out between the bar open and the entry attempt. After confirmation, the SL and TP are derived from the previous bar's ATR(14): stop distance is ATR × 2.0, target distance is ATR × 3.0, giving a fixed 1:1.5 R:R that the EA enforces via a min-R:R gate (InpMinRRx = 15, where 15 means 1.5 R:R — adjusting the SL or TP multiplier below this threshold causes PreTradeRiskOK to reject the trade with reason RR_TOO_LOW).

The position-management stack is what holds the EA together once a trade is live. ManageInTrade() runs on every tick and applies three independent mechanisms. First, a one-shot break-even at 1R: once bid (for longs) or ask (for shorts) reaches entry + 1R, the stop is moved to entry (adjusted for the broker's SYMBOL_TRADE_STOPS_LEVEL), locking the trade at scratch. Second, a partial take-profit at 1R: 50% of the position (InpPartialTP1Pct) is closed at the same 1R trigger, converting the runner into a free option. Third, a forward-only ATR trail at 1.5 × ATR(14) (InpTrailATRMult) that only ratchets the stop in the profitable direction and only when the new stop is above the broker's stop-level minimum. All three modify calls go through TryModify_EX18065(), which retries up to three times on requote/timeout/price-changed with 100ms between attempts, so a momentary quote glitch will not leave a position with a stale stop.

The exit conditions are the regime flip, the opposite-signal flip, the time stop, and an optional session close. CheckExits() runs at the start of every new bar. It closes the position if the new bar's signal direction is opposite to the position (e.g. a short-signal-bar appearing while a long is open), if the regime has flipped to CHOPPY or COMPRESS (the EA trusts the regime classifier more than any single pullback signal), if the trade has been open for InpMaxBarsInTrade bars (200 by default, which is roughly 16 hours on M5), or — if the user enables InpExitAtSessionEnd — within the last hour before the configured session end hour. The trade lifecycle is enforced one-shot per bar: g_lastEntryBar prevents the EA from entering twice on the same bar even if both the signal and the confirmation clear, and the original entry is only ever sent through SendOrder() after TryClose_EX18065() / TryModify_EX18065() verify the modification path with their 3-attempt retry loops for requote and price-change conditions.

The risk budget is the final gate. PreTradeRiskOK() refuses to send any order unless the daily loss is below 3% of the effective capital, the weekly loss is below 6%, the effective capital is above the $50 floor (InpCapitalCapFloor), spread is below 50 points, the trade is inside the server-time session window (default 07:00–20:59, weekends blocked), the manual news window is not active, the EA's global kill switch is off, the maximum-open-trades cap is not reached, the lot sizing produces a value at or above the symbol's minimum lot, and OrderCalcMargin confirms the account has the free margin. Sizing is a fixed-fractional 0.5% risk of the effective capital divided by the per-tick loss of the configured stop distance, normalized to the broker's lot step, with a 0.10-lot fixed fallback (InpLotsFixed) if the calculated size rounds below the minimum lot. CooldownLosses=3 means after three consecutive closed-out losses the EA pauses for three bars before the next entry attempt; the EA also defaults to InpDryRun=true, so on a fresh install the logs will show '[DRY-RUN] BUY lots=0.10 ...' lines for every signal without any real order hitting the broker, which makes the first 24 hours of forward testing safe to run unattended.

Strategy Deep Dive

On every new bar, ComputeRegime() classifies the market into one of six states from ADX(14), ATR(14)-percentile, and Bollinger Band width, and any bar flagged CHOPPY or COMPRESS is treated as a no-trade state. ComputeSignal() then reads the 21-EMA and 55-EMA stack and the previous bar's close against the slow MA — if the close came within 0.5 × ATR(14) of the slow line, the bar closed in the trend direction, and RSI(14) clears the 45/55 directional gate, the EA arms a long or short signal with a 0–100 confidence score. ConfirmEntry() re-checks spread and refuses the signal if the H1 55-EMA disagrees, then PreTradeRiskOK() sizes the position at 0.5% risk of the effective capital, normalized to the lot step, with a margin pre-check and 3% daily / 6% weekly loss caps. Once live, ManageInTrade() applies a one-shot break-even at 1R, a 50% partial TP at 1R, and a 1.5 × ATR(14) forward-only trail; CheckExits() closes the trade on opposite-signal, regime flip, 200-bar time stop, or session end. SendOrder() defaults to InpDryRun=true so the first 24 hours log virtual fills without hitting the broker.

Entry Signal

A long entry triggers on the bar after the price has pulled back to within 0.5 × ATR(14) of the slow 55-EMA while the fast 21-EMA is above it and the previous candle closed bullish with RSI(14) >= 45. A short entry is the mirror image: slow 55-EMA above fast 21-EMA, candle within 0.5 ATR of the slow line, bearish close, RSI(14) <= 55. The H1 55-EMA must also confirm the trade direction, and the entry is skipped on any bar where the regime classifier flagged CHOPPY or COMPRESS.

Exit Signal

Positions are closed when the new bar's signal direction flips against the open trade, when ComputeRegime() flips the market to CHOPPY or COMPRESS, when the trade has been open for 200 bars (InpMaxBarsInTrade), or — if InpExitAtSessionEnd is enabled — in the last hour before the configured session end. The 50% partial TP at 1R and the 1.5 × ATR forward trail let winners run while the original stop is locked to break-even at 1R.

Stop Loss

Stop-loss distance is set to 2.0 × ATR(14) of the previous bar (InpATRStopMult = 2.0), adjusted to respect the broker's SYMBOL_TRADE_STOPS_LEVEL minimum by AdjustForStops(). Once price reaches 1R in profit, the stop is moved to break-even (open price, snapped to stops-level) for both long and short positions, and then ratcheted forward at 1.5 × ATR(14) on every tick where the new stop would be tighter than the current one.

Take Profit

Take-profit distance is set to 3.0 × ATR(14) of the previous bar (InpATRTPMult = 3.0), giving a fixed 1:1.5 R:R that the EA enforces via InpMinRRx = 15 (where 15 = 1.5 R:R). Half the position is closed at the 1R level (InpPartialTP1R = 1.0, InpPartialTP1Pct = 50), so 50% of the position banks a 1R win while the remainder rides the 1.5 × ATR trail.

Best For

Best suited to traders running XAUUSD M5–H1 with a $100 minimum account, since InpMaxOpenTrades defaults to 1 and the 0.5% fixed-fractional sizing keeps per-trade dollar risk under $1 on a $100 balance. The H1 55-EMA confirmation means a low-spread ECN broker with reliable server time is required — spread is capped at 50 points (InpMaxSpreadPoints) and a misaligned server clock will mis-time the 07:00–20:59 server-time session gate. The 200-bar time stop and the CHOPPY/COMPRESS regime filter make it appropriate for the London and New York sessions, where XAUUSD pullbacks to the 55-EMA actually develop, rather than the quiet Asian range where the retest never arrives.

Strategy Logic

Pipsgrowth EX18065 TrendFollow — Strategy Logic Analysis (from .mq5 source)

Family: TrendFollow Magic: 22218065 Version: 2.00

BRIEF: Fast/slow MA cross establishes trend direction, then wait for price to retest the slow MA before entering in the trend direction. 12-layer engine: REGIME (ADX+ATR-pct+BB-width), SIGNAL (MA-stack side + retest-touch + RSI gate), ENTRY (one-shot per bar), CONFIRM (HTF-EMA + candle-close + spread), NOTRADE, CAPITAL cap, RISK, SIZING, MANAGE (BE+partial+trail), EXIT, SCALING (pyramid OFF), OnTester. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester

INDICATOR STACK:

  • FastMA
  • SlowMA
  • ATR
  • RSI
  • ADX
  • BB
  • HTFMA

KEY FUNCTIONS:

  • NormalizePrice()
  • NormalizeVol()
  • CountOpenForMagic()
  • GetBuffer()
  • SafeCopy()
  • TodayLoss()
  • IsInSession()
  • IsInNewsWindow()
  • SpreadPoints()
  • StopsLevelPrice()
  • AdjustForStops()
  • ComputeRegime()
  • ...and 11 more

INTERNAL CONSTANTS (0 total):

INPUT PARAMETERS (42 total across 7 groups):

  • [=== Identity ===] InpTradeComment = "Psgrowth.com Expert_18065" // Trade comment
  • [=== Trade & Risk ===] InpDryRun = true // Dry-run (no real sends)
  • [=== Trade & Risk ===] InpKillSwitch = false // Global kill switch
  • [=== Trade & Risk ===] InpMagic = 22218065 // Magic number
  • [=== Trade & Risk ===] InpRiskPercent = 0.5 // Risk % per trade (effective_capital)
  • [=== Trade & Risk ===] InpLotsFixed = 0.10 // Fixed lots fallback
  • [=== Trade & Risk ===] InpDailyLossLimitPct = 3.0 // Daily loss limit %
  • [=== Trade & Risk ===] InpWeeklyLossLimitPct = 6.0 // Weekly loss limit %
  • [=== Trade & Risk ===] InpCooldownLosses = 3 // Cooldown after N losses (bars)
  • [=== Trade & Risk ===] InpMaxOpenTrades = 1 // Max concurrent trades
  • [=== Capital Allocation Cap ===] InpCapitalCapAmount = 0.0 // Real-money cap ($, not notional)
  • [=== Capital Allocation Cap ===] InpCapitalCapFloor = 50.0 // Equity floor ($, blocks new entries)
  • [=== Signal: MA + Retest ===] InpFastMAPeriod = 21 // Fast MA period
  • [=== Signal: MA + Retest ===] InpSlowMAPeriod = 55 // Slow MA period
  • [=== Signal: MA + Retest ===] InpMAMethod = MODE_EMA // MA method
  • [=== Signal: MA + Retest ===] InpRSIPeriod = 14 // RSI period
  • [=== Signal: MA + Retest ===] InpRSIBuyMin = 45.0 // RSI min for buy
  • [=== Signal: MA + Retest ===] InpRSISellMax = 55.0 // RSI max for sell
  • [=== Signal: MA + Retest ===] InpHTF = 8 // Timeframe (1=M1,2=M5,3=M15,4=M30,5=H1,6=H4,7=D1) // HTF for trend agreement
  • [=== Regime & Filters ===] InpADXPeriod = 14 // ADX period
  • [=== Regime & Filters ===] InpADXStrongMin = 25.0 // ADX ≥ strong trend
  • [=== Regime & Filters ===] InpATRPeriod = 14 // ATR period
  • [=== Regime & Filters ===] InpATRPctLookback = 50 // ATR-percentile lookback
  • [=== Regime & Filters ===] InpBBPeriod = 20 // Bollinger period
  • [=== Regime & Filters ===] InpBBDev = 2.0 // Bollinger deviation
  • [=== Regime & Filters ===] InpRetestATRMult = 0.5 // Retest tolerance (×ATR)
  • [=== Regime & Filters ===] InpMaxSpreadPoints = 50 // Max spread (points)
  • [=== Regime & Filters ===] InpMinRRx = 15 // Min R/R ×10 (1.5 → 15)
  • [=== Stops & Management ===] InpATRStopMult = 2.0 // SL = ATR × mult
  • [=== Stops & Management ===] InpATRTPMult = 3.0 // TP = ATR × mult
  • [=== Stops & Management ===] InpBETriggerR = 1.0 // Break-even trigger (×R)
  • [=== Stops & Management ===] InpPartialTP1R = 1.0 // Partial TP at ×R (0=off)
  • [=== Stops & Management ===] InpPartialTP1Pct = 50.0 // Partial close % (0–100)
  • [=== Stops & Management ===] InpTrailATRMult = 1.5 // ATR trailing multiplier
  • [=== Stops & Management ===] InpMaxBarsInTrade = 200 // Time-based exit (bars)
  • [=== News & Session ===] InpUseNewsWindow = true // Block around manual news time
  • [=== News & Session ===] InpNewsBufferMin = 15 // News buffer (minutes each side)
  • [=== News & Session ===] InpNewsHH = 12 // News hour (server time, 0=off)
  • [=== News & Session ===] InpNewsMM = 30 // News minute
  • [=== News & Session ===] InpSessionStartHH = 7 // Session start hour (server)
  • [=== News & Session ===] InpSessionEndHH = 21 // Session end hour (server)
  • [=== News & Session ===] InpExitAtSessionEnd = false // Close all at session end
Pseudocode
// Pipsgrowth EX18065 TrendFollow — Execution Flow (from source analysis)
// Family: TrendFollow
// Fast/slow MA cross establishes trend direction, then wait for price to retest the slow MA before entering in the trend direction. 12-layer engine: REGIME (ADX+ATR-pct+BB-width), SIGNAL (MA-stack side + retest-touch + RSI gate), ENTRY (one-shot per bar), CONFIRM (HTF-EMA + candle-close + spread), NOTRADE, CAPITAL cap, RISK, SIZING, MANAGE (BE+partial+trail), EXIT, SCALING (pyramid OFF), OnTester. 12 layers: REGIME, SIGNAL, ENTRY, CONFIRM, NO-TRADE, CAPITAL CAP, RISK, SIZING, MANAGE, EXIT, SCALING, OnTester

ON_INIT:
    Create indicator handles: FastMA, SlowMA, ATR, RSI, ADX, BB, HTFMA
    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 H4 or Daily chart for best results
  7. 7Configure EMA periods, ADX threshold, and lot size in the dialog
  8. 8Enable Allow Algo Trading and click OK

EA Parameters

ParameterDefaultDescription
InpTradeComment"Psgrowth.com Expert_18065"Trade comment
InpDryRuntrueDry-run (no real sends)
InpKillSwitchfalseGlobal kill switch
InpMagic22218065Magic number
InpRiskPercent0.5Risk % per trade (effective_capital)
InpLotsFixed0.10Fixed lots fallback
InpDailyLossLimitPct3.0Daily loss limit %
InpWeeklyLossLimitPct6.0Weekly loss limit %
InpCooldownLosses3Cooldown after N losses (bars)
InpMaxOpenTrades1Max concurrent trades
InpCapitalCapAmount0.0Real-money cap ($, not notional)
InpCapitalCapFloor50.0Equity floor ($, blocks new entries)
InpFastMAPeriod21Fast MA period
InpSlowMAPeriod55Slow MA period
InpMAMethodMODE_EMAMA method
InpRSIPeriod14RSI period
InpRSIBuyMin45.0RSI min for buy
InpRSISellMax55.0RSI max for sell
InpHTF8Timeframe (1=M1,2=M5,3=M15,4=M30,5=H1,6=H4,7=D1) // HTF for trend agreement
InpADXPeriod14ADX period
InpADXStrongMin25.0ADX ≥ strong trend
InpATRPeriod14ATR period
InpATRPctLookback50ATR-percentile lookback
InpBBPeriod20Bollinger period
InpBBDev2.0Bollinger deviation
InpRetestATRMult0.5Retest tolerance (×ATR)
InpMaxSpreadPoints50Max spread (points)
InpMinRRx15Min R/R ×10 (1.5 → 15)
InpATRStopMult2.0SL = ATR × mult
InpATRTPMult3.0TP = ATR × mult
InpBETriggerR1.0Break-even trigger (×R)
InpPartialTP1R1.0Partial TP at ×R (0=off)
InpPartialTP1Pct50.0Partial close % (0–100)
InpTrailATRMult1.5ATR trailing multiplier
InpMaxBarsInTrade200Time-based exit (bars)
InpUseNewsWindowtrueBlock around manual news time
InpNewsBufferMin15News buffer (minutes each side)
InpNewsHH12News hour (server time, 0=off)
InpNewsMM30News minute
InpSessionStartHH7Session start hour (server)
InpSessionEndHH21Session end hour (server)
InpExitAtSessionEndfalseClose all at session end
Source Code (.mq5)Open Source
Pipsgrowth_com_EX18065.mq5
#property copyright "Pipsgrowth.com"
#property link      "https://pipsgrowth.com"
#property version   "2.00"
#property strict
#property description "Pipsgrowth.com EX18065 MAwithRetest_EA — MA Crossover + Pullback Retest, full 12-layer stack."

#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>

//+------------------------------------------------------------------+
//| INPUTS  (18 total, grouped)                                       |
//+------------------------------------------------------------------+
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_APPLIED_PRICE MapAppliedPriceInt(int ap)
{
   switch(ap)
   {
      case 1: return PRICE_CLOSE;
      case 2: return PRICE_OPEN;
      case 3: return PRICE_HIGH;
      case 4: return PRICE_LOW;
      case 5: return PRICE_MEDIAN;
      case 6: return PRICE_TYPICAL;
      case 7: return PRICE_WEIGHTED;
      default: return PRICE_CLOSE;
   }
}
ENUM_TIMEFRAMES g_InpHTF = PERIOD_H1;
input group "=== Identity ==="
input string   InpTradeComment       = "Psgrowth.com Expert_18065"; // Trade comment

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;
   }

Full source code available on download

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

Tags:ex18065trendfollowpipsgrowthfreemt5xauusd

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_EX18065.mq5
File Size35.7 KB
Versionv2.00
PlatformMetaTrader 5
File Type.mq5 Source
StrategyTrend Following
Risk LevelMedium Risk
Timeframes
M5H1
Currency Pairs
XAUUSD
Min. Deposit$100