385 lines
16 KiB
MQL5
385 lines
16 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| UnifiedDashboard.mqh - Professional Trading Dashboard |
|
||
|
//| Single, Efficient Dashboard for Revolutionary AI EA |
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
#ifndef UNIFIED_DASHBOARD_MQH
|
||
|
#define UNIFIED_DASHBOARD_MQH
|
||
|
|
||
|
#include <AI/AIIntegrationManager.mqh>
|
||
|
#include <Indicators/IndicatorEngine.mqh>
|
||
|
|
||
|
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
|