mql5/Experts/Advisors/DualEA/Include/CDualEAController.mqh

263 lines
6.9 KiB
MQL5
Raw Permalink Normal View History

2026-02-24 12:47:37 -05:00
//+------------------------------------------------------------------+
//| CDualEAController.mqh - P0-P5 Master Controller |
//| Singleton controller managing all P0-P5 hardening systems |
//+------------------------------------------------------------------+
#ifndef CDUALEACONTROLLER_MQH
#define CDUALEACONTROLLER_MQH
#include "DualEA_MasterIntegration.mqh"
#include "CSystemMonitor.mqh"
#include "CSQLiteExplorationCounter.mqh"
#include "CSQLiteKnowledgeBase.mqh"
#include "CArchitectureConfig.mqh"
#include "CErrorHandling.mqh"
#include "CResourceManager.mqh"
// Forward declarations
class CIndicatorCache;
class CFeatureDriftDetector;
// Indicator types enum
enum ENUM_INDICATOR_TYPE
{
INDI_MA,
INDI_RSI,
INDI_ATR,
INDI_MACD,
INDI_ADX,
INDI_STOCHASTIC,
INDI_CCI,
INDI_MOMENTUM,
INDI_WILLIAMS,
INDI_DEMARKER,
INDI_FORCE_INDEX,
INDI_BULLS_POWER,
INDI_BEARS_POWER,
INDI_RVI,
INDI_OSMA,
INDI_TRIX,
INDI_AC,
INDI_AO,
INDI_ALLIGATOR,
INDI_GATOR,
INDI_ICHIMOKU,
INDI_FRACTALS,
INDI_ZIGZAG,
INDI_UO
};
// Note: SDualEAConfig is defined in DualEA_MasterIntegration.mqh
// and included via CDualEAController.mqh dependencies
//+------------------------------------------------------------------+
//| Dual EA Controller Class - Singleton |
//+------------------------------------------------------------------+
class CDualEAController
{
private:
static CDualEAController* s_instance;
SDualEAConfig m_config;
bool m_initialized;
CSystemMonitor* m_system_monitor;
CSQLiteKnowledgeBase* m_sqlite_kb;
CIndicatorCache* m_indicator_cache;
CFeatureDriftDetector* m_feature_drift;
// CPU budgeting
ulong m_last_tick_cpu_ms;
int m_cpu_budget_pct;
// Gate tracking
struct SGateRecord
{
string name;
bool passed;
double confidence;
datetime timestamp;
};
SGateRecord m_gate_records[];
int m_gate_record_count;
// Daily tracking
double m_daily_pnl;
double m_max_drawdown;
int m_consecutive_losses;
public:
CDualEAController()
{
m_initialized = false;
m_system_monitor = NULL;
m_sqlite_kb = NULL;
m_indicator_cache = NULL;
m_feature_drift = NULL;
m_last_tick_cpu_ms = 0;
m_cpu_budget_pct = 50;
m_gate_record_count = 0;
m_daily_pnl = 0.0;
m_max_drawdown = 0.0;
m_consecutive_losses = 0;
ArrayResize(m_gate_records, 0);
}
~CDualEAController()
{
Shutdown();
}
static CDualEAController* Instance()
{
if(s_instance == NULL)
s_instance = new CDualEAController();
return s_instance;
}
static void Destroy()
{
if(s_instance != NULL)
{
delete s_instance;
s_instance = NULL;
}
}
bool Initialize(SDualEAConfig &config)
{
if(m_initialized) return true;
m_config = config;
// Initialize system monitor
m_system_monitor = new CSystemMonitor();
// Initialize SQLite KB if enabled
if(config.sqlite_enabled)
{
m_sqlite_kb = new CSQLiteKnowledgeBase(config.sqlite_db_name);
if(!m_sqlite_kb.Initialize())
{
delete m_sqlite_kb;
m_sqlite_kb = NULL;
}
}
m_initialized = true;
Print("[DualEAController] P0-P5 controller initialized");
return true;
}
void Shutdown()
{
if(m_sqlite_kb != NULL)
{
m_sqlite_kb.Close();
delete m_sqlite_kb;
m_sqlite_kb = NULL;
}
if(m_system_monitor != NULL)
{
delete m_system_monitor;
m_system_monitor = NULL;
}
m_initialized = false;
}
CSQLiteKnowledgeBase* GetSQLiteKB() { return m_sqlite_kb; }
CIndicatorCache* GetIndicatorCache() { return m_indicator_cache; }
CFeatureDriftDetector* GetFeatureDrift() { return m_feature_drift; }
bool PreGateValidation(const string gate_name, const double &features[], double threshold)
{
// P2: Pre-gate validation with concept drift check
if(m_feature_drift != NULL)
{
// Check for feature drift before allowing gate processing
return true; // Simplified - always allow in stub
}
return true;
}
bool ShouldProcessGate(const string gate_name, bool &was_skipped)
{
// P3: CPU budgeting - skip non-essential gates under load
// G1, G4, G7, G8 are never skipped per spec
if(gate_name == "G1" || gate_name == "G4" || gate_name == "G7" || gate_name == "G8")
{
was_skipped = false;
return true;
}
// Check CPU budget
if(m_cpu_budget_pct < 20) // Under high load
{
was_skipped = true;
return false;
}
was_skipped = false;
return true;
}
void PostGateRecord(const string gate_name, bool passed, double confidence)
{
// Record gate result for auditing
int idx = m_gate_record_count;
ArrayResize(m_gate_records, idx + 1);
m_gate_records[idx].name = gate_name;
m_gate_records[idx].passed = passed;
m_gate_records[idx].confidence = confidence;
m_gate_records[idx].timestamp = TimeCurrent();
m_gate_record_count++;
}
bool SelectStrategyForExecution(const string strategy_name, const double &signals[])
{
// P2-5: Correlation-aware strategy selection
return true; // Simplified - always allow in stub
}
bool CheckCircuitBreakers(double daily_pnl_pct, double drawdown_pct,
int consecutive_losses, string &reason)
{
// P4-3: Nuclear risk engine circuit breakers
if(drawdown_pct > 10.0)
{
reason = "Max drawdown exceeded: " + DoubleToString(drawdown_pct, 2) + "%";
return true; // Circuit breaker triggered
}
if(consecutive_losses > 5)
{
reason = "Max consecutive losses: " + IntegerToString(consecutive_losses);
return true;
}
return false; // No circuit breaker
}
double GetRecommendedPositionSize(double base_size)
{
// P4-3: Kelly criterion position sizing (simplified)
return base_size;
}
string GetStatusReport()
{
string report = "=== DualEA Controller Status ===\n";
report += "Initialized: " + (m_initialized ? "Yes" : "No") + "\n";
report += "SQLite KB: " + (m_sqlite_kb != NULL ? "Active" : "Inactive") + "\n";
report += "Gate records: " + IntegerToString(m_gate_record_count) + "\n";
return report;
}
};
// Static instance initialization
CDualEAController* CDualEAController::s_instance = NULL;
// Global pointer for P0-P5 integration (defined in PaperEA_v2_P0P5_Integration.mqh)
// extern CDualEAController* g_dual_ea_controller;
#endif // CDUALEACONTROLLER_MQH