198 lines
6.9 KiB
MQL5
198 lines
6.9 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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;
|
|
}
|