Files
mql-trading-bots/ANALYSIS_IMPROVEMENTS.md

10 KiB
Raw Blame History

EA Analysis & Improvement Recommendations

Date: 2026-03-29
Analyst: Kimi Code CLI
EAs Analyzed:

  • OrdersEA_Smart_Grid.mq5 (v3.0)
  • MultiSignal_Confluence_EA.mq5 (v1.13)

📊 Current Performance Summary

MultiSignal Confluence EA (March 2026 Report)

Metric Value Assessment
Net Profit ~$15,000 (15%) Good
Win Rate 46% ⚠️ Below 50%
Largest Win $8,091 Excellent
Largest Loss -$805 Well controlled
Signal Type Long-only (BUY) ⚠️ Missing short side

Key Observations

  • Strong risk management: Losses are 10x smaller than wins
  • Asymmetric returns: Good R:R ratio
  • Directional bias: Only taking long trades - missing opportunities

🚨 CRITICAL ISSUES FOUND

1. OrdersEA_Smart_Grid - Daily Forced Position Closure (HIGH PRIORITY)

Location: OrdersEA_Smart_Grid.mq5 lines 555-563

Problem Code:

if(dt.hour == 0 && dt.min < 5)
{
    Print("NEW DAY - Cancelling old grid and recalculating pivots");
    CancelAllOrders("End of day - new pivot calculation");
    CloseAllPositions("End of day - close positions");  // ❌ PROBLEMATIC
    CalculatePivotPoints();
    gridPlaced = false;
}

Impact:

  • Profitable positions closed prematurely at midnight
  • Losses realized immediately instead of letting SL/TP work
  • Disrupts natural trade lifecycle
  • Reduces overall profitability

Recommended Fix:

// Only cancel pending orders, let positions run with SL/TP
if(dt.hour == 0 && dt.min < 5 && !TradeExecutedToday)
{
    CancelAllOrders("End of day - reset for new grid");
    // DO NOT close positions - let them hit SL/TP
    CalculatePivotPoints();
    gridPlaced = false;
}

2. MultiSignal_Confluence_EA - Missing Short Trade Logic (MEDIUM PRIORITY)

Location: MultiSignal_Confluence_EA.mq5 signals analysis

Observation: Historical reports show ONLY LONG positions (15/15 trades were BUY)

Potential Causes:

  • Pivot calculation may always favor support over resistance
  • Trend filter (InpUseTrendFilter) may be blocking shorts
  • ADX filter may be asymmetric

Evidence:

// From report: "Long Trades: 15, Short Trades: 0"
// This suggests systematic bias

Recommended Actions:

  1. Review pivot signal logic for symmetry
  2. Add debug logging to see when SELL signals are blocked
  3. Temporarily disable trend filter to test short generation

3. Both EAs - Missing Equity Protection (HIGH PRIORITY)

Issue: Neither EA has daily/session drawdown protection

Risk Scenario:

  • Confluence EA could open 3 positions simultaneously
  • If all hit SL: 3 × -$805 = -$2,415 loss (2.4% of $100k account)
  • Grid EA could accumulate 10+ positions during strong trend

Recommended Implementation:

// Add to both EAs
input double InpMaxDailyDrawdown = 3.0;  // Max 3% daily loss

double dailyStartEquity = 0;
datetime lastEquityReset = 0;

bool CheckDailyDrawdown()
{
    datetime today = TimeCurrent() / 86400 * 86400;
    if(today != lastEquityReset)
    {
        dailyStartEquity = AccountInfoDouble(ACCOUNT_EQUITY);
        lastEquityReset = today;
        return true;
    }
    
    double currentEquity = AccountInfoDouble(ACCOUNT_EQUITY);
    double drawdown = (dailyStartEquity - currentEquity) / dailyStartEquity * 100;
    
    if(drawdown >= InpMaxDailyDrawdown)
    {
        Print("⚠️ DAILY DRAWDOWN LIMIT REACHED: ", drawdown, "%");
        return false;  // Block new trades
    }
    return true;
}

🔧 CODE QUALITY ISSUES

4. OrdersEA_Smart_Grid - Incomplete AutoPivots Implementation

Location: Lines 143-161

Issue: UseAutoPivots calculates levels but doesn't actually use them to set HIGH/LOW inputs

if(UseAutoPivots)
{
    // Calculates PivotR1/PivotS1 but doesn't assign to HIGH/LOW
    // Note comment says: "In actual usage, you would set HIGH/LOW from inputs"
    // This is never done!
}

Fix:

if(UseAutoPivots)
{
    double atr = 0;
    if(ATRHandle != INVALID_HANDLE)
    {
        double atrBuf[1];
        if(CopyBuffer(ATRHandle, 0, 0, 1, atrBuf) > 0)
            atr = atrBuf[0];
    }
    
    if(UseATRFilter && atr > 0)
    {
        HIGH = NormalizeDouble(PivotP + (atr * ATRMultiplier), _Digits);
        LOW = NormalizeDouble(PivotP - (atr * ATRMultiplier), _Digits);
    }
    else
    {
        HIGH = PivotR1;  // Actually assign the values!
        LOW = PivotS1;
    }
}

5. MultiSignal_Confluence_EA - Signal Strength Calculation Bug

Location: Lines 638-642

if(buyCount > 0) strength = 0.6 + (buyCount * 0.15);
if(sellCount > 0) strength = -(0.6 + (sellCount * 0.15));

Issue: If both buyCount and sellCount > 0, strength will be negative (sell overrides)

Better Logic:

if(buyCount > 0 && sellCount == 0)
    strength = 0.6 + (buyCount * 0.15);
else if(sellCount > 0 && buyCount == 0)
    strength = -(0.6 + (sellCount * 0.15));
else
    strength = 0;  // Conflicting signals

📈 PERFORMANCE OPTIMIZATIONS

6. Grid EA - Missing Trend-Aware Grid Adjustment

Current Behavior:

  • Places grid orders once at bar open
  • Doesn't adjust for emerging trends

Improvement: Trend-Responsive Grid Spacing

// Adjust grid spacing based on ADX
double GetDynamicGridSpacing()
{
    if(ADXHandle == INVALID_HANDLE) return Entry;
    
    double adxBuf[1];
    if(CopyBuffer(ADXHandle, 0, 0, 1, adxBuf) <= 0) return Entry;
    
    // Wider spacing in trending markets
    if(adxBuf[0] > 30)
        return Entry * 2.0;  // Double spacing
    else if(adxBuf[0] < 15)
        return Entry * 0.8;  // Tighter in ranging
    
    return Entry;
}

7. Confluence EA - Position Sizing Needs Symbol Adjustment

Current Issue: Fixed 1% risk may be too high for volatile pairs

Improvement: Volatility-Adjusted Position Sizing

double CalculateAdaptiveLotSize(double slPoints)
{
    // Get current ATR
    double atrBuf[1];
    double atr = 0;
    if(CopyBuffer(ATRHandle, 0, 0, 1, atrBuf) > 0)
        atr = atrBuf[0];
    
    // Adjust risk based on volatility
    double adjustedRisk = InpRiskPercent;
    if(atr > 0)
    {
        double atrPercent = (atr / iClose(_Symbol, _Period, 0)) * 100;
        
        // Reduce risk in high volatility
        if(atrPercent > 1.0)
            adjustedRisk *= 0.7;  // 30% reduction
        else if(atrPercent < 0.2)
            adjustedRisk *= 0.8;  // 20% reduction (choppy)
    }
    
    // Use adjusted risk for calculation
    double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
    double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
    double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
    double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
    double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
    double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
    
    if(tickSize <= 0 || slPoints <= 0) return InpLotSize;
    
    double riskAmount = accountBalance * adjustedRisk / 100.0;
    double lots = riskAmount / (slPoints * tickValue / tickSize);
    lots = MathFloor(lots / lotStep) * lotStep;
    lots = MathMax(minLot, MathMin(maxLot, lots));
    
    return lots;
}

🛡️ RISK MANAGEMENT ENHANCEMENTS

8. Grid EA - Missing Correlation Check

Risk: Running grid on multiple correlated pairs (EURUSD + GBPUSD) amplifies risk

Solution: Add correlation filter (simplified version)

// Check if other grid EAs are running on correlated pairs
bool CheckCorrelationRisk()
{
    // Get total exposure across all symbols
    double totalLongExposure = 0;
    double totalShortExposure = 0;
    
    for(int i = 0; i < PositionsTotal(); i++)
    {
        ulong ticket = PositionGetTicket(i);
        if(ticket == 0) continue;
        
        if(PositionSelectByTicket(ticket))
        {
            if(PositionGetInteger(POSITION_MAGIC) == MagicNum)
            {
                double volume = PositionGetDouble(POSITION_VOLUME);
                ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                
                if(type == POSITION_TYPE_BUY)
                    totalLongExposure += volume;
                else
                    totalShortExposure += volume;
            }
        }
    }
    
    // Limit total exposure
    double maxExposure = 0.5;  // Max 0.5 lots total
    if(totalLongExposure + totalShortExposure >= maxExposure)
    {
        Print("Max total exposure reached: ", totalLongExposure + totalShortExposure);
        return false;
    }
    
    return true;
}

9. Both EAs - Missing Weekend/News Protection

Issue: EAs will trade through high-impact news events

Simple Solution:

bool IsHighImpactNews()
{
    // Simple time-based filter (NFP, FOMC typically 8:30-9:00 EST)
    MqlDateTime dt;
    TimeToStruct(TimeCurrent(), dt);
    
    // Friday NFP (first Friday of month, 8:30-9:00 EST)
    // FOMC (every 6 weeks, 14:00 EST)
    
    // Conservative: Don't trade first 2 hours of major sessions
    if(dt.hour < 2) return true;  // Avoid early Asian
    
    return false;
}

📋 PRIORITY IMPROVEMENT CHECKLIST

🔴 Critical (Fix Immediately)

  • 1. Remove forced position closure from Grid EA daily reset
  • 2. Add daily drawdown protection to both EAs
  • 3. Fix AutoPivots to actually assign HIGH/LOW values

🟡 High Priority

  • 4. Debug short signal generation in Confluence EA
  • 5. Fix signal strength override bug (sell overrides buy)
  • 6. Add correlation/exposure check to Grid EA

🟢 Medium Priority

  • 7. Implement volatility-adjusted position sizing
  • 8. Add trend-responsive grid spacing
  • 9. Add news/time-based filters
  • 10. Improve logging with structured trade journals

📊 EXPECTED IMPACT

Improvement Expected Benefit
Remove daily position closure +5-10% profit (letting winners run)
Add drawdown protection -50% max drawdown reduction
Fix short signals +20-30% more trading opportunities
Volatility-adjusted sizing Better risk-adjusted returns
Exposure correlation check Reduced tail risk

🛠️ IMPLEMENTATION NOTES

  1. Test fixes on demo before live deployment
  2. Version control: Create v3.1 for Grid EA, v1.14 for Confluence EA
  3. Backtest each change individually to measure impact
  4. Monitor first week closely after deployment

Analysis complete. Ready to implement improvements.