//+------------------------------------------------------------------+ //| UnifiedDashboard.mqh - Professional Trading Dashboard | //| Single, Efficient Dashboard for Revolutionary AI EA | //+------------------------------------------------------------------+ #ifndef UNIFIED_DASHBOARD_MQH #define UNIFIED_DASHBOARD_MQH #include #include class UnifiedDashboard { private: string m_symbol; string m_prefix; int m_x_pos; int m_y_pos; int m_width; int m_height; // Performance tracking double m_daily_start_balance; int m_total_trades; int m_winning_trades; datetime m_session_start; // Display state bool m_initialized; datetime m_last_update; public: UnifiedDashboard(void); ~UnifiedDashboard(void); // Core methods bool Initialize(string symbol, int x_pos = 20, int y_pos = 50); void UpdateLive(void); void UpdateAnalysis(AIAnalysisResult &ai_result, IndicatorSignal &tech_signal); void UpdateTrade(string signal, double lot_size, double price, double confidence); void Destroy(void); private: // Dashboard creation void CreateBackground(void); void CreateHeader(void); void CreateStatusSection(void); void CreateAnalysisSection(void); void CreatePerformanceSection(void); // Update methods void UpdateStatus(void); void UpdatePerformance(void); // Utility methods void CreateLabel(string name, string text, int x, int y, color clr = clrWhite, int size = 9); void CreateRectangle(string name, int x, int y, int width, int height, color bg_color); string FormatMoney(double amount); string FormatPercent(double percent); color GetSignalColor(string signal); void CleanupObjects(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ UnifiedDashboard::UnifiedDashboard(void) { m_symbol = ""; m_prefix = "RevAI_Dashboard_"; m_x_pos = 20; m_y_pos = 50; m_width = 320; m_height = 400; m_initialized = false; m_last_update = 0; m_daily_start_balance = 0; m_total_trades = 0; m_winning_trades = 0; m_session_start = TimeCurrent(); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ UnifiedDashboard::~UnifiedDashboard(void) { Destroy(); } //+------------------------------------------------------------------+ //| Initialize dashboard | //+------------------------------------------------------------------+ bool UnifiedDashboard::Initialize(string symbol, int x_pos = 20, int y_pos = 50) { m_symbol = symbol; m_x_pos = x_pos; m_y_pos = y_pos; m_prefix = "RevAI_" + m_symbol + "_"; m_daily_start_balance = AccountInfoDouble(ACCOUNT_BALANCE); // Create dashboard components CreateBackground(); CreateHeader(); CreateStatusSection(); CreateAnalysisSection(); CreatePerformanceSection(); m_initialized = true; ChartRedraw(); Print("✅ Unified Dashboard initialized for ", m_symbol); return true; } //+------------------------------------------------------------------+ //| Update dashboard with live data (called every tick) | //+------------------------------------------------------------------+ void UnifiedDashboard::UpdateLive(void) { if (!m_initialized) return; // Update only essential info every 5 seconds to avoid lag datetime current_time = TimeCurrent(); if (current_time - m_last_update < 5) return; UpdateStatus(); UpdatePerformance(); m_last_update = current_time; ChartRedraw(); } //+------------------------------------------------------------------+ //| Update analysis section | //+------------------------------------------------------------------+ void UnifiedDashboard::UpdateAnalysis(AIAnalysisResult &ai_result, IndicatorSignal &tech_signal) { if (!m_initialized) return; // AI Analysis ObjectSetString(0, m_prefix + "ai_signal", OBJPROP_TEXT, "AI Signal: " + (ai_result.signal == AI_SIGNAL_BUY ? "BUY" : ai_result.signal == AI_SIGNAL_SELL ? "SELL" : "HOLD")); ObjectSetInteger(0, m_prefix + "ai_signal", OBJPROP_COLOR, ai_result.signal == AI_SIGNAL_BUY ? clrLimeGreen : ai_result.signal == AI_SIGNAL_SELL ? clrOrangeRed : clrYellow); ObjectSetString(0, m_prefix + "ai_confidence", OBJPROP_TEXT, "AI Confidence: " + DoubleToString(ai_result.confidence, 1) + "%"); ObjectSetString(0, m_prefix + "market_regime", OBJPROP_TEXT, "Market: " + ai_result.market_regime); // Technical Analysis string tech_signal_text = "Tech Signal: " + (tech_signal.signal == SIGNAL_BUY ? "BUY" : tech_signal.signal == SIGNAL_SELL ? "SELL" : "NEUTRAL"); ObjectSetString(0, m_prefix + "tech_signal", OBJPROP_TEXT, tech_signal_text); ObjectSetInteger(0, m_prefix + "tech_signal", OBJPROP_COLOR, tech_signal.signal == SIGNAL_BUY ? clrLimeGreen : tech_signal.signal == SIGNAL_SELL ? clrOrangeRed : clrGray); ObjectSetString(0, m_prefix + "tech_strength", OBJPROP_TEXT, "Tech Strength: " + (int)tech_signal.strength + "/4"); } //+------------------------------------------------------------------+ //| Update trade information | //+------------------------------------------------------------------+ void UnifiedDashboard::UpdateTrade(string signal, double lot_size, double price, double confidence) { if (!m_initialized) return; m_total_trades++; ObjectSetString(0, m_prefix + "last_trade", OBJPROP_TEXT, "Last: " + signal + " " + DoubleToString(lot_size, 2) + " @ " + DoubleToString(price, _Digits)); ObjectSetString(0, m_prefix + "total_trades", OBJPROP_TEXT, "Total Trades: " + IntegerToString(m_total_trades)); } //+------------------------------------------------------------------+ //| Create dashboard background | //+------------------------------------------------------------------+ void UnifiedDashboard::CreateBackground(void) { // Main background CreateRectangle(m_prefix + "background", m_x_pos, m_y_pos, m_width, m_height, C'25,25,35'); // Header background CreateRectangle(m_prefix + "header_bg", m_x_pos, m_y_pos, m_width, 40, C'65,105,225'); // Section separators CreateRectangle(m_prefix + "sep1", m_x_pos + 5, m_y_pos + 120, m_width - 10, 1, C'100,100,120'); CreateRectangle(m_prefix + "sep2", m_x_pos + 5, m_y_pos + 220, m_width - 10, 1, C'100,100,120'); } //+------------------------------------------------------------------+ //| Create dashboard header | //+------------------------------------------------------------------+ void UnifiedDashboard::CreateHeader(void) { CreateLabel(m_prefix + "title", "🚀 Revolutionary AI v4.0", m_x_pos + 10, m_y_pos + 8, clrWhite, 11); CreateLabel(m_prefix + "symbol", m_symbol, m_x_pos + m_width - 80, m_y_pos + 8, clrYellow, 11); CreateLabel(m_prefix + "status", "● ACTIVE", m_x_pos + 10, m_y_pos + 25, clrLimeGreen, 8); } //+------------------------------------------------------------------+ //| Create status section | //+------------------------------------------------------------------+ void UnifiedDashboard::CreateStatusSection(void) { int y_start = m_y_pos + 50; CreateLabel(m_prefix + "section1", "═══ MARKET STATUS ═══", m_x_pos + 10, y_start, clrCyan, 9); CreateLabel(m_prefix + "time", "Time: ", m_x_pos + 10, y_start + 20, clrWhite, 8); CreateLabel(m_prefix + "spread", "Spread: ", m_x_pos + 10, y_start + 35, clrWhite, 8); CreateLabel(m_prefix + "price", "Price: ", m_x_pos + 10, y_start + 50, clrWhite, 8); } //+------------------------------------------------------------------+ //| Create analysis section | //+------------------------------------------------------------------+ void UnifiedDashboard::CreateAnalysisSection(void) { int y_start = m_y_pos + 130; CreateLabel(m_prefix + "section2", "═══ AI ANALYSIS ═══", m_x_pos + 10, y_start, clrCyan, 9); CreateLabel(m_prefix + "ai_signal", "AI Signal: LOADING...", m_x_pos + 10, y_start + 20, clrGray, 8); CreateLabel(m_prefix + "ai_confidence", "AI Confidence: --", m_x_pos + 10, y_start + 35, clrWhite, 8); CreateLabel(m_prefix + "tech_signal", "Tech Signal: LOADING...", m_x_pos + 10, y_start + 50, clrGray, 8); CreateLabel(m_prefix + "tech_strength", "Tech Strength: --", m_x_pos + 10, y_start + 65, clrWhite, 8); CreateLabel(m_prefix + "market_regime", "Market: --", m_x_pos + 10, y_start + 80, clrWhite, 8); } //+------------------------------------------------------------------+ //| Create performance section | //+------------------------------------------------------------------+ void UnifiedDashboard::CreatePerformanceSection(void) { int y_start = m_y_pos + 230; CreateLabel(m_prefix + "section3", "═══ PERFORMANCE ═══", m_x_pos + 10, y_start, clrCyan, 9); CreateLabel(m_prefix + "balance", "Balance: " + FormatMoney(AccountInfoDouble(ACCOUNT_BALANCE)), m_x_pos + 10, y_start + 20, clrWhite, 8); CreateLabel(m_prefix + "daily_pnl", "Daily P&L: +0.00%", m_x_pos + 10, y_start + 35, clrWhite, 8); CreateLabel(m_prefix + "total_trades", "Total Trades: 0", m_x_pos + 10, y_start + 50, clrWhite, 8); CreateLabel(m_prefix + "win_rate", "Win Rate: --%", m_x_pos + 10, y_start + 65, clrWhite, 8); CreateLabel(m_prefix + "last_trade", "Last: --", m_x_pos + 10, y_start + 80, clrWhite, 8); } //+------------------------------------------------------------------+ //| Update status section | //+------------------------------------------------------------------+ void UnifiedDashboard::UpdateStatus(void) { // Update time ObjectSetString(0, m_prefix + "time", OBJPROP_TEXT, "Time: " + TimeToString(TimeCurrent(), TIME_MINUTES)); // Update spread double spread = (SymbolInfoDouble(m_symbol, SYMBOL_ASK) - SymbolInfoDouble(m_symbol, SYMBOL_BID)) / SymbolInfoDouble(m_symbol, SYMBOL_POINT); ObjectSetString(0, m_prefix + "spread", OBJPROP_TEXT, "Spread: " + DoubleToString(spread, 1) + " pts"); // Update price ObjectSetString(0, m_prefix + "price", OBJPROP_TEXT, "Price: " + DoubleToString(SymbolInfoDouble(m_symbol, SYMBOL_BID), _Digits)); } //+------------------------------------------------------------------+ //| Update performance section | //+------------------------------------------------------------------+ void UnifiedDashboard::UpdatePerformance(void) { // Update balance double current_balance = AccountInfoDouble(ACCOUNT_BALANCE); ObjectSetString(0, m_prefix + "balance", OBJPROP_TEXT, "Balance: " + FormatMoney(current_balance)); // Calculate daily P&L double daily_pnl = 0; if (m_daily_start_balance > 0) { daily_pnl = ((current_balance - m_daily_start_balance) / m_daily_start_balance) * 100; } color pnl_color = (daily_pnl >= 0) ? clrLimeGreen : clrOrangeRed; string pnl_sign = (daily_pnl >= 0) ? "+" : ""; ObjectSetString(0, m_prefix + "daily_pnl", OBJPROP_TEXT, "Daily P&L: " + pnl_sign + DoubleToString(daily_pnl, 2) + "%"); ObjectSetInteger(0, m_prefix + "daily_pnl", OBJPROP_COLOR, pnl_color); // Update win rate double win_rate = (m_total_trades > 0) ? ((double)m_winning_trades / m_total_trades) * 100 : 0; ObjectSetString(0, m_prefix + "win_rate", OBJPROP_TEXT, "Win Rate: " + DoubleToString(win_rate, 1) + "%"); } //+------------------------------------------------------------------+ //| Create label object | //+------------------------------------------------------------------+ void UnifiedDashboard::CreateLabel(string name, string text, int x, int y, color clr = clrWhite, int size = 9) { ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0); ObjectSetString(0, name, OBJPROP_TEXT, text); ObjectSetString(0, name, OBJPROP_FONT, "Consolas"); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, size); ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER); } //+------------------------------------------------------------------+ //| Create rectangle object | //+------------------------------------------------------------------+ void UnifiedDashboard::CreateRectangle(string name, int x, int y, int width, int height, color bg_color) { ObjectCreate(0, name, OBJ_RECTANGLE_LABEL, 0, 0, 0); ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER); 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, bg_color); ObjectSetInteger(0, name, OBJPROP_BORDER_TYPE, BORDER_FLAT); ObjectSetInteger(0, name, OBJPROP_WIDTH, 1); ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, C'60,60,70'); } //+------------------------------------------------------------------+ //| Format money display | //+------------------------------------------------------------------+ string UnifiedDashboard::FormatMoney(double amount) { return "$" + DoubleToString(amount, 2); } //+------------------------------------------------------------------+ //| Format percentage display | //+------------------------------------------------------------------+ string UnifiedDashboard::FormatPercent(double percent) { string sign = (percent >= 0) ? "+" : ""; return sign + DoubleToString(percent, 2) + "%"; } //+------------------------------------------------------------------+ //| Get color for signal type | //+------------------------------------------------------------------+ color UnifiedDashboard::GetSignalColor(string signal) { if (signal == "BUY") return clrLimeGreen; if (signal == "SELL") return clrOrangeRed; return clrGray; } //+------------------------------------------------------------------+ //| Destroy dashboard | //+------------------------------------------------------------------+ void UnifiedDashboard::Destroy(void) { if (!m_initialized) return; CleanupObjects(); m_initialized = false; ChartRedraw(); } //+------------------------------------------------------------------+ //| Clean up all dashboard objects | //+------------------------------------------------------------------+ void UnifiedDashboard::CleanupObjects(void) { ObjectsDeleteAll(0, m_prefix, -1, -1); } #endif // UNIFIED_DASHBOARD_MQH