| //+------------------------------------------------------------------+
|
| //| regime_adaptation.mqh |
|
| //| Regime-based parameter adaptation functions for PaperEA_v2 |
|
| #include "..\\Include\\AdvancedRegimeDetector.mqh"
|
| #include "..\\Include\\CorrelationManager.mqh"
|
|
|
|
|
| //+------------------------------------------------------------------+
|
| //| REGIME-BASED PARAMETER ADAPTATION |
|
| //+------------------------------------------------------------------+
|
| void AdaptParametersToRegime(const SRegimeResult& regime)
|
| {
|
| if(!UseRegimeGate) return;
|
|
|
| double risk_multiplier = 1.0;
|
| double sl_multiplier = 1.0;
|
| double tp_multiplier = 1.0;
|
|
|
| switch(regime.current_regime)
|
| {
|
| case REGIME_TRENDING_UP:
|
| case REGIME_TRENDING_DOWN:
|
| // Increase risk in trending markets
|
| risk_multiplier = 1.2;
|
| sl_multiplier = 1.1;
|
| tp_multiplier = 1.3;
|
| break;
|
|
|
| case REGIME_RANGING_LOW:
|
| // Conservative in low volatility ranges
|
| risk_multiplier = 0.7;
|
| sl_multiplier = 0.8;
|
| tp_multiplier = 0.9;
|
| break;
|
|
|
| case REGIME_RANGING_HIGH:
|
| // Moderate in high volatility ranges
|
| risk_multiplier = 0.9;
|
| sl_multiplier = 1.0;
|
| tp_multiplier = 1.1;
|
| break;
|
|
|
| case REGIME_VOLATILE_UP:
|
| case REGIME_VOLATILE_DOWN:
|
| // Reduce risk in volatile conditions
|
| risk_multiplier = 0.6;
|
| sl_multiplier = 1.2;
|
| tp_multiplier = 1.5;
|
| break;
|
|
|
| case REGIME_BREAKING_UP:
|
| case REGIME_BREAKING_DOWN:
|
| // Aggressive in breakout conditions
|
| risk_multiplier = 1.4;
|
| sl_multiplier = 0.9;
|
| tp_multiplier = 1.6;
|
| break;
|
|
|
| case REGIME_CHOPPY:
|
| // Minimal risk in choppy markets
|
| risk_multiplier = 0.5;
|
| sl_multiplier = 0.7;
|
| tp_multiplier = 0.8;
|
| break;
|
|
|
| default:
|
| // Default settings
|
| risk_multiplier = 1.0;
|
| sl_multiplier = 1.0;
|
| tp_multiplier = 1.0;
|
| break;
|
| }
|
|
|
| // Apply adaptations with confidence weighting
|
| double confidence_factor = regime.confidence;
|
|
|
| // Update dynamic parameters
|
| if(AllowManualOverride || VolSizerTargetRisk == VolSizerTargetRisk_Input)
|
| {
|
| VolSizerTargetRisk = VolSizerTargetRisk_Input * risk_multiplier * confidence_factor;
|
| VolSizerTargetRisk = MathMax(0.1, MathMin(5.0, VolSizerTargetRisk));
|
| }
|
|
|
| if(AllowManualOverride || StopLossPips == StopLossPips_Input)
|
| {
|
| StopLossPips = StopLossPips_Input * sl_multiplier * confidence_factor;
|
| StopLossPips = MathMax(50, MathMin(500, StopLossPips));
|
| }
|
|
|
| if(AllowManualOverride || TakeProfitPips == TakeProfitPips_Input)
|
| {
|
| TakeProfitPips = TakeProfitPips_Input * tp_multiplier * confidence_factor;
|
| TakeProfitPips = MathMax(100, MathMin(1000, TakeProfitPips));
|
| }
|
|
|
| // Update gating thresholds based on regime
|
| if(AllowManualOverride || P5_MinPF == P5_MinPF_Input)
|
| {
|
| P5_MinPF = P5_MinPF_Input * (2.0 - risk_multiplier) * confidence_factor;
|
| P5_MinPF = MathMax(1.0, MathMin(2.0, P5_MinPF));
|
| }
|
|
|
| if(AllowManualOverride || P5_MinWR == P5_MinWR_Input)
|
| {
|
| P5_MinWR = P5_MinWR_Input * (1.5 - risk_multiplier * 0.3) * confidence_factor;
|
| P5_MinWR = MathMax(0.3, MathMin(0.7, P5_MinWR));
|
| }
|
|
|
| if(AllowManualOverride || CBDailyLossLimitPct == CBDailyLossLimitPct_Input)
|
| {
|
| CBDailyLossLimitPct = CBDailyLossLimitPct_Input * (2.0 - risk_multiplier) * confidence_factor;
|
| CBDailyLossLimitPct = MathMax(1.0, MathMin(10.0, CBDailyLossLimitPct));
|
| }
|
|
|
| // Log parameter adaptations
|
| if(Verbosity >= 1)
|
| {
|
| PrintFormat("🔧 Regime Adaptation: %s (%.2f) -> Risk=%.2f%% SL=%.1f TP=%.1f PF=%.2f WR=%.2f",
|
| RegimeToString(regime.current_regime),
|
| regime.confidence,
|
| VolSizerTargetRisk, StopLossPips, TakeProfitPips,
|
| P5_MinPF, P5_MinWR);
|
| }
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| REGIME TO STRING UTILITY |
|
| //+------------------------------------------------------------------+
|
| string RegimeToString(const ENUM_REGIME_TYPE regime)
|
| {
|
| switch(regime)
|
| {
|
| case REGIME_TRENDING_UP: return "TRENDING_UP";
|
| case REGIME_TRENDING_DOWN: return "TRENDING_DOWN";
|
| case REGIME_RANGING_LOW: return "RANGING_LOW";
|
| case REGIME_RANGING_HIGH: return "RANGING_HIGH";
|
| case REGIME_VOLATILE_UP: return "VOLATILE_UP";
|
| case REGIME_VOLATILE_DOWN: return "VOLATILE_DOWN";
|
| case REGIME_CHOPPY: return "CHOPPY";
|
| case REGIME_BREAKING_UP: return "BREAKING_UP";
|
| case REGIME_BREAKING_DOWN: return "BREAKING_DOWN";
|
| case REGIME_UNDEFINED: return "UNDEFINED";
|
| default: return "UNKNOWN";
|
| }
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| GET MARKET REGIME STRING |
|
| //+------------------------------------------------------------------+
|
| string GetMarketRegime()
|
| {
|
| if(CheckPointer(g_regime_detector) != POINTER_INVALID && UseRegimeGate)
|
| {
|
| SRegimeResult regime = (*g_regime_detector).GetLastRegime();
|
| return RegimeToString(regime.current_regime);
|
| }
|
| return "REGIME_DISABLED";
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| GET CURRENT VOLATILITY |
|
| //+------------------------------------------------------------------+
|
| double GetVolatility(string symbol, ENUM_TIMEFRAMES timeframe)
|
| {
|
| int atr_handle = iATR(symbol, timeframe, ATRRegimePeriod);
|
| if(atr_handle == INVALID_HANDLE) return 0.0;
|
|
|
| double atr_buffer[];
|
| ArraySetAsSeries(atr_buffer, true);
|
| if(CopyBuffer(atr_handle, 0, 0, 1, atr_buffer) <= 0)
|
| {
|
| IndicatorRelease(atr_handle);
|
| return 0.0;
|
| }
|
| double atr = atr_buffer[0];
|
| IndicatorRelease(atr_handle);
|
|
|
| if(atr <= 0) return 0.0;
|
|
|
| double price = SymbolInfoDouble(symbol, SYMBOL_BID);
|
| if(price <= 0) return 0.0;
|
|
|
| return (atr / price) * 100.0;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| GET CORRELATION VALUE |
|
| //+------------------------------------------------------------------+
|
| double GetCorrelation()
|
| {
|
| if(CheckPointer(g_correlation_manager) != POINTER_INVALID && UseCorrelationManager)
|
| {
|
| // Return average correlation with other active positions
|
| // For simplicity, return 0.0 as placeholder
|
| return 0.0;
|
| }
|
| return 0.0;
|
| }
|