| //+------------------------------------------------------------------+
|
| //| RiskIntegration.mqh |
|
| //| Copyright 2025, Your Company Name |
|
| //| https://www.yoursite.com |
|
| //+------------------------------------------------------------------+
|
| #property copyright "Copyright 2025, Your Company Name"
|
| #property link "https://www.yoursite.com"
|
| #property version "1.00"
|
| #property strict
|
|
|
| // Include all risk management components
|
| #include "RiskParameters.mqh"
|
| #include "RiskMetrics.mqh"
|
| #include "PositionSizer.mqh"
|
| #include "DrawdownManager.mqh"
|
| #include "CorrelationMatrix.mqh"
|
|
|
| //+------------------------------------------------------------------+
|
| //| Risk Integration Class |
|
| //+------------------------------------------------------------------+
|
| class CRiskIntegration
|
| {
|
| private:
|
| // Component instances
|
| CRiskParameters* m_riskParams; // Risk parameters
|
| CRiskMetrics* m_riskMetrics; // Risk metrics calculator
|
| CPositionSizer* m_positionSizer; // Position sizing
|
| CDrawdownManager* m_drawdownMgr; // Drawdown management
|
| CCorrelationMatrix* m_corrMatrix; // Correlation analysis
|
|
|
| // State
|
| bool m_isInitialized; // Initialization flag
|
| double m_accountEquity; // Current account equity
|
|
|
| // Private methods
|
| bool InitializeComponents();
|
| void UpdateAccountInfo();
|
|
|
| public:
|
| // Constructor/Destructor
|
| CRiskIntegration();
|
| ~CRiskIntegration();
|
|
|
| // Initialization
|
| bool Initialize();
|
| void Deinitialize();
|
| void Update();
|
|
|
| // Risk assessment
|
| bool CanOpenPosition(const string symbol, const ENUM_ORDER_TYPE type,
|
| const double price, const double stopLoss,
|
| const double takeProfit, double &suggestedSize);
|
|
|
| // Position management
|
| bool ValidatePositionSize(const string symbol, const double size);
|
| bool UpdatePositionMetrics(const string symbol, const double size,
|
| const double openPrice, const double currentPrice);
|
|
|
| // Getters
|
| bool IsInitialized() const { return m_isInitialized; }
|
| double GetAccountEquity() const { return m_accountEquity; }
|
| double GetMaxPositionSize() const;
|
|
|
| // Component access
|
| CRiskParameters* GetRiskParameters() { return m_riskParams; }
|
| CRiskMetrics* GetRiskMetrics() { return m_riskMetrics; }
|
| CPositionSizer* GetPositionSizer() { return m_positionSizer; }
|
| CDrawdownManager* GetDrawdownManager() { return m_drawdownMgr; }
|
| CCorrelationMatrix* GetCorrelationMatrix() { return m_corrMatrix; }
|
| };
|
|
|
| //+------------------------------------------------------------------+
|
| //| Constructor |
|
| //+------------------------------------------------------------------+
|
| CRiskIntegration::CRiskIntegration() :
|
| m_riskParams(NULL),
|
| m_riskMetrics(NULL),
|
| m_positionSizer(NULL),
|
| m_drawdownMgr(NULL),
|
| m_corrMatrix(NULL),
|
| m_isInitialized(false),
|
| m_accountEquity(0.0)
|
| {
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Destructor |
|
| //+------------------------------------------------------------------+
|
| CRiskIntegration::~CRiskIntegration()
|
| {
|
| Deinitialize();
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Initialize risk integration |
|
| //+------------------------------------------------------------------+
|
| bool CRiskIntegration::Initialize()
|
| {
|
| if (m_isInitialized)
|
| return true;
|
|
|
| // Create components
|
| m_riskParams = new CRiskParameters();
|
| if (m_riskParams == NULL || !m_riskParams.Initialize())
|
| {
|
| Print("Failed to initialize risk parameters");
|
| return false;
|
| }
|
|
|
| m_riskMetrics = new CRiskMetrics();
|
| if (m_riskMetrics == NULL || !m_riskMetrics.Initialize())
|
| {
|
| Print("Failed to initialize risk metrics");
|
| return false;
|
| }
|
|
|
| m_positionSizer = new CPositionSizer();
|
| if (m_positionSizer == NULL || !m_positionSizer.Initialize(m_riskParams, m_riskMetrics))
|
| {
|
| Print("Failed to initialize position sizer");
|
| return false;
|
| }
|
|
|
| m_drawdownMgr = new CDrawdownManager();
|
| if (m_drawdownMgr == NULL || !m_drawdownMgr.Initialize())
|
| {
|
| Print("Failed to initialize drawdown manager");
|
| return false;
|
| }
|
|
|
| m_corrMatrix = new CCorrelationMatrix();
|
| if (m_corrMatrix == NULL || !m_corrMatrix.Initialize())
|
| {
|
| Print("Failed to initialize correlation matrix");
|
| return false;
|
| }
|
|
|
| // Update account information
|
| UpdateAccountInfo();
|
|
|
| m_isInitialized = true;
|
| Print("Risk integration initialized successfully");
|
| return true;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Deinitialize risk integration |
|
| //+------------------------------------------------------------------+
|
| void CRiskIntegration::Deinitialize()
|
| {
|
| if (m_corrMatrix != NULL)
|
| {
|
| m_corrMatrix.Deinitialize();
|
| delete m_corrMatrix;
|
| m_corrMatrix = NULL;
|
| }
|
|
|
| if (m_drawdownMgr != NULL)
|
| {
|
| m_drawdownMgr.Deinitialize();
|
| delete m_drawdownMgr;
|
| m_drawdownMgr = NULL;
|
| }
|
|
|
| if (m_positionSizer != NULL)
|
| {
|
| m_positionSizer.Deinitialize();
|
| delete m_positionSizer;
|
| m_positionSizer = NULL;
|
| }
|
|
|
| if (m_riskMetrics != NULL)
|
| {
|
| m_riskMetrics.Deinitialize();
|
| delete m_riskMetrics;
|
| m_riskMetrics = NULL;
|
| }
|
|
|
| if (m_riskParams != NULL)
|
| {
|
| delete m_riskParams;
|
| m_riskParams = NULL;
|
| }
|
|
|
| m_isInitialized = false;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Update risk metrics and state |
|
| //+------------------------------------------------------------------+
|
| void CRiskIntegration::Update()
|
| {
|
| if (!m_isInitialized)
|
| return;
|
|
|
| // Update account information
|
| UpdateAccountInfo();
|
|
|
| // Update drawdown manager
|
| if (m_drawdownMgr != NULL)
|
| {
|
| m_drawdownMgr.UpdateEquity(m_accountEquity);
|
| }
|
|
|
| // Update correlation matrix periodically
|
| static datetime lastCorrelationUpdate = 0;
|
| if (TimeCurrent() - lastCorrelationUpdate >= 3600) // Update hourly
|
| {
|
| if (m_corrMatrix != NULL)
|
| {
|
| m_corrMatrix.Update();
|
| }
|
| lastCorrelationUpdate = TimeCurrent();
|
| }
|
|
|
| // Update risk metrics
|
| if (m_riskMetrics != NULL)
|
| {
|
| m_riskMetrics.Update();
|
| }
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Check if a position can be opened with the given parameters |
|
| //+------------------------------------------------------------------+
|
| bool CRiskIntegration::CanOpenPosition(const string symbol, const ENUM_ORDER_TYPE type,
|
| const double price, const double stopLoss,
|
| const double takeProfit, double &suggestedSize)
|
| {
|
| if (!m_isInitialized || symbol == "")
|
| return false;
|
|
|
| // Check if we're in a drawdown that exceeds limits
|
| if (m_drawdownMgr != NULL && m_riskParams != NULL)
|
| {
|
| if (m_drawdownMgr.IsDrawdownLimitReached(m_riskParams.GetMaxDrawdownPct()))
|
| {
|
| Print("Cannot open position: Maximum drawdown limit reached");
|
| return false;
|
| }
|
|
|
| if (m_drawdownMgr.IsDailyLossLimitReached(m_riskParams.GetMaxDailyLossPct()))
|
| {
|
| Print("Cannot open position: Daily loss limit reached");
|
| return false;
|
| }
|
| }
|
|
|
| // Calculate stop loss in pips
|
| double stopLossPips = 0.0;
|
| if (stopLoss > 0.0)
|
| {
|
| double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
|
| double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
|
|
|
| if (point > 0.0 && tickSize > 0.0)
|
| {
|
| if (type == ORDER_TYPE_BUY)
|
| stopLossPips = (price - stopLoss) / (point * 10.0);
|
| else
|
| stopLossPips = (stopLoss - price) / (point * 10.0);
|
|
|
| stopLossPips = MathMax(1.0, stopLossPips); // Ensure at least 1 pip
|
| }
|
| }
|
|
|
| // Get position size
|
| double riskPercent = (m_riskParams != NULL) ? m_riskParams.GetRiskPerTrade() : 1.0;
|
| double size = 0.0;
|
|
|
| if (m_positionSizer != NULL)
|
| {
|
| if (!m_positionSizer.CalculateSize(symbol, stopLossPips, riskPercent, m_accountEquity, size))
|
| {
|
| Print("Failed to calculate position size");
|
| return false;
|
| }
|
| }
|
|
|
| // Check correlation with existing positions
|
| if (m_corrMatrix != NULL && m_riskParams != NULL)
|
| {
|
| if (!m_corrMatrix.ValidateNewPosition(symbol, type, price, size))
|
| {
|
| Print("Cannot open position: Correlation limit exceeded");
|
| return false;
|
| }
|
| }
|
|
|
| // Check if size is within allowed limits
|
| if (!ValidatePositionSize(symbol, size))
|
| {
|
| return false;
|
| }
|
|
|
| suggestedSize = size;
|
| return true;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Validate if position size is within allowed limits |
|
| //+------------------------------------------------------------------+
|
| bool CRiskIntegration::ValidatePositionSize(const string symbol, const double size)
|
| {
|
| if (!m_isInitialized || symbol == "" || size <= 0.0)
|
| return false;
|
|
|
| // Check minimum position size
|
| double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
|
| if (size < minLot)
|
| {
|
| PrintFormat("Position size (%.2f) is below minimum (%.2f)", size, minLot);
|
| return false;
|
| }
|
|
|
| // Check maximum position size
|
| double maxLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
|
| if (maxLot > 0.0 && size > maxLot)
|
| {
|
| PrintFormat("Position size (%.2f) exceeds maximum (%.2f)", size, maxLot);
|
| return false;
|
| }
|
|
|
| // Check against risk parameters
|
| if (m_riskParams != NULL)
|
| {
|
| double maxLotsPerTrade = m_riskParams.GetMaxLotsPerTrade();
|
| if (maxLotsPerTrade > 0.0 && size > maxLotsPerTrade)
|
| {
|
| PrintFormat("Position size (%.2f) exceeds maximum per trade (%.2f)", size, maxLotsPerTrade);
|
| return false;
|
| }
|
|
|
| double maxRiskPerTrade = m_riskParams.GetMaxRiskPerTrade();
|
| if (maxRiskPerTrade > 0.0)
|
| {
|
| double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);
|
| double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
|
| double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
|
|
|
| if (tickValue > 0.0 && tickSize > 0.0 && point > 0.0)
|
| {
|
| double riskAmount = size * (tickValue / tickSize) * point * 10.0; // Risk per pip
|
| double maxRiskAmount = m_accountEquity * (maxRiskPerTrade / 100.0);
|
|
|
| if (riskAmount > maxRiskAmount)
|
| {
|
| PrintFormat("Position risk (%.2f) exceeds maximum risk per trade (%.2f)",
|
| riskAmount, maxRiskAmount);
|
| return false;
|
| }
|
| }
|
| }
|
| }
|
|
|
| return true;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Update position metrics |
|
| //+------------------------------------------------------------------+
|
| bool CRiskIntegration::UpdatePositionMetrics(const string symbol, const double size,
|
| const double openPrice, const double currentPrice)
|
| {
|
| if (!m_isInitialized || symbol == "" || size <= 0.0 || openPrice <= 0.0)
|
| return false;
|
|
|
| // Update risk metrics with the new position
|
| if (m_riskMetrics != NULL)
|
| {
|
| // This is a simplified example - in practice, you would update all relevant metrics
|
| double pips = (currentPrice - openPrice) / (SymbolInfoDouble(symbol, SYMBOL_POINT) * 10.0);
|
| m_riskMetrics.UpdateTradeMetrics(pips > 0, MathAbs(pips));
|
| }
|
|
|
| return true;
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Get maximum allowed position size based on risk parameters |
|
| //+------------------------------------------------------------------
|
| double CRiskIntegration::GetMaxPositionSize()
|
| {
|
| if (!m_isInitialized || m_riskParams == NULL)
|
| return 0.0;
|
|
|
| return m_riskParams.GetMaxLotsPerTrade();
|
| }
|
|
|
| //+------------------------------------------------------------------+
|
| //| Update account information |
|
| //+------------------------------------------------------------------+
|
| void CRiskIntegration::UpdateAccountInfo()
|
| {
|
| m_accountEquity = AccountInfoDouble(ACCOUNT_EQUITY);
|
|
|
| // Update risk metrics with new equity
|
| if (m_riskMetrics != NULL)
|
| {
|
| m_riskMetrics.UpdateEquity(m_accountEquity);
|
| }
|
| }
|