626 lines
21 KiB
MQL5
626 lines
21 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| DualEA_MasterIntegration.mqh - Complete P0/P1 Integration |
|
||
|
|
//| Master include file that initializes all hardened components |
|
||
|
|
//| Version: 2.0 - Comprehensive EA Hardening & Intelligence Upgrade |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#ifndef DUALEA_MASTERINTEGRATION_MQH
|
||
|
|
#define DUALEA_MASTERINTEGRATION_MQH
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| P0 Components - Critical Fixes |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#include "CShadowLogger.mqh" // P0-1: Atomic CSV writes
|
||
|
|
#include "CGateFeatureCache.mqh" // P0-5: Feature caching
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| P1 Components - Architecture Upgrades |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#include "CSQLiteKnowledgeBase.mqh" // P1-1: SQLite KB
|
||
|
|
#include "CInsightGateBridge.mqh" // P1-2: O(1) insights bridge
|
||
|
|
#include "CRegimeAwareStrategy.mqh" // P1-3: Regime adaptation
|
||
|
|
#include "CSystemMonitor.mqh" // P1-4: Health circuit breaker
|
||
|
|
// Replaced Redis with SQLite - zero external dependencies
|
||
|
|
#include "CSQLiteExplorationCounter.mqh"// P1-5: Redis counters
|
||
|
|
#include "CPositionManager.mqh" // P1-6: Correlation sizing
|
||
|
|
|
||
|
|
// Include existing components
|
||
|
|
#include "EnhancedEfficientGateSystem.mqh"
|
||
|
|
#include "CMLPolishGateONNX.mqh"
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Configuration Structure |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
struct SDualEAConfig
|
||
|
|
{
|
||
|
|
// P0-1: Shadow logging
|
||
|
|
bool shadow_logging_enabled;
|
||
|
|
bool shadow_mode_only;
|
||
|
|
string shadow_log_directory;
|
||
|
|
|
||
|
|
// P0-4: ONNX monitoring
|
||
|
|
bool onnx_health_monitor_enabled;
|
||
|
|
int onnx_max_latency_ms;
|
||
|
|
|
||
|
|
// P0-5: Feature cache
|
||
|
|
int feature_cache_max_age_seconds;
|
||
|
|
|
||
|
|
// P1-1: SQLite
|
||
|
|
bool sqlite_enabled;
|
||
|
|
string sqlite_db_name;
|
||
|
|
|
||
|
|
// P1-2: Insight bridge
|
||
|
|
int insight_cache_sync_seconds;
|
||
|
|
|
||
|
|
// P1-4: System monitor
|
||
|
|
bool circuit_breaker_enabled;
|
||
|
|
double max_tick_latency_ms;
|
||
|
|
double max_error_rate_per_hour;
|
||
|
|
int circuit_breaker_cooldown_minutes;
|
||
|
|
|
||
|
|
// P1-5: Redis
|
||
|
|
bool redis_enabled;
|
||
|
|
string redis_host;
|
||
|
|
int redis_port;
|
||
|
|
|
||
|
|
// P1-6: Position management
|
||
|
|
bool correlation_sizing_enabled;
|
||
|
|
bool volatility_exits_enabled;
|
||
|
|
double max_risk_per_trade_pct;
|
||
|
|
double max_total_risk_pct;
|
||
|
|
int max_positions;
|
||
|
|
|
||
|
|
void SetDefaults()
|
||
|
|
{
|
||
|
|
// P0 defaults
|
||
|
|
shadow_logging_enabled = true;
|
||
|
|
shadow_mode_only = false;
|
||
|
|
shadow_log_directory = "DualEA\\ShadowLogs";
|
||
|
|
|
||
|
|
// P0-4 defaults
|
||
|
|
onnx_health_monitor_enabled = true;
|
||
|
|
onnx_max_latency_ms = 100;
|
||
|
|
|
||
|
|
// P0-5 defaults
|
||
|
|
feature_cache_max_age_seconds = 5;
|
||
|
|
|
||
|
|
// P1-1 defaults
|
||
|
|
sqlite_enabled = true;
|
||
|
|
sqlite_db_name = "dualea_kb.db";
|
||
|
|
|
||
|
|
// P1-2 defaults
|
||
|
|
insight_cache_sync_seconds = 60;
|
||
|
|
|
||
|
|
// P1-4 defaults
|
||
|
|
circuit_breaker_enabled = true;
|
||
|
|
max_tick_latency_ms = 50.0;
|
||
|
|
max_error_rate_per_hour = 50.0;
|
||
|
|
circuit_breaker_cooldown_minutes = 15;
|
||
|
|
|
||
|
|
// P1-5 defaults
|
||
|
|
redis_enabled = false; // Disabled by default (requires Redis server)
|
||
|
|
redis_host = "127.0.0.1";
|
||
|
|
redis_port = 6379;
|
||
|
|
|
||
|
|
// P1-6 defaults
|
||
|
|
correlation_sizing_enabled = true;
|
||
|
|
volatility_exits_enabled = true;
|
||
|
|
max_risk_per_trade_pct = 1.0;
|
||
|
|
max_total_risk_pct = 5.0;
|
||
|
|
max_positions = 10;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Dual EA Master Controller |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
class CDualEAMasterController
|
||
|
|
{
|
||
|
|
private:
|
||
|
|
SDualEAConfig m_config;
|
||
|
|
bool m_initialized;
|
||
|
|
datetime m_last_status_log;
|
||
|
|
|
||
|
|
// Component references
|
||
|
|
CShadowLogger* m_shadow_logger;
|
||
|
|
CGateFeatureCache* m_feature_cache;
|
||
|
|
CSQLiteKnowledgeBase* m_sqlite_kb;
|
||
|
|
CInsightGateBridge* m_insight_bridge;
|
||
|
|
CRegimeAwareStrategy* m_regime_strategy;
|
||
|
|
CSystemMonitor* m_system_monitor;
|
||
|
|
CSQLiteExplorationCounter* m_explore_counter;
|
||
|
|
CPositionManager* m_position_manager;
|
||
|
|
|
||
|
|
public:
|
||
|
|
// Constructor
|
||
|
|
CDualEAMasterController()
|
||
|
|
{
|
||
|
|
m_config.SetDefaults();
|
||
|
|
m_initialized = false;
|
||
|
|
m_last_status_log = 0;
|
||
|
|
m_shadow_logger = NULL;
|
||
|
|
m_feature_cache = NULL;
|
||
|
|
m_sqlite_kb = NULL;
|
||
|
|
m_insight_bridge = NULL;
|
||
|
|
m_regime_strategy = NULL;
|
||
|
|
m_system_monitor = NULL;
|
||
|
|
m_explore_counter = NULL;
|
||
|
|
m_position_manager = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Initialize all components |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool Initialize(const SDualEAConfig &config)
|
||
|
|
{
|
||
|
|
m_config = config;
|
||
|
|
|
||
|
|
Print("=== DualEA Master Controller v2.0 Initializing ===");
|
||
|
|
|
||
|
|
// P0-5: Initialize feature cache first (others depend on it)
|
||
|
|
if(!InitializeFeatureCache()) return false;
|
||
|
|
|
||
|
|
// P1-1: Initialize SQLite KB
|
||
|
|
if(m_config.sqlite_enabled)
|
||
|
|
{
|
||
|
|
if(!InitializeSQLiteKB()) return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-3: Initialize regime strategy (depends on feature cache)
|
||
|
|
if(!InitializeRegimeStrategy()) return false;
|
||
|
|
|
||
|
|
// P1-2: Initialize insight bridge (depends on SQLite KB)
|
||
|
|
if(m_config.sqlite_enabled)
|
||
|
|
{
|
||
|
|
if(!InitializeInsightBridge()) return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-4: Initialize system monitor
|
||
|
|
if(m_config.circuit_breaker_enabled)
|
||
|
|
{
|
||
|
|
if(!InitializeSystemMonitor()) return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-5: Initialize exploration counter (SQLite-based)
|
||
|
|
if(!InitializeExploreCounter()) return false;
|
||
|
|
|
||
|
|
// P1-6: Initialize position manager (depends on feature cache and regime)
|
||
|
|
if(!InitializePositionManager()) return false;
|
||
|
|
|
||
|
|
// P0-1: Initialize shadow logger
|
||
|
|
if(m_config.shadow_logging_enabled)
|
||
|
|
{
|
||
|
|
if(!InitializeShadowLogger()) return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_initialized = true;
|
||
|
|
Print("=== DualEA Master Controller v2.0 Ready ===");
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Component initializers |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool InitializeFeatureCache()
|
||
|
|
{
|
||
|
|
m_feature_cache = new CGateFeatureCache();
|
||
|
|
if(!m_feature_cache.Initialize())
|
||
|
|
{
|
||
|
|
Print("[MasterController] ERROR: Feature cache initialization failed");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Set global reference for gates
|
||
|
|
g_gate_feature_cache = m_feature_cache;
|
||
|
|
|
||
|
|
Print("[MasterController] P0-5: Feature cache initialized");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool InitializeSQLiteKB()
|
||
|
|
{
|
||
|
|
m_sqlite_kb = new CSQLiteKnowledgeBase(m_config.sqlite_db_name);
|
||
|
|
if(!m_sqlite_kb.Initialize())
|
||
|
|
{
|
||
|
|
Print("[MasterController] WARNING: SQLite KB init failed, continuing with reduced functionality");
|
||
|
|
// Don't fail completely - we can work without SQLite
|
||
|
|
delete m_sqlite_kb;
|
||
|
|
m_sqlite_kb = NULL;
|
||
|
|
m_config.sqlite_enabled = false;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
g_sqlite_kb = m_sqlite_kb;
|
||
|
|
Print("[MasterController] P1-1: SQLite KB initialized");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool InitializeInsightBridge()
|
||
|
|
{
|
||
|
|
m_insight_bridge = new CInsightGateBridge(m_sqlite_kb);
|
||
|
|
if(!m_insight_bridge.Initialize(m_sqlite_kb))
|
||
|
|
{
|
||
|
|
Print("[MasterController] WARNING: Insight bridge init failed");
|
||
|
|
delete m_insight_bridge;
|
||
|
|
m_insight_bridge = NULL;
|
||
|
|
return true; // Don't fail completely
|
||
|
|
}
|
||
|
|
|
||
|
|
// CRITICAL: Preload historical data to populate bridge stats immediately
|
||
|
|
m_insight_bridge.PreloadHotStrategies();
|
||
|
|
|
||
|
|
g_insight_gate_bridge = m_insight_bridge;
|
||
|
|
Print("[MasterController] P1-2: Insight-Gate bridge initialized with historical data");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool InitializeRegimeStrategy()
|
||
|
|
{
|
||
|
|
m_regime_strategy = new CRegimeAwareStrategy(m_feature_cache);
|
||
|
|
|
||
|
|
g_regime_strategy = m_regime_strategy;
|
||
|
|
Print("[MasterController] P1-3: Regime-aware strategy initialized");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool InitializeSystemMonitor()
|
||
|
|
{
|
||
|
|
m_system_monitor = new CSystemMonitor();
|
||
|
|
|
||
|
|
// Thresholds are configured internally via SHealthThresholds.SetDefaults()
|
||
|
|
// m_system_monitor.SetThresholds() is not available - using default thresholds
|
||
|
|
|
||
|
|
g_system_monitor = m_system_monitor;
|
||
|
|
Print("[MasterController] P1-4: System monitor with circuit breaker initialized");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool InitializeExploreCounter()
|
||
|
|
{
|
||
|
|
m_explore_counter = new CSQLiteExplorationCounter();
|
||
|
|
if(!m_explore_counter.Initialize())
|
||
|
|
{
|
||
|
|
Print("[MasterController] WARNING: Exploration counter init failed, using fallback");
|
||
|
|
delete m_explore_counter;
|
||
|
|
m_explore_counter = NULL;
|
||
|
|
return true; // Don't fail - fallback is built-in
|
||
|
|
}
|
||
|
|
|
||
|
|
g_sqliteCounter = m_explore_counter;
|
||
|
|
Print("[MasterController] P1-5: SQLite exploration counter initialized");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool InitializePositionManager()
|
||
|
|
{
|
||
|
|
m_position_manager = new CPositionManager(m_feature_cache, m_regime_strategy);
|
||
|
|
|
||
|
|
// Configure
|
||
|
|
m_position_manager.SetMaxPositions(m_config.max_positions);
|
||
|
|
m_position_manager.SetMaxRiskPerTrade(m_config.max_risk_per_trade_pct);
|
||
|
|
m_position_manager.SetMaxTotalRisk(m_config.max_total_risk_pct);
|
||
|
|
|
||
|
|
SVolatilityExitConfig vol_config;
|
||
|
|
vol_config.SetDefaults();
|
||
|
|
m_position_manager.SetVolatilityExitConfig(vol_config);
|
||
|
|
|
||
|
|
g_position_manager = m_position_manager;
|
||
|
|
Print("[MasterController] P1-6: Position manager with correlation sizing initialized");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool InitializeShadowLogger()
|
||
|
|
{
|
||
|
|
m_shadow_logger = new CShadowLogger();
|
||
|
|
|
||
|
|
if(!m_shadow_logger.Initialize(m_config.shadow_mode_only, m_config.shadow_log_directory))
|
||
|
|
{
|
||
|
|
Print("[MasterController] WARNING: Shadow logger init failed");
|
||
|
|
delete m_shadow_logger;
|
||
|
|
m_shadow_logger = NULL;
|
||
|
|
return true; // Don't fail
|
||
|
|
}
|
||
|
|
|
||
|
|
Print("[MasterController] P0-1: Shadow logger with atomic CSV initialized");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| OnTick processing - call from EA's OnTick() |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnTick()
|
||
|
|
{
|
||
|
|
if(!m_initialized) return;
|
||
|
|
|
||
|
|
// P0-5: Update feature cache
|
||
|
|
if(m_feature_cache != NULL)
|
||
|
|
m_feature_cache.Update();
|
||
|
|
|
||
|
|
// P1-3: Update regime detection
|
||
|
|
if(m_regime_strategy != NULL)
|
||
|
|
m_regime_strategy.Update();
|
||
|
|
|
||
|
|
// P1-4: Update system monitor
|
||
|
|
if(m_system_monitor != NULL)
|
||
|
|
m_system_monitor.OnTickUpdate();
|
||
|
|
|
||
|
|
// P1-6: Check volatility exits
|
||
|
|
if(m_position_manager != NULL)
|
||
|
|
m_position_manager.CheckVolatilityExits();
|
||
|
|
|
||
|
|
// P1-2: Sync insight bridge periodically
|
||
|
|
if(m_insight_bridge != NULL && m_system_monitor != NULL)
|
||
|
|
{
|
||
|
|
static int tick_counter = 0;
|
||
|
|
tick_counter++;
|
||
|
|
if(tick_counter % 600 == 0) // Every ~10 seconds (assuming 60 ticks/sec)
|
||
|
|
{
|
||
|
|
m_insight_bridge.OnTickSync();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Log status periodically
|
||
|
|
if(TimeCurrent() - m_last_status_log > 300) // Every 5 minutes
|
||
|
|
{
|
||
|
|
LogSystemStatus();
|
||
|
|
m_last_status_log = TimeCurrent();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Check if trading is allowed (circuit breaker) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool IsTradingAllowed(string &reason)
|
||
|
|
{
|
||
|
|
reason = "";
|
||
|
|
|
||
|
|
// P1-4: Check system monitor circuit breaker
|
||
|
|
if(m_system_monitor != NULL && m_system_monitor.IsCircuitBreakerActive())
|
||
|
|
{
|
||
|
|
reason = "Circuit breaker: " + m_system_monitor.GetCircuitBreakerReason();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-3: Check regime allows trading
|
||
|
|
if(m_regime_strategy != NULL)
|
||
|
|
{
|
||
|
|
if(!m_regime_strategy.IsTradingAllowed(reason))
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Process trade signal through all gates |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool ProcessTradeSignal(TradingSignal &signal,
|
||
|
|
CEfficientGateManagerEnhanced &gate_manager,
|
||
|
|
string &block_reason)
|
||
|
|
{
|
||
|
|
// P1-3: Apply regime-adjusted parameters
|
||
|
|
if(m_regime_strategy != NULL)
|
||
|
|
{
|
||
|
|
double min_confidence = m_regime_strategy.GetMinConfidenceThreshold();
|
||
|
|
// Could adjust gate thresholds here
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-2: Fast gate decision using insights
|
||
|
|
if(m_insight_bridge != NULL)
|
||
|
|
{
|
||
|
|
double signal_confidence = m_insight_bridge.GetSignalConfidence(
|
||
|
|
signal.strategy, signal.symbol);
|
||
|
|
|
||
|
|
if(signal_confidence < 0.4)
|
||
|
|
{
|
||
|
|
// Adjust-only mode: do not block, but penalize confidence and annotate reason
|
||
|
|
signal.confidence = MathMax(0.05, MathMin(1.0, signal.confidence * signal_confidence));
|
||
|
|
block_reason = "Low insight confidence (soft): " + DoubleToString(signal_confidence, 2);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-6: Check position limits
|
||
|
|
if(m_position_manager != NULL)
|
||
|
|
{
|
||
|
|
double risk_amount = 0; // Calculate based on signal
|
||
|
|
if(!m_position_manager.CanOpenPosition(signal.symbol, signal.type,
|
||
|
|
risk_amount, block_reason))
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Process through gate cascade
|
||
|
|
CSignalDecision decision;
|
||
|
|
return gate_manager.ProcessSignalEnhanced(signal, decision, block_reason);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Log gate decision to shadow log |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void LogGateDecision(const string &gate_name, const TradingSignal &signal,
|
||
|
|
bool passed, double confidence, double threshold)
|
||
|
|
{
|
||
|
|
if(m_shadow_logger != NULL)
|
||
|
|
{
|
||
|
|
SShadowLogEntry entry;
|
||
|
|
entry.Init(signal.symbol, signal.direction == 0 ? "BUY" : "SELL",
|
||
|
|
signal.price, signal.volume, signal.strategy);
|
||
|
|
|
||
|
|
// Convert gate_name to gate number for entry
|
||
|
|
int gate_num = 0;
|
||
|
|
if(gate_name == "G1") gate_num = 0;
|
||
|
|
else if(gate_name == "G2") gate_num = 1;
|
||
|
|
else if(gate_name == "G3") gate_num = 2;
|
||
|
|
else if(gate_name == "G4") gate_num = 3;
|
||
|
|
else if(gate_name == "G5") gate_num = 4;
|
||
|
|
else if(gate_name == "G6") gate_num = 5;
|
||
|
|
else if(gate_name == "G7") gate_num = 6;
|
||
|
|
else if(gate_name == "G8") gate_num = 7;
|
||
|
|
|
||
|
|
entry.gate_passed[gate_num] = passed;
|
||
|
|
entry.gate_confidence[gate_num] = confidence;
|
||
|
|
entry.gate_threshold[gate_num] = threshold;
|
||
|
|
entry.gate_block_reason[gate_num] = passed ? "" : "Below threshold";
|
||
|
|
|
||
|
|
m_shadow_logger.LogGateDecision(entry);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Record completed trade |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void RecordTrade(const STradeRecord &trade)
|
||
|
|
{
|
||
|
|
// P1-1: Log to SQLite
|
||
|
|
if(m_sqlite_kb != NULL)
|
||
|
|
{
|
||
|
|
m_sqlite_kb.LogTrade(trade);
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-2: Update insight bridge
|
||
|
|
if(m_insight_bridge != NULL)
|
||
|
|
{
|
||
|
|
m_insight_bridge.OnTradeCompleted(trade.strategy, trade.symbol,
|
||
|
|
trade.pnl, trade.r_multiple);
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-4: Update system monitor
|
||
|
|
if(m_system_monitor != NULL)
|
||
|
|
{
|
||
|
|
m_system_monitor.RecordTrade();
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-6: Remove from position tracking
|
||
|
|
if(m_position_manager != NULL && trade.id > 0)
|
||
|
|
{
|
||
|
|
// m_position_manager->RemovePosition((ulong)trade.id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Get position size with all adjustments |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double CalculatePositionSize(const TradingSignal &signal, double risk_pct)
|
||
|
|
{
|
||
|
|
if(m_position_manager == NULL) return 0;
|
||
|
|
|
||
|
|
double account_balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
||
|
|
|
||
|
|
return m_position_manager.CalculatePositionSize(
|
||
|
|
signal.symbol,
|
||
|
|
signal.type,
|
||
|
|
signal.price,
|
||
|
|
signal.sl,
|
||
|
|
risk_pct,
|
||
|
|
account_balance
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Log system status |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void LogSystemStatus()
|
||
|
|
{
|
||
|
|
string status = "=== DualEA System Status ===\n";
|
||
|
|
|
||
|
|
// P1-4: System monitor status
|
||
|
|
if(m_system_monitor != NULL)
|
||
|
|
{
|
||
|
|
status += "Health: " + m_system_monitor.GetHealthReport() + "\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-3: Regime status
|
||
|
|
if(m_regime_strategy != NULL)
|
||
|
|
{
|
||
|
|
status += "Regime: " + m_regime_strategy.RegimeToString(
|
||
|
|
m_regime_strategy.GetCurrentRegime()) + "\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-6: Position status
|
||
|
|
if(m_position_manager != NULL)
|
||
|
|
{
|
||
|
|
status += "Positions: " + m_position_manager.GetRiskReport() + "\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
// P1-2: Bridge status
|
||
|
|
if(m_insight_bridge != NULL)
|
||
|
|
{
|
||
|
|
double hit_rate, avg_lookup;
|
||
|
|
int cache_size;
|
||
|
|
m_insight_bridge.GetStats(hit_rate, avg_lookup, cache_size);
|
||
|
|
status += StringFormat("Insights: HitRate=%.1f%% Latency=%.2fus Cache=%d\n",
|
||
|
|
hit_rate * 100, avg_lookup, cache_size);
|
||
|
|
}
|
||
|
|
|
||
|
|
Print(status);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Shutdown all components |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void Shutdown()
|
||
|
|
{
|
||
|
|
Print("=== DualEA Master Controller v2.0 Shutting Down ===");
|
||
|
|
|
||
|
|
// Save all data
|
||
|
|
if(m_sqlite_kb != NULL) m_sqlite_kb.Close();
|
||
|
|
|
||
|
|
// Cleanup
|
||
|
|
if(m_shadow_logger != NULL) { delete m_shadow_logger; m_shadow_logger = NULL; }
|
||
|
|
if(m_position_manager != NULL) { delete m_position_manager; m_position_manager = NULL; }
|
||
|
|
if(m_system_monitor != NULL) { delete m_system_monitor; m_system_monitor = NULL; }
|
||
|
|
if(m_insight_bridge != NULL) { delete m_insight_bridge; m_insight_bridge = NULL; }
|
||
|
|
if(m_regime_strategy != NULL) { delete m_regime_strategy; m_regime_strategy = NULL; }
|
||
|
|
if(m_sqlite_kb != NULL) { delete m_sqlite_kb; m_sqlite_kb = NULL; }
|
||
|
|
if(m_feature_cache != NULL) { delete m_feature_cache; m_feature_cache = NULL; }
|
||
|
|
|
||
|
|
m_initialized = false;
|
||
|
|
Print("=== DualEA Master Controller v2.0 Shutdown Complete ===");
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Getters |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
CRegimeAwareStrategy* GetRegimeStrategy() { return m_regime_strategy; }
|
||
|
|
CPositionManager* GetPositionManager() { return m_position_manager; }
|
||
|
|
CSystemMonitor* GetSystemMonitor() { return m_system_monitor; }
|
||
|
|
CInsightGateBridge* GetInsightBridge() { return m_insight_bridge; }
|
||
|
|
CSQLiteKnowledgeBase* GetSQLiteKB() { return m_sqlite_kb; }
|
||
|
|
bool IsInitialized() { return m_initialized; }
|
||
|
|
};
|
||
|
|
|
||
|
|
// Global master controller instance
|
||
|
|
CDualEAMasterController* g_master_controller = NULL;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Initialize DualEA Master Controller |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool InitializeDualEAMasterController(const SDualEAConfig &config)
|
||
|
|
{
|
||
|
|
if(g_master_controller != NULL)
|
||
|
|
{
|
||
|
|
g_master_controller.Shutdown();
|
||
|
|
delete g_master_controller;
|
||
|
|
}
|
||
|
|
|
||
|
|
g_master_controller = new CDualEAMasterController();
|
||
|
|
return g_master_controller.Initialize(config);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Shutdown DualEA Master Controller |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void ShutdownDualEAMasterController()
|
||
|
|
{
|
||
|
|
if(g_master_controller != NULL)
|
||
|
|
{
|
||
|
|
g_master_controller.Shutdown();
|
||
|
|
delete g_master_controller;
|
||
|
|
g_master_controller = NULL;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif // DUALEA_MASTERINTEGRATION_MQH
|