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