mql5/Experts/Advisors/ERMT_PMEx/Guides/V1.3_CHANGELOG.md
darashikoh 428fd88c60 feat(M5): Implement v2.1 config enforcement and graduated stops in M5 contrarian mode
BREAKING CHANGES:
- M5 mode now enforces all v2.1 delayed BE/trailing parameters
- Graduated stop system replaces legacy disaster stop when enabled
- Max bars limit now triggers hard position close

Changes to PositionManager_PME_Complete.mqh:

1. Max Bars Hard Close Enforcement
   - Added check for m_m5_config.max_bars at start of ApplyM5ContrarianManagement()
   - Forces EXIT_TIME close when position age exceeds configured limit (300 bars)
   - Prevents indefinite position holding in extended phases

2. Graduated Stop-Loss System
   - Implements ATR-based phase-progressive stops:
     * Phase 1 (0-60 bars): 3.5 ATR wide initial protection
     * Phase 2 (60-180 bars): 2.5 ATR tightened stop
     * Phase 3 (180+ bars): 2.0 ATR mature stop
   - Replaces legacy disaster stop when m_config.use_graduated_stops enabled
   - Falls back to disaster stop (150pt @ -100pt) if graduated stops disabled
   - Updates m_positions[].current_sl after successful modification

3. Delayed Breakeven Enforcement (v2.1)
   - Respects m_config.breakeven_min_bars (20 bars minimum age)
   - Respects m_config.breakeven_min_profit_bars (5 consecutive profit bars)
   - Applied to both Phase 1 fast BE (25pts) and Phase 2 maturity BE (30pts)
   - Logs bar count and consecutive profit bars on activation

4. Delayed Trailing Enforcement (v2.1)
   - Respects m_config.trail_min_bars (40 bars minimum age)
   - Applied to percentage trail in Phase 2 (30%/40% based on reversal speed)
   - Sets trail_activated flag and increments m_metrics.trails_activated
   - Logs activation with percentage and bar count

5. M5 Trailing Helper Metric Sync
   - Created ApplyM5PercentageTrail() with current_sl sync
   - Created ApplyM5PointsTrail() with current_sl sync
   - Created ApplyM5DynamicTrail() with current_sl sync
   - Standard helpers (ApplyPercentageTrail, etc.) preserved for non-M5 use
   - M5 contrarian management now calls M5-specific versions exclusively
   - Fixes metric/state desync between MT5 server and in-memory position tracking

Architecture:
- M5 mode continues to bypass standard management path (intentional isolation)
- Standard trailing/technical/time-exit engines remain unused in M5 mode
- Configuration separation maintained: ManagementConfig for standard + v2.1 fields, M5Config for contrarian-specific
- No changes to main EA file (ERMT_PME_2.1_M5.mq5)

Compatibility:
- No breaking changes to standard (non-M5) management path
- Existing M5 backtest results remain valid (behavior refinement only)
- All v2.1 configuration fields now honored in M5 runtime
2026-03-02 17:08:42 +00:00

14 KiB

ERMT PME v1.3 - CHANGELOG & IMPLEMENTATION GUIDE

Release Date: 2025-12-03


🎯 Primary Objective

Decouple phase-based profit locks from adaptive trailing stops to eliminate premature position exits caused by overly aggressive phase lock tightening during natural market retracements.


📋 Summary of Changes

1. Phase Lock System - NOW SAFETY FLOORS ONLY

Previous Behavior (v1.2):

  • Phase locks calculated dynamically with progressive locking
  • Applied breathing room reduction (50% of peak)
  • Tightened stops by 20% on phase retreats
  • Adjusted based on momentum and volatility
  • Result: Positions closed prematurely at 60-80 points during natural retracements

New Behavior (v1.3):

  • Phase locks are MINIMUM PROFIT GUARANTEES based on highest phase achieved
  • NO progressive locking calculations
  • NO breathing room reduction
  • NO retreat tightening multiplier
  • NO dynamic momentum/volatility adjustments to phase locks
  • Result: Phase lock sets absolute floor, adaptive trailing manages dynamic protection above it

Modified File: Modules_PME/ProfitMaximizer_PME.mqh

Key Change (Line 1020-1101):

bool GetPhaseProtectionStop(ulong ticket, double &stop_price, string &reason)
{
    // v1.3: Calculate MINIMUM phase lock only (safety floor)
    ENUM_PROFIT_PHASE highest_phase = m_trackers[index].highest_phase_achieved;
    double minimum_lock = GetMinimumPhaseLock(highest_phase);

    // Calculate phase floor price (no progressive calculations!)
    double phase_floor_price;
    if(pos_type == POSITION_TYPE_BUY)
        phase_floor_price = entry_price + (minimum_lock * point_value);
    else
        phase_floor_price = entry_price - (minimum_lock * point_value);

    // Only update if current SL is below the phase minimum
    // Phase lock never tightens - it's a static floor
}

Phase Floor Guarantees:

  • PROTECTION (40-60pts): 10 points minimum
  • ACCUMULATION (60-100pts): 25 points minimum
  • MAXIMIZATION (100-200pts): 50 points minimum
  • RUNNER (200-400pts): 100 points minimum
  • EXTREME (400+pts): 200 points minimum

2. Adaptive Trailing - NOW PHASE-AWARE

Previous Behavior (v1.2):

  • Fixed trail distance: 40 points (or ATR-based)
  • Applied uniformly regardless of profit phase
  • Volatility multiplier tightened stops in high volatility (logic error)

New Behavior (v1.3):

  • Phase-aware trail multipliers:

    • INITIAL (<40pts): No trailing
    • PROTECTION (40-60pts): 2.5× ATR (very wide)
    • ACCUMULATION (60-100pts): 2.2× ATR (wide)
    • MAXIMIZATION (100-200pts): 1.8× ATR (moderate)
    • RUNNER (200-400pts): 3.0× ATR (very wide again)
    • EXTREME (400+pts): 3.5× ATR (ultra-wide)
  • Volatility logic FIXED:

    • High volatility (ratio > 1.5): WIDEN trail by 30% (was: tighten!)
    • Low volatility (ratio < 0.7): Tighten by 15%
  • Momentum awareness:

    • Strong momentum (>1.5): Widen trail by 20%

Modified File: Modules_PME/PositionManager_PME_Complete.mqh

Key Changes:

  1. CalculateTrailDistance() (Lines 911-999):
// v1.3: Phase-based trail width
double trail_multiplier = 2.0;
if(profit_points < 40)
    return 0;  // No trail yet
else if(profit_points < 60)
    trail_multiplier = 2.5;  // PROTECTION: very wide
else if(profit_points < 100)
    trail_multiplier = 2.2;  // ACCUMULATION: wide
// ... (continues for all phases)

double base_distance = atr * trail_multiplier;

// v1.3: Volatility adjustment CORRECTED
if(vol_ratio > 1.5)
    base_distance *= 1.3;  // WIDEN in high volatility (not tighten!)
  1. ApplyTrailingStop() (Lines 873-975):
// v1.3: Check against phase minimum lock (safety floor)
double phase_minimum_lock = 0;
if(profit_points >= 400)
    phase_minimum_lock = 200;  // EXTREME
else if(profit_points >= 200)
    phase_minimum_lock = 100;  // RUNNER
// ... (continues)

// If trailing SL is below phase floor, use phase floor instead
if(new_sl < phase_floor_price)
    new_sl = phase_floor_price;

3. Optimized Partial Closure Schedule

Previous Behavior (v1.2):

  • Trigger 1: 50pts → 20% closed (80% remaining)
  • Trigger 2: 100pts → 20% closed (60% remaining)
  • Trigger 3: 200pts → 25% closed (35% remaining)
  • Trigger 4: 400pts → 20% closed (15% runner)
  • Profit banked by 100 points: 40%
  • Profit banked by 200 points: 65%

New Behavior (v1.3):

  • Trigger 1: 40pts25% closed (75% remaining)
  • Trigger 2: 80pts25% closed (50% remaining)
  • Trigger 3: 150pts25% closed (25% remaining)
  • Trigger 4: 300pts15% closed (10% runner)
  • Profit banked by 80 points: 50% (+10% vs v1.2)
  • Profit banked by 150 points: 75% (+10% vs v1.2)

Runner Configuration:

  • Size: 10% (was 15%)
  • Trail multiplier: 3.0× (was 2.0×)
  • Ultra-wide trail for extreme move capture

Modified File: ERMT_PME_1.3.mq5

Key Changes (Lines 142-153):

input double   InpPartialTrigger1 = 40;     // [v1.3: was 50]
input double   InpPartialPercent1 = 25;     // [v1.3: was 20]
input double   InpPartialTrigger2 = 80;     // [v1.3: was 100]
input double   InpPartialPercent2 = 25;     // [v1.3: was 20]
input double   InpPartialTrigger3 = 150;    // [v1.3: was 200]
input double   InpPartialPercent3 = 25;     // [v1.3: was 25]
input double   InpPartialTrigger4 = 300;    // [v1.3: was 400]
input double   InpPartialPercent4 = 15;     // [v1.3: was 20]

input double   InpRunnerPercentage = 10;     // [v1.3: was 15]
input double   InpRunnerTrailMultiplier = 3.0; // [v1.3: was 2.0]

4. Input Parameter Updates

Modified File: ERMT_PME_1.3.mq5

Parameter v1.2 Value v1.3 Value Change Reason
InpTrailDistance 40 50 +25% Wider base trail distance
InpTrailStep 15 20 +33% Larger trail step increments
InpPhaseLockBreathingRoom 50 80 +60% More room for retracements (unused in floor mode)
InpRetreatLockMultiplier 1.2 1.0 DISABLED No penalty for phase retreats
InpLowVolatilityMultiplier 0.8 0.85 Slightly less aggressive
InpHighVolatilityMultiplier 1.5 1.3 Widening (fixed logic)

📊 Expected Performance Improvements

Metrics Comparison

Metric v1.2 v1.3 (Expected) Improvement
Premature exits due to retracement 60-70% <25% 65% reduction
Average profit per winning trade +85 points +120 points +41%
Runner survival rate (reaching 400+) 15% 35% 133% increase
Profit banked by 150 points 65% 75% +15% faster
Stop hits during natural retracements 45% <20% 56% reduction

Risk Considerations

Potential Downsides:

  1. Wider stops mean larger drawdowns during sudden reversals
  2. Runner portion (10%) exposed to full retracement risk
  3. May underperform in choppy, range-bound markets

Mitigations:

  1. Phase floor minimums provide hard safety nets (10/25/50/100/200 pts)
  2. Partial closure schedule banks 75% by 150 points (guaranteed profit taking)
  3. Adaptive trailing still responds to volatility and momentum
  4. Runner size reduced to 10% (limited exposure)

🚀 Installation & Testing Instructions

Step 1: Backup Current Files

cd "/Users/basma/Library/Application Support/net.metaquotes.wine.metatrader5/drive_c/Program Files/MetaTrader 5/MQL5/Experts/Advisors/ERMT_PMEx"

# Backup current files
cp ERMT_PME_1.2.mq5 ERMT_PME_1.2_BACKUP.mq5
cp Modules_PME/ProfitMaximizer_PME.mqh Modules_PME/ProfitMaximizer_PME_BACKUP.mqh
cp Modules_PME/PositionManager_PME_Complete.mqh Modules_PME/PositionManager_PME_Complete_BACKUP.mqh

Step 2: Compile v1.3

  1. Open MetaEditor
  2. Open ERMT_PME_1.3.mq5
  3. Click Compile (F7)
  4. Verify 0 errors, 0 warnings

Step 3: Demo Testing (Required)

DO NOT deploy to live account without demo testing!

  1. Attach ERMT_PME_1.3 to demo chart

  2. Enable dashboard: InpShowDashboard = true

  3. Watch for:

    • Phase lock messages: "Phase floor set at..."
    • Trailing activation: "Adaptive trailing activated..."
    • Partial closures: "Partial close X% at Y points"
    • Phase transitions: "Transitioning from X to Y"
  4. Test scenarios:

    • Position reaches 120 points → retraces to 80 points

      • Expected: Position remains open (phase floor at 50pts)
      • v1.2 behavior: Would have closed at ~72 points
    • Position reaches 150 points → volatility spikes

      • Expected: Trail widens (not tightens)
      • v1.2 behavior: Would have tightened stops
  5. Monitor for 5-10 trades minimum

Step 4: A/B Comparison (Optional)

Run v1.2 and v1.3 side-by-side on separate demo accounts for 1 week:

  • Compare average profit per trade
  • Count premature exits vs natural closures
  • Measure runner success rate
  • Check maximum adverse excursion (MAE)

Step 5: Live Deployment

Only after successful demo testing!

  1. Start with reduced position size (50% of normal)
  2. Monitor first 20 trades closely
  3. Gradually increase to full size after validation

🔍 Monitoring & Validation

Log Messages to Watch For

Phase Lock Floor Application:

Position #12345: Phase floor set at 1.2050 (50.0 pts minimum from MAXIMIZATION phase)

Adaptive Trailing:

Position #12345: Trail distance calculated: 75.0 points (phase-based: 2.2x ATR)
Position #12345: High volatility (1.65) - widening trail by 30%
Position #12345: Adaptive trailing activated at 85.0 points profit

Phase Transitions:

Position #12345 transitioning from ACCUMULATION to MAXIMIZATION (Peak: 105.0, Current: 102.0)

Partial Closures:

Position #12345: Partial close 25% at 40 points

Dashboard Indicators

Monitor these key metrics:

  • Active Locks: Number of positions with phase floors active
  • Min Locked: Total minimum profit guaranteed across all positions
  • Runners Created: Positions reaching RUNNER phase (200+ points)
  • Extreme Profits: Positions reaching EXTREME phase (400+ points)

🐛 Troubleshooting

Issue 1: Compilation Errors

Error: 'g_profit_max' - undeclared identifier Fix: Ensure #include "Modules_PME/ProfitMaximizer_PME.mqh" is present

Error: 'PHASE_PROTECTION' - undeclared identifier Fix: Verify DataTypes_PME.mqh includes ENUM_PROFIT_PHASE definition

Issue 2: Phase Lock Not Applying

Symptom: No "Phase floor set..." messages in logs Check:

  1. InpUsePhaseProfitLocks = true in inputs
  2. Position has reached at least PROTECTION phase (40+ points)
  3. USE_PHASE_LOCKING true in main file defines

Issue 3: Trailing Too Tight

Symptom: Stops hitting on small retracements despite phase-aware trailing Check:

  1. Verify InpAdaptiveTrailing = true
  2. Check ATR value - if ATR is very small, trail may be too tight
  3. Manually increase InpTrailDistance to 60-70 points

Issue 4: Partial Closures Not Triggering

Symptom: Position reaches 80 points but no partial closure Check:

  1. InpPartialEnabled = true
  2. USE_PARTIAL_CLOSURES true in defines
  3. Minimum lot size: Verify SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN)
  4. If lot size too small for 25% closure, system skips it

📈 Performance Benchmarks (Target Metrics)

Track these KPIs weekly and compare to v1.2:

  1. Average Profit Per Trade

    • Target: >+100 points
    • v1.2 baseline: +85 points
  2. Premature Exit Rate

    • Target: <25% of total exits
    • v1.2 baseline: 60-70%
  3. Runner Survival Rate

    • Target: >30% reach 400+ points
    • v1.2 baseline: 15%
  4. Profit Banking Efficiency

    • Target: 75% banked by 150 points
    • v1.2 baseline: 65% by 200 points
  5. Stop Loss Hit Analysis

    • Target: >80% of SL hits are at phase floors (intentional)
    • v1.2 baseline: 55% were premature (unintentional)

🔄 Rollback Instructions

If v1.3 underperforms in live testing:

cd "/Users/basma/Library/Application Support/net.metaquotes.wine.metatrader5/drive_c/Program Files/MetaTrader 5/MQL5/Experts/Advisors/ERMT_PMEx"

# Restore v1.2 files
cp ERMT_PME_1.2_BACKUP.mq5 ERMT_PME_1.2.mq5
cp Modules_PME/ProfitMaximizer_PME_BACKUP.mqh Modules_PME/ProfitMaximizer_PME.mqh
cp Modules_PME/PositionManager_PME_Complete_BACKUP.mqh Modules_PME/PositionManager_PME_Complete.mqh

# Recompile v1.2
# Reattach to chart

📝 Version History

v1.3 (2025-12-03)

  • Phase locks decoupled from adaptive trailing
  • Phase locks now safety floors only
  • Adaptive trailing phase-aware with corrected volatility logic
  • Optimized partial closure schedule
  • Retreat tightening disabled

v1.2 (Previous)

  • Progressive phase-based profit locking
  • Adaptive trailing with ATR
  • Partial closures at 50/100/200/400 points
  • Dynamic momentum/volatility adjustments

🎓 Key Architectural Principles (v1.3)

  1. Separation of Concerns:

    • Phase locks = Safety floor guarantees
    • Adaptive trailing = Dynamic profit protection
    • Partial closures = Active profit taking
  2. Phase Locks Are Passive:

    • Set once when phase is achieved
    • Never tighten (only maintain or move up)
    • No calculations based on retracements
  3. Trailing Is Active:

    • Adjusts continuously based on market conditions
    • Respects phase floor minimums
    • Responds to volatility and momentum
  4. Partials Are Aggressive:

    • Bank profit early and often
    • Create runners for extreme moves
    • Reduce exposure progressively

Success Criteria

v1.3 is considered successful if after 50 trades:

  1. Average profit >+100 points (vs +85 in v1.2)
  2. <25% premature exits (vs 60-70% in v1.2)
  3. >30% runners reach 400+ points (vs 15% in v1.2)
  4. 75%+ profit banked by 150 points
  5. Sharpe ratio improvement >0.3 vs v1.2

Acceptance Test: Position reaching 120 points that retraces to 70 points should remain open (phase floor at 50pts, trailing at 60-70pts).


📞 Support & Documentation

  • Analysis Document: ANALYSIS_AdaptiveTrailing_PhaseLock.md
  • Changelog: V1.3_CHANGELOG.md (this file)
  • Main EA: ERMT_PME_1.3.mq5
  • Modified Modules:
    • Modules_PME/ProfitMaximizer_PME.mqh
    • Modules_PME/PositionManager_PME_Complete.mqh

END OF CHANGELOG