mql5/Shared Projects/ERMT-ML/Modules-ML8x/Dashboard_v71.mqh

770 lines
31 KiB
MQL5
Raw Permalink Normal View History

Module Integration Summary for External Trade Management Overview To fully integrate the enhanced external trade management system, updates are required to 5 out of 7 existing modules. The updates maintain backward compatibility while adding new functionality for external trade handling. Module Update Requirements 🟢 No Updates Required (2 modules) TechnicalAnalysis.mqh - Already provides necessary calculations EntrySystem.mqh - Only handles EA's own entry signals 🟡 Minor Updates (2 modules) DataTypes.mqh - Add external trade structures and fields Utilities.mqh - Enhanced logging for external trades 🟠 Moderate Updates (3 modules) RiskManager.mqh - Enhanced risk enforcement methods TradeManager.mqh - Improved stop management for externals Dashboard.mqh - Display external trade information Integration Steps Phase 1: Data Structures (DataTypes.mqh) Add ENUM_EXTERNAL_STATUS enumeration Extend ManagedTrade structure with external-specific fields Add ExternalTradeStats structure for metrics Update DashboardConfig with show_external flag Key additions: external_status - Track state of external trade source_name - Identify where trade came from stops_modified - Track if we modified the trade original_sl/tp - Store original values for comparison Phase 2: Risk Management (RiskManager.mqh) Add EnforceRiskRulesEnhanced() method Implement GetExternalExposure() for risk aggregation Add UpdateExternalStats() for tracking Enhance ValidateAndAdjustRiskExternal() method Key features: Separate risk calculation for external trades Cache mechanism for performance Statistical tracking of external positions Smart risk adjustment without closing trades Phase 3: Trade Management (TradeManager.mqh) Add ApplyDefaultStopsEnhanced() with better logic Implement OverrideExternalStops() with smart override Create ManageExternalTrade() with different rules Add ApplyBreakevenExternal() with wider triggers Key features: Smart stop override (only improve, never worsen) Different management rules for external trades Respect minimum broker distances Track modification success/failure rates Phase 4: User Interface (Dashboard.mqh) Add CreateExternalSection() for display area Implement UpdateExternalSection() for real-time updates Add SetCustomText() for flexible display Create ShowExternalTrades() toggle method Key features: Real-time external trade count and risk Color-coded risk warnings List of active external positions Modification statistics display Phase 5: Logging (Utilities.mqh) Add LogExternalTrade() for detailed event logging Create separate CSV log for external trades Enhance GenerateReportEnhanced() with external section Add IdentifyTradeSource() for magic number interpretation Key features: Separate CSV log for external trade events Detailed tracking of all modifications Source identification from magic numbers Enhanced reporting with external statistics
2025-08-27 14:21:02 +01:00
//+------------------------------------------------------------------+
//| Dashboard_v71.mqh |
//| Institutional Grade Dashboard Module v7.1 |
//| Real-time Analytics, Risk Metrics, Performance |
//+------------------------------------------------------------------+
#ifndef DASHBOARD_V71_MQH
#define DASHBOARD_V71_MQH
#include "DataTypes_v71.mqh"
#include <ChartObjects/ChartObjectsTxtControls.mqh>
#include <ChartObjects/ChartObjectsShapes.mqh>
//+------------------------------------------------------------------+
//| Dashboard Layout |
//+------------------------------------------------------------------+
struct DashboardLayout
{
int x_start;
int y_start;
int width;
int height;
int panel_width;
int panel_height;
int row_height;
int column_width;
color bg_color;
color text_color;
color profit_color;
color loss_color;
color warning_color;
string font_name;
int font_size;
};
//+------------------------------------------------------------------+
//| Dashboard Panel |
//+------------------------------------------------------------------+
struct DashboardPanel
{
string name;
int x;
int y;
int width;
int height;
bool is_visible;
string objects[];
};
//+------------------------------------------------------------------+
//| Dashboard Class - Institutional Grade |
//+------------------------------------------------------------------+
class CDashboardV71
{
private:
//--- Layout configuration
DashboardLayout m_layout;
//--- Panels
DashboardPanel m_panel_account;
DashboardPanel m_panel_performance;
DashboardPanel m_panel_risk;
DashboardPanel m_panel_positions;
DashboardPanel m_panel_execution;
DashboardPanel m_panel_correlation;
//--- Object prefix
string m_prefix;
//--- Update tracking
datetime m_last_update;
int m_update_counter;
//--- Visualization options
bool m_show_var_metrics;
bool m_show_greek_letters;
bool m_show_execution_stats;
bool m_show_ml_confidence;
bool m_show_correlation_map;
//--- Helper methods
void CreatePanel(DashboardPanel &panel, string title);
void CreateLabel(string name, int x, int y, string text,
color clr = clrWhite, int size = 0);
void CreateValue(string name, int x, int y, string text,
color clr = clrWhite, int size = 0);
void CreateRectangle(string name, int x, int y, int width,
int height, color clr);
void CreateProgressBar(string name, int x, int y, int width,
double value, double max_value);
void CreateHeatMap(string name, int x, int y, double &matrix[][]);
color GetGradientColor(double value, double min_val, double max_val);
string FormatLargeNumber(double value);
void UpdateObject(string name, string text, color clr = WRONG_VALUE);
void DeletePanel(DashboardPanel &panel);
public:
CDashboardV71();
~CDashboardV71();
//--- Initialization
bool Create(int x, int y, color bg_color = C'20,20,20',
color profit_color = clrLime, color loss_color = clrRed);
bool CreateInstitutional(int x, int y);
void Destroy();
//--- Updates
void Update(PerformanceMetrics &performance, ManagedTrade &trades[],
MarketConditions &conditions);
void UpdateInstitutional(PerformanceMetricsV71 &performance,
SystemStateV71 &state, ExecutionMetrics &execution);
//--- Panel updates
void UpdateAccountPanel(double balance, double equity, double margin_level);
void UpdatePerformancePanel(PerformanceMetricsV71 &performance);
void UpdateRiskPanel(SystemStateV71 &state);
void UpdatePositionsPanel(ManagedTradeV71 &trades[]);
void UpdateExecutionPanel(ExecutionMetrics &execution);
void UpdateCorrelationPanel(CorrelationMatrix &correlations);
//--- Real-time metrics
void UpdateVaRMetrics(double var, double cvar, double stress_var);
void UpdateGreeks(double delta, double gamma, double vega, double theta);
void UpdateMLConfidence(double confidence, string model_status);
void UpdateOrderFlow(double imbalance, double vpin, double liquidity);
//--- Alerts and warnings
void ShowAlert(string message, color alert_color = clrYellow);
void ShowRiskWarning(string risk_type, double level);
void ClearAlerts();
//--- Configuration
void SetVisualizationOptions(bool show_var, bool show_greeks,
bool show_exec, bool show_ml, bool show_corr);
void SetUpdateFrequency(int milliseconds);
void TogglePanel(string panel_name);
//--- Export
void Screenshot(string filename);
void ExportMetrics(string filename);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CDashboardV71::CDashboardV71()
{
m_prefix = "DASHBOARD_V71_";
m_last_update = 0;
m_update_counter = 0;
m_show_var_metrics = true;
m_show_greek_letters = false;
m_show_execution_stats = true;
m_show_ml_confidence = true;
m_show_correlation_map = false;
//--- Default layout
m_layout.width = 400;
m_layout.height = 800;
m_layout.panel_width = 380;
m_layout.panel_height = 150;
m_layout.row_height = 20;
m_layout.column_width = 100;
m_layout.bg_color = C'20,20,20';
m_layout.text_color = clrWhite;
m_layout.profit_color = clrLime;
m_layout.loss_color = clrRed;
m_layout.warning_color = clrYellow;
m_layout.font_name = "Consolas";
m_layout.font_size = 9;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CDashboardV71::~CDashboardV71()
{
Destroy();
}
//+------------------------------------------------------------------+
//| Create institutional dashboard |
//+------------------------------------------------------------------+
bool CDashboardV71::CreateInstitutional(int x, int y)
{
m_layout.x_start = x;
m_layout.y_start = y;
//--- Create main background
CreateRectangle(m_prefix + "MAIN_BG", x, y, m_layout.width, m_layout.height, m_layout.bg_color);
//--- Create title
CreateLabel(m_prefix + "TITLE", x + 10, y + 10, "ERMT 7.1 - INSTITUTIONAL DASHBOARD",
m_layout.text_color, 12);
int current_y = y + 40;
//--- Account panel
m_panel_account.name = "ACCOUNT";
m_panel_account.x = x + 10;
m_panel_account.y = current_y;
m_panel_account.width = m_layout.panel_width;
m_panel_account.height = 80;
CreatePanel(m_panel_account, "ACCOUNT METRICS");
current_y += 90;
//--- Performance panel
m_panel_performance.name = "PERFORMANCE";
m_panel_performance.x = x + 10;
m_panel_performance.y = current_y;
m_panel_performance.width = m_layout.panel_width;
m_panel_performance.height = 120;
CreatePanel(m_panel_performance, "PERFORMANCE ANALYTICS");
current_y += 130;
//--- Risk panel
m_panel_risk.name = "RISK";
m_panel_risk.x = x + 10;
m_panel_risk.y = current_y;
m_panel_risk.width = m_layout.panel_width;
m_panel_risk.height = 140;
CreatePanel(m_panel_risk, "RISK METRICS");
current_y += 150;
//--- Positions panel
m_panel_positions.name = "POSITIONS";
m_panel_positions.x = x + 10;
m_panel_positions.y = current_y;
m_panel_positions.width = m_layout.panel_width;
m_panel_positions.height = 160;
CreatePanel(m_panel_positions, "ACTIVE POSITIONS");
current_y += 170;
//--- Execution panel
if(m_show_execution_stats)
{
m_panel_execution.name = "EXECUTION";
m_panel_execution.x = x + 10;
m_panel_execution.y = current_y;
m_panel_execution.width = m_layout.panel_width;
m_panel_execution.height = 100;
CreatePanel(m_panel_execution, "EXECUTION QUALITY");
current_y += 110;
}
//--- Update timestamp
CreateLabel(m_prefix + "TIMESTAMP", x + 10, m_layout.y_start + m_layout.height - 20,
"Last Update: " + TimeToString(TimeCurrent()), clrGray, 8);
return true;
}
//+------------------------------------------------------------------+
//| Create panel |
//+------------------------------------------------------------------+
void CDashboardV71::CreatePanel(DashboardPanel &panel, string title)
{
string base_name = m_prefix + panel.name + "_";
//--- Panel background
CreateRectangle(base_name + "BG", panel.x, panel.y, panel.width, panel.height, C'30,30,30');
//--- Panel border
CreateRectangle(base_name + "BORDER", panel.x, panel.y, panel.width, 2, C'50,50,50');
//--- Panel title
CreateLabel(base_name + "TITLE", panel.x + 5, panel.y + 5, title, clrCyan, 10);
panel.is_visible = true;
}
//+------------------------------------------------------------------+
//| Update institutional dashboard |
//+------------------------------------------------------------------+
void CDashboardV71::UpdateInstitutional(PerformanceMetricsV71 &performance,
SystemStateV71 &state, ExecutionMetrics &execution)
{
//--- Update account panel
UpdateAccountPanel(AccountInfoDouble(ACCOUNT_BALANCE),
AccountInfoDouble(ACCOUNT_EQUITY),
AccountInfoDouble(ACCOUNT_MARGIN_LEVEL));
//--- Update performance panel
UpdatePerformancePanel(performance);
//--- Update risk panel
UpdateRiskPanel(state);
//--- Update execution panel
if(m_show_execution_stats)
UpdateExecutionPanel(execution);
//--- Update timestamp
UpdateObject(m_prefix + "TIMESTAMP",
"Updated: " + TimeToString(TimeCurrent(), TIME_SECONDS), clrGray);
m_last_update = TimeCurrent();
m_update_counter++;
}
//+------------------------------------------------------------------+
//| Update account panel |
//+------------------------------------------------------------------+
void CDashboardV71::UpdateAccountPanel(double balance, double equity, double margin_level)
{
string base = m_prefix + "ACCOUNT_";
int x = m_panel_account.x + 10;
int y = m_panel_account.y + 25;
//--- Balance
CreateLabel(base + "BAL_LBL", x, y, "Balance:", m_layout.text_color);
CreateValue(base + "BAL_VAL", x + 100, y, FormatLargeNumber(balance), m_layout.text_color);
//--- Equity
y += m_layout.row_height;
CreateLabel(base + "EQ_LBL", x, y, "Equity:", m_layout.text_color);
color eq_color = (equity >= balance) ? m_layout.profit_color : m_layout.loss_color;
CreateValue(base + "EQ_VAL", x + 100, y, FormatLargeNumber(equity), eq_color);
//--- Margin Level
y += m_layout.row_height;
CreateLabel(base + "ML_LBL", x, y, "Margin Lvl:", m_layout.text_color);
color ml_color = (margin_level > 200) ? m_layout.profit_color :
(margin_level > 100) ? m_layout.warning_color : m_layout.loss_color;
string ml_text = (margin_level > 0) ? DoubleToString(margin_level, 1) + "%" : "N/A";
CreateValue(base + "ML_VAL", x + 100, y, ml_text, ml_color);
//--- Floating P/L
double floating_pl = equity - balance;
CreateLabel(base + "PL_LBL", x + 200, y - m_layout.row_height * 2, "Float P/L:", m_layout.text_color);
color pl_color = (floating_pl >= 0) ? m_layout.profit_color : m_layout.loss_color;
CreateValue(base + "PL_VAL", x + 280, y - m_layout.row_height * 2,
FormatLargeNumber(floating_pl), pl_color);
}
//+------------------------------------------------------------------+
//| Update performance panel |
//+------------------------------------------------------------------+
void CDashboardV71::UpdatePerformancePanel(PerformanceMetricsV71 &performance)
{
string base = m_prefix + "PERFORMANCE_";
int x = m_panel_performance.x + 10;
int y = m_panel_performance.y + 25;
//--- Row 1: Win Rate & Profit Factor
CreateLabel(base + "WR_LBL", x, y, "Win Rate:", m_layout.text_color);
color wr_color = (performance.win_rate > 50) ? m_layout.profit_color : m_layout.loss_color;
CreateValue(base + "WR_VAL", x + 80, y, DoubleToString(performance.win_rate, 1) + "%", wr_color);
CreateLabel(base + "PF_LBL", x + 190, y, "Prof Factor:", m_layout.text_color);
color pf_color = (performance.profit_factor > 1.0) ? m_layout.profit_color : m_layout.loss_color;
CreateValue(base + "PF_VAL", x + 280, y, DoubleToString(performance.profit_factor, 2), pf_color);
//--- Row 2: Sharpe & Sortino
y += m_layout.row_height;
CreateLabel(base + "SR_LBL", x, y, "Sharpe:", m_layout.text_color);
color sr_color = (performance.sharpe_ratio > 1.0) ? m_layout.profit_color :
(performance.sharpe_ratio > 0) ? m_layout.text_color : m_layout.loss_color;
CreateValue(base + "SR_VAL", x + 80, y, DoubleToString(performance.sharpe_ratio, 2), sr_color);
CreateLabel(base + "SO_LBL", x + 190, y, "Sortino:", m_layout.text_color);
CreateValue(base + "SO_VAL", x + 280, y, DoubleToString(performance.sortino_ratio, 2), sr_color);
//--- Row 3: Information Ratio & Hit Rate
y += m_layout.row_height;
CreateLabel(base + "IR_LBL", x, y, "Info Ratio:", m_layout.text_color);
CreateValue(base + "IR_VAL", x + 80, y, DoubleToString(performance.information_ratio, 2), m_layout.text_color);
CreateLabel(base + "HR_LBL", x + 190, y, "Hit Rate:", m_layout.text_color);
CreateValue(base + "HR_VAL", x + 280, y, DoubleToString(performance.hit_rate, 1) + "%", m_layout.text_color);
//--- Row 4: Max DD & Recovery
y += m_layout.row_height;
CreateLabel(base + "DD_LBL", x, y, "Max DD:", m_layout.text_color);
CreateValue(base + "DD_VAL", x + 80, y, DoubleToString(performance.max_drawdown_percent, 1) + "%", m_layout.loss_color);
CreateLabel(base + "RF_LBL", x + 190, y, "Recovery:", m_layout.text_color);
CreateValue(base + "RF_VAL", x + 280, y, DoubleToString(performance.recovery_factor, 2), m_layout.text_color);
}
//+------------------------------------------------------------------+
//| Update risk panel |
//+------------------------------------------------------------------+
void CDashboardV71::UpdateRiskPanel(SystemStateV71 &state)
{
string base = m_prefix + "RISK_";
int x = m_panel_risk.x + 10;
int y = m_panel_risk.y + 25;
//--- VaR Metrics
if(m_show_var_metrics)
{
CreateLabel(base + "VAR_LBL", x, y, "VaR (95%):", m_layout.text_color);
color var_color = (state.current_var < 2.0) ? m_layout.profit_color :
(state.current_var < 3.0) ? m_layout.warning_color : m_layout.loss_color;
CreateValue(base + "VAR_VAL", x + 80, y, DoubleToString(state.current_var, 2) + "%", var_color);
CreateLabel(base + "CVAR_LBL", x + 190, y, "CVaR:", m_layout.text_color);
CreateValue(base + "CVAR_VAL", x + 280, y, DoubleToString(state.current_cvar, 2) + "%", var_color);
y += m_layout.row_height;
}
//--- Portfolio Beta
CreateLabel(base + "BETA_LBL", x, y, "Beta:", m_layout.text_color);
color beta_color = (MathAbs(state.portfolio_beta) < 1.0) ? m_layout.text_color : m_layout.warning_color;
CreateValue(base + "BETA_VAL", x + 80, y, DoubleToString(state.portfolio_beta, 2), beta_color);
//--- Real-time Sharpe
CreateLabel(base + "RTS_LBL", x + 190, y, "RT Sharpe:", m_layout.text_color);
CreateValue(base + "RTS_VAL", x + 280, y, DoubleToString(state.sharpe_real_time, 2), m_layout.text_color);
//--- Risk Score
y += m_layout.row_height;
CreateLabel(base + "RISK_SCORE_LBL", x, y, "Risk Score:", m_layout.text_color);
color risk_color = RiskScoreToColor(state.risk_score);
CreateValue(base + "RISK_SCORE_VAL", x + 80, y, IntegerToString(state.risk_score) + "/100", risk_color);
//--- Risk Score Bar
CreateProgressBar(base + "RISK_BAR", x, y + 20, 350, state.risk_score, 100);
//--- Max Correlation
y += m_layout.row_height + 25;
CreateLabel(base + "CORR_LBL", x, y, "Max Correlation:", m_layout.text_color);
color corr_color = (state.max_position_correlation < 0.7) ? m_layout.text_color : m_layout.warning_color;
CreateValue(base + "CORR_VAL", x + 120, y, DoubleToString(state.max_position_correlation, 2), corr_color);
}
//+------------------------------------------------------------------+
//| Update positions panel |
//+------------------------------------------------------------------+
void CDashboardV71::UpdatePositionsPanel(ManagedTradeV71 &trades[])
{
string base = m_prefix + "POSITIONS_";
int x = m_panel_positions.x + 10;
int y = m_panel_positions.y + 25;
int trade_count = ArraySize(trades);
int display_count = MathMin(trade_count, 6); // Show max 6 positions
//--- Header
CreateLabel(base + "HDR", x, y,
"Symbol Dir Vol P/L Risk R-Mult", clrCyan, 8);
y += 15;
//--- Position details
for(int i = 0; i < display_count; i++)
{
string row_base = base + "ROW_" + IntegerToString(i) + "_";
//--- Symbol
CreateLabel(row_base + "SYM", x, y, trades[i].symbol, m_layout.text_color, 8);
//--- Direction
string dir = (trades[i].type == POSITION_TYPE_BUY) ? "BUY" : "SELL";
color dir_color = (trades[i].type == POSITION_TYPE_BUY) ? clrDodgerBlue : clrOrangeRed;
CreateLabel(row_base + "DIR", x + 60, y, dir, dir_color, 8);
//--- Volume
CreateLabel(row_base + "VOL", x + 100, y, DoubleToString(trades[i].volume, 2), m_layout.text_color, 8);
//--- P/L
color pl_color = (trades[i].profit >= 0) ? m_layout.profit_color : m_layout.loss_color;
CreateLabel(row_base + "PL", x + 150, y, DoubleToString(trades[i].profit, 0), pl_color, 8);
//--- Risk
CreateLabel(row_base + "RISK", x + 220, y, DoubleToString(trades[i].risk_percent, 1) + "%", m_layout.text_color, 8);
//--- R-Multiple
color r_color = (trades[i].r_multiple >= 0) ? m_layout.profit_color : m_layout.loss_color;
CreateLabel(row_base + "R", x + 280, y, DoubleToString(trades[i].r_multiple, 1) + "R", r_color, 8);
y += 15;
}
//--- Summary
if(trade_count > 0)
{
y += 5;
double total_risk = 0;
double total_profit = 0;
for(int i = 0; i < trade_count; i++)
{
total_risk += trades[i].risk_percent;
total_profit += trades[i].profit;
}
CreateLabel(base + "SUMM", x, y,
"Total: " + IntegerToString(trade_count) + " positions, " +
"Risk: " + DoubleToString(total_risk, 1) + "%, " +
"P/L: " + DoubleToString(total_profit, 0),
m_layout.text_color, 9);
}
else
{
CreateLabel(base + "EMPTY", x, y, "No active positions", clrGray);
}
}
//+------------------------------------------------------------------+
//| Update execution panel |
//+------------------------------------------------------------------+
void CDashboardV71::UpdateExecutionPanel(ExecutionMetrics &execution)
{
string base = m_prefix + "EXECUTION_";
int x = m_panel_execution.x + 10;
int y = m_panel_execution.y + 25;
//--- Average Slippage
CreateLabel(base + "SLIP_LBL", x, y, "Avg Slippage:", m_layout.text_color);
color slip_color = (execution.avg_slippage < 0) ? m_layout.profit_color : // Negative = price improvement
(execution.avg_slippage < 1) ? m_layout.text_color : m_layout.loss_color;
CreateValue(base + "SLIP_VAL", x + 100, y, DoubleToString(execution.avg_slippage, 2) + " pips", slip_color);
//--- Fill Rate
CreateLabel(base + "FILL_LBL", x + 200, y, "Fill Rate:", m_layout.text_color);
double fill_rate = (execution.fills_count > 0) ?
(double)(execution.fills_count - execution.rejected_orders) / execution.fills_count * 100 : 0;
CreateValue(base + "FILL_VAL", x + 280, y, DoubleToString(fill_rate, 1) + "%", m_layout.text_color);
//--- Positive Slippage Rate
y += m_layout.row_height;
CreateLabel(base + "POS_LBL", x, y, "Pos Slip Rate:", m_layout.text_color);
CreateValue(base + "POS_VAL", x + 100, y, DoubleToString(execution.positive_slippage_rate * 100, 1) + "%", m_layout.text_color);
//--- Average Fill Time
CreateLabel(base + "TIME_LBL", x + 200, y, "Fill Time:", m_layout.text_color);
CreateValue(base + "TIME_VAL", x + 280, y, DoubleToString(execution.avg_fill_time_ms, 0) + " ms", m_layout.text_color);
//--- VWAP Tracking Error
if(execution.vwap_tracking_error != 0)
{
y += m_layout.row_height;
CreateLabel(base + "VWAP_LBL", x, y, "VWAP Error:", m_layout.text_color);
CreateValue(base + "VWAP_VAL", x + 100, y, DoubleToString(execution.vwap_tracking_error, 3), m_layout.text_color);
}
}
//+------------------------------------------------------------------+
//| Create label object |
//+------------------------------------------------------------------+
void CDashboardV71::CreateLabel(string name, int x, int y, string text, color clr, int size)
{
if(ObjectFind(0, name) >= 0)
{
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
}
else
{
ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetString(0, name, OBJPROP_TEXT, text);
ObjectSetString(0, name, OBJPROP_FONT, m_layout.font_name);
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, (size > 0) ? size : m_layout.font_size);
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
}
}
//+------------------------------------------------------------------+
//| Create value object (right-aligned) |
//+------------------------------------------------------------------+
void CDashboardV71::CreateValue(string name, int x, int y, string text, color clr, int size)
{
CreateLabel(name, x, y, text, clr, size);
}
//+------------------------------------------------------------------+
//| Create rectangle object |
//+------------------------------------------------------------------+
void CDashboardV71::CreateRectangle(string name, int x, int y, int width, int height, color clr)
{
if(ObjectFind(0, name) < 0)
{
ObjectCreate(0, name, OBJ_RECTANGLE_LABEL, 0, 0, 0);
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
ObjectSetInteger(0, name, OBJPROP_XSIZE, width);
ObjectSetInteger(0, name, OBJPROP_YSIZE, height);
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clr);
ObjectSetInteger(0, name, OBJPROP_BORDER_TYPE, BORDER_FLAT);
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, name, OBJPROP_WIDTH, 0);
ObjectSetInteger(0, name, OBJPROP_BACK, true);
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
}
}
//+------------------------------------------------------------------+
//| Create progress bar |
//+------------------------------------------------------------------+
void CDashboardV71::CreateProgressBar(string name, int x, int y, int width, double value, double max_value)
{
//--- Background
CreateRectangle(name + "_BG", x, y, width, 10, C'40,40,40');
//--- Fill
int fill_width = (int)(width * value / max_value);
color fill_color = GetGradientColor(value, 0, max_value);
CreateRectangle(name + "_FILL", x, y, fill_width, 10, fill_color);
}
//+------------------------------------------------------------------+
//| Get gradient color based on value |
//+------------------------------------------------------------------+
color CDashboardV71::GetGradientColor(double value, double min_val, double max_val)
{
double ratio = (value - min_val) / (max_val - min_val);
ratio = MathMax(0, MathMin(1, ratio));
//--- Green to Red gradient
int r = (int)(255 * ratio);
int g = (int)(255 * (1 - ratio));
int b = 0;
return StringToColor(StringFormat("%d,%d,%d", r, g, b));
}
//+------------------------------------------------------------------+
//| Format large numbers |
//+------------------------------------------------------------------+
string CDashboardV71::FormatLargeNumber(double value)
{
if(MathAbs(value) >= 1000000)
return DoubleToString(value / 1000000, 2) + "M";
else if(MathAbs(value) >= 1000)
return DoubleToString(value / 1000, 2) + "K";
else
return DoubleToString(value, 2);
}
//+------------------------------------------------------------------+
//| Update object text and color |
//+------------------------------------------------------------------+
void CDashboardV71::UpdateObject(string name, string text, color clr)
{
if(ObjectFind(0, name) >= 0)
{
ObjectSetString(0, name, OBJPROP_TEXT, text);
if(clr != WRONG_VALUE)
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
}
}
//+------------------------------------------------------------------+
//| Update VaR metrics display |
//+------------------------------------------------------------------+
void CDashboardV71::UpdateVaRMetrics(double var, double cvar, double stress_var)
{
string base = m_prefix + "VAR_METRICS_";
int x = m_panel_risk.x + 10;
int y = m_panel_risk.y + 100;
CreateLabel(base + "TITLE", x, y, "Value at Risk Analysis", clrCyan, 10);
y += 20;
//--- VaR
CreateLabel(base + "VAR_LBL", x, y, "VaR (95%):", m_layout.text_color);
color var_color = (var < 2.0) ? m_layout.profit_color :
(var < 3.0) ? m_layout.warning_color : m_layout.loss_color;
CreateValue(base + "VAR_VAL", x + 100, y, DoubleToString(var, 2) + "%", var_color);
//--- CVaR
y += m_layout.row_height;
CreateLabel(base + "CVAR_LBL", x, y, "CVaR (95%):", m_layout.text_color);
CreateValue(base + "CVAR_VAL", x + 100, y, DoubleToString(cvar, 2) + "%", var_color);
//--- Stressed VaR
y += m_layout.row_height;
CreateLabel(base + "SVAR_LBL", x, y, "Stressed VaR:", m_layout.text_color);
color svar_color = (stress_var < 5.0) ? m_layout.warning_color : m_layout.loss_color;
CreateValue(base + "SVAR_VAL", x + 100, y, DoubleToString(stress_var, 2) + "%", svar_color);
}
//+------------------------------------------------------------------+
//| Show alert message |
//+------------------------------------------------------------------+
void CDashboardV71::ShowAlert(string message, color alert_color)
{
string name = m_prefix + "ALERT";
int x = m_layout.x_start + 10;
int y = m_layout.y_start + m_layout.height - 50;
//--- Alert background
CreateRectangle(name + "_BG", x, y, m_layout.panel_width, 30, C'50,20,20');
//--- Alert text
CreateLabel(name + "_TEXT", x + 5, y + 5, "" + message, alert_color, 10);
}
//+------------------------------------------------------------------+
//| Clear all alerts |
//+------------------------------------------------------------------+
void CDashboardV71::ClearAlerts()
{
ObjectDelete(0, m_prefix + "ALERT_BG");
ObjectDelete(0, m_prefix + "ALERT_TEXT");
}
//+------------------------------------------------------------------+
//| Destroy dashboard |
//+------------------------------------------------------------------+
void CDashboardV71::Destroy()
{
//--- Delete all objects with prefix
int total = ObjectsTotal(0);
for(int i = total - 1; i >= 0; i--)
{
string obj_name = ObjectName(0, i);
if(StringFind(obj_name, m_prefix) == 0)
ObjectDelete(0, obj_name);
}
ChartRedraw();
}
//+------------------------------------------------------------------+
//| Create standard dashboard (compatibility) |
//+------------------------------------------------------------------+
bool CDashboardV71::Create(int x, int y, color bg_color, color profit_color, color loss_color)
{
m_layout.bg_color = bg_color;
m_layout.profit_color = profit_color;
m_layout.loss_color = loss_color;
return CreateInstitutional(x, y);
}
//+------------------------------------------------------------------+
//| Update standard dashboard (compatibility) |
//+------------------------------------------------------------------+
void CDashboardV71::Update(PerformanceMetrics &performance, ManagedTrade &trades[],
MarketConditions &conditions)
{
//--- Convert to V71 structures and update
PerformanceMetricsV71 perf_v71;
//--- Copy basic metrics
perf_v71.total_trades = performance.total_trades;
perf_v71.winning_trades = performance.winning_trades;
perf_v71.losing_trades = performance.losing_trades;
perf_v71.gross_profit = performance.gross_profit;
perf_v71.gross_loss = performance.gross_loss;
perf_v71.net_profit = performance.net_profit;
perf_v71.profit_factor = performance.profit_factor;
perf_v71.win_rate = performance.win_rate;
perf_v71.sharpe_ratio = performance.sharpe_ratio;
perf_v71.max_drawdown_percent = performance.max_drawdown_percent;
SystemStateV71 state;
state.current_var = 0;
state.current_cvar = 0;
state.portfolio_beta = 0;
state.sharpe_real_time = performance.sharpe_ratio;
state.risk_score = 50;
ExecutionMetrics exec;
exec.avg_slippage = 0;
exec.positive_slippage_rate = 0;
exec.avg_fill_time_ms = 10;
exec.fills_count = performance.total_trades;
exec.rejected_orders = 0;
UpdateInstitutional(perf_v71, state, exec);
}
#endif // DASHBOARD_V71_MQH