mql5/Shared Projects/ERMT-ML/Modules-ML8x/Dashboard_v71.mqh
darashikoh 0fb1bd1b0a 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

770 lines
No EOL
31 KiB
MQL5

//+------------------------------------------------------------------+
//| 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