432 lines
16 KiB
MQL5
432 lines
16 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| SimplifiedStoryDashboard.mqh - AI-Powered Story Interface |
|
||
|
//| Displays market narratives and AI insights in a story format |
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
// PROPER INCLUDES
|
||
|
#include <AI/AIIntegrationManager.mqh>
|
||
|
#include <Indicators/IndicatorEngine.mqh>
|
||
|
|
||
|
// Story categories
|
||
|
enum ENUM_STORY_TYPE
|
||
|
{
|
||
|
STORY_ANALYSIS, // AI Analysis stories
|
||
|
STORY_PERFORMANCE, // Performance stories
|
||
|
STORY_NEWS, // Market news stories
|
||
|
STORY_STRATEGY // Strategy change stories
|
||
|
};
|
||
|
|
||
|
struct StoryEntry
|
||
|
{
|
||
|
ENUM_STORY_TYPE type;
|
||
|
string title;
|
||
|
string content;
|
||
|
datetime timestamp;
|
||
|
string icon;
|
||
|
color text_color;
|
||
|
};
|
||
|
|
||
|
class SimplifiedStoryDashboard
|
||
|
{
|
||
|
private:
|
||
|
AIIntegrationManager* m_aiManager;
|
||
|
string m_symbol;
|
||
|
int m_x_pos;
|
||
|
int m_y_pos;
|
||
|
int m_width;
|
||
|
int m_height;
|
||
|
|
||
|
StoryEntry m_stories[];
|
||
|
int m_max_stories;
|
||
|
int m_current_story;
|
||
|
|
||
|
// Display objects
|
||
|
string m_dashboard_prefix;
|
||
|
|
||
|
public:
|
||
|
// Constructor
|
||
|
SimplifiedStoryDashboard(AIIntegrationManager* aiMgr, string symbol, int x = 450, int y = 50)
|
||
|
{
|
||
|
m_aiManager = aiMgr;
|
||
|
m_symbol = symbol;
|
||
|
m_x_pos = x;
|
||
|
m_y_pos = y;
|
||
|
m_width = 350;
|
||
|
m_height = 400;
|
||
|
m_max_stories = 10;
|
||
|
m_current_story = 0;
|
||
|
m_dashboard_prefix = "story_dashboard_" + m_symbol + "_";
|
||
|
|
||
|
ArrayResize(m_stories, m_max_stories);
|
||
|
InitializeDefaultStories();
|
||
|
}
|
||
|
|
||
|
// Destructor
|
||
|
~SimplifiedStoryDashboard()
|
||
|
{
|
||
|
DestroyDashboard();
|
||
|
}
|
||
|
|
||
|
// Initialize dashboard
|
||
|
void Initialize(string symbol, int x_pos, int y_pos)
|
||
|
{
|
||
|
m_symbol = symbol;
|
||
|
m_x_pos = x_pos;
|
||
|
m_y_pos = y_pos;
|
||
|
}
|
||
|
|
||
|
// Create dashboard
|
||
|
bool CreateDashboard()
|
||
|
{
|
||
|
CreateBackground();
|
||
|
CreateHeader();
|
||
|
CreateNavigationButtons();
|
||
|
DisplayCurrentStory();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// Update dashboard
|
||
|
void UpdateDashboard()
|
||
|
{
|
||
|
DisplayCurrentStory();
|
||
|
ChartRedraw();
|
||
|
}
|
||
|
|
||
|
// Update method (for regular updates)
|
||
|
void Update()
|
||
|
{
|
||
|
UpdateDashboard();
|
||
|
}
|
||
|
|
||
|
// Add analysis story
|
||
|
void ShowAnalysisStory(AIAnalysisResult &analysis)
|
||
|
{
|
||
|
StoryEntry story;
|
||
|
story.type = STORY_ANALYSIS;
|
||
|
story.title = "🧠 AI Analysis Update";
|
||
|
story.content = "Market regime: " + analysis.market_regime +
|
||
|
"\\nSignal: " + AISignalToString(analysis.signal) +
|
||
|
"\\nConfidence: " + DoubleToString(analysis.confidence * 100, 1) + "%" +
|
||
|
"\\nRisk Score: " + DoubleToString(analysis.risk_score, 1) + "/10" +
|
||
|
"\\n\\n" + analysis.analysis_summary;
|
||
|
story.timestamp = TimeCurrent();
|
||
|
story.icon = "🧠";
|
||
|
story.text_color = (analysis.signal == AI_SIGNAL_BUY) ? clrLightGreen :
|
||
|
(analysis.signal == AI_SIGNAL_SELL) ? clrLightPink : clrYellow;
|
||
|
|
||
|
AddStory(story);
|
||
|
}
|
||
|
|
||
|
// Add performance story
|
||
|
void ShowPerformanceStory(double dailyPnL, double winRate, int totalTrades)
|
||
|
{
|
||
|
StoryEntry story;
|
||
|
story.type = STORY_PERFORMANCE;
|
||
|
story.title = "📊 Performance Update";
|
||
|
story.content = "Daily P&L: $" + DoubleToString(dailyPnL, 2) +
|
||
|
"\\nWin Rate: " + DoubleToString(winRate * 100, 1) + "%" +
|
||
|
"\\nTotal Trades: " + IntegerToString(totalTrades) +
|
||
|
"\\n\\nThe AI trading system continues to adapt and optimize " +
|
||
|
"performance based on market conditions and historical data.";
|
||
|
story.timestamp = TimeCurrent();
|
||
|
story.icon = "📊";
|
||
|
story.text_color = (dailyPnL >= 0) ? clrLightGreen : clrLightPink;
|
||
|
|
||
|
AddStory(story);
|
||
|
}
|
||
|
|
||
|
// Destroy dashboard
|
||
|
void DestroyDashboard()
|
||
|
{
|
||
|
// Delete all objects with our prefix
|
||
|
ObjectsDeleteAll(0, m_dashboard_prefix, -1, -1);
|
||
|
ChartRedraw();
|
||
|
}
|
||
|
|
||
|
// Navigate to next story
|
||
|
void NextStory()
|
||
|
{
|
||
|
m_current_story = (m_current_story + 1) % GetActiveStoriesCount();
|
||
|
DisplayCurrentStory();
|
||
|
}
|
||
|
|
||
|
// Navigate to previous story
|
||
|
void PreviousStory()
|
||
|
{
|
||
|
int activeCount = GetActiveStoriesCount();
|
||
|
if (activeCount > 0)
|
||
|
{
|
||
|
m_current_story = (m_current_story - 1 + activeCount) % activeCount;
|
||
|
}
|
||
|
DisplayCurrentStory();
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
// Initialize default stories
|
||
|
void InitializeDefaultStories()
|
||
|
{
|
||
|
// Welcome story
|
||
|
StoryEntry welcome;
|
||
|
welcome.type = STORY_STRATEGY;
|
||
|
welcome.title = "🚀 Revolutionary AI Trading";
|
||
|
welcome.content = "Welcome to the Revolutionary AI Trading System!\\n\\n" +
|
||
|
"This advanced system uses multiple AI engines to analyze " +
|
||
|
"market conditions and provide intelligent trading signals.\\n\\n" +
|
||
|
"Features:\\n• Multi-spectrum analysis\\n• Dynamic strategy switching\\n" +
|
||
|
"• Real-time market adaptation\\n• Advanced risk management";
|
||
|
welcome.timestamp = TimeCurrent();
|
||
|
welcome.icon = "🚀";
|
||
|
welcome.text_color = clrWhite;
|
||
|
|
||
|
AddStory(welcome);
|
||
|
}
|
||
|
|
||
|
// Add story to the array
|
||
|
void AddStory(StoryEntry &story)
|
||
|
{
|
||
|
// Shift existing stories
|
||
|
for (int i = ArraySize(m_stories) - 1; i > 0; i--)
|
||
|
{
|
||
|
m_stories[i] = m_stories[i-1];
|
||
|
}
|
||
|
|
||
|
// Add new story at the beginning
|
||
|
m_stories[0] = story;
|
||
|
|
||
|
// Set current story to the new one
|
||
|
m_current_story = 0;
|
||
|
|
||
|
// Update display
|
||
|
DisplayCurrentStory();
|
||
|
}
|
||
|
|
||
|
// Get count of active stories
|
||
|
int GetActiveStoriesCount()
|
||
|
{
|
||
|
int count = 0;
|
||
|
for (int i = 0; i < ArraySize(m_stories); i++)
|
||
|
{
|
||
|
if (m_stories[i].title != "") count++;
|
||
|
}
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
// Create background
|
||
|
void CreateBackground()
|
||
|
{
|
||
|
string name = m_dashboard_prefix + "background";
|
||
|
ObjectCreate(0, name, OBJ_RECTANGLE_LABEL, 0, 0, 0);
|
||
|
ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
||
|
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, m_x_pos);
|
||
|
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, m_y_pos);
|
||
|
ObjectSetInteger(0, name, OBJPROP_XSIZE, m_width);
|
||
|
ObjectSetInteger(0, name, OBJPROP_YSIZE, m_height);
|
||
|
ObjectSetInteger(0, name, OBJPROP_BGCOLOR, C'20,25,35');
|
||
|
ObjectSetInteger(0, name, OBJPROP_BORDER_TYPE, BORDER_FLAT);
|
||
|
ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, C'65,105,225');
|
||
|
ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);
|
||
|
}
|
||
|
|
||
|
// Create header
|
||
|
void CreateHeader()
|
||
|
{
|
||
|
string name = m_dashboard_prefix + "header";
|
||
|
ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0);
|
||
|
ObjectSetString(0, name, OBJPROP_TEXT, "📚 AI Story Dashboard");
|
||
|
ObjectSetString(0, name, OBJPROP_FONT, "Arial Bold");
|
||
|
ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 12);
|
||
|
ObjectSetInteger(0, name, OBJPROP_COLOR, clrWhite);
|
||
|
ObjectSetInteger(0, name, OBJPROP_XDISTANCE, m_x_pos + 10);
|
||
|
ObjectSetInteger(0, name, OBJPROP_YDISTANCE, m_y_pos + 10);
|
||
|
}
|
||
|
|
||
|
// Create navigation buttons
|
||
|
void CreateNavigationButtons()
|
||
|
{
|
||
|
// Previous button
|
||
|
string prevName = m_dashboard_prefix + "prev_btn";
|
||
|
ObjectCreate(0, prevName, OBJ_RECTANGLE_LABEL, 0, 0, 0);
|
||
|
ObjectSetInteger(0, prevName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
||
|
ObjectSetInteger(0, prevName, OBJPROP_XDISTANCE, m_x_pos + 10);
|
||
|
ObjectSetInteger(0, prevName, OBJPROP_YDISTANCE, m_y_pos + 35);
|
||
|
ObjectSetInteger(0, prevName, OBJPROP_XSIZE, 30);
|
||
|
ObjectSetInteger(0, prevName, OBJPROP_YSIZE, 25);
|
||
|
ObjectSetInteger(0, prevName, OBJPROP_BGCOLOR, C'50,50,60');
|
||
|
ObjectSetInteger(0, prevName, OBJPROP_BORDER_TYPE, BORDER_FLAT);
|
||
|
|
||
|
string prevText = m_dashboard_prefix + "prev_text";
|
||
|
ObjectCreate(0, prevText, OBJ_LABEL, 0, 0, 0);
|
||
|
ObjectSetString(0, prevText, OBJPROP_TEXT, "◀");
|
||
|
ObjectSetString(0, prevText, OBJPROP_FONT, "Arial");
|
||
|
ObjectSetInteger(0, prevText, OBJPROP_FONTSIZE, 10);
|
||
|
ObjectSetInteger(0, prevText, OBJPROP_COLOR, clrWhite);
|
||
|
ObjectSetInteger(0, prevText, OBJPROP_XDISTANCE, m_x_pos + 20);
|
||
|
ObjectSetInteger(0, prevText, OBJPROP_YDISTANCE, m_y_pos + 40);
|
||
|
|
||
|
// Next button
|
||
|
string nextName = m_dashboard_prefix + "next_btn";
|
||
|
ObjectCreate(0, nextName, OBJ_RECTANGLE_LABEL, 0, 0, 0);
|
||
|
ObjectSetInteger(0, nextName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
|
||
|
ObjectSetInteger(0, nextName, OBJPROP_XDISTANCE, m_x_pos + 45);
|
||
|
ObjectSetInteger(0, nextName, OBJPROP_YDISTANCE, m_y_pos + 35);
|
||
|
ObjectSetInteger(0, nextName, OBJPROP_XSIZE, 30);
|
||
|
ObjectSetInteger(0, nextName, OBJPROP_YSIZE, 25);
|
||
|
ObjectSetInteger(0, nextName, OBJPROP_BGCOLOR, C'50,50,60');
|
||
|
ObjectSetInteger(0, nextName, OBJPROP_BORDER_TYPE, BORDER_FLAT);
|
||
|
|
||
|
string nextText = m_dashboard_prefix + "next_text";
|
||
|
ObjectCreate(0, nextText, OBJ_LABEL, 0, 0, 0);
|
||
|
ObjectSetString(0, nextText, OBJPROP_TEXT, "▶");
|
||
|
ObjectSetString(0, nextText, OBJPROP_FONT, "Arial");
|
||
|
ObjectSetInteger(0, nextText, OBJPROP_FONTSIZE, 10);
|
||
|
ObjectSetInteger(0, nextText, OBJPROP_COLOR, clrWhite);
|
||
|
ObjectSetInteger(0, nextText, OBJPROP_XDISTANCE, m_x_pos + 55);
|
||
|
ObjectSetInteger(0, nextText, OBJPROP_YDISTANCE, m_y_pos + 40);
|
||
|
|
||
|
// Story counter
|
||
|
string counterName = m_dashboard_prefix + "counter";
|
||
|
ObjectCreate(0, counterName, OBJ_LABEL, 0, 0, 0);
|
||
|
ObjectSetString(0, counterName, OBJPROP_FONT, "Arial");
|
||
|
ObjectSetInteger(0, counterName, OBJPROP_FONTSIZE, 9);
|
||
|
ObjectSetInteger(0, counterName, OBJPROP_COLOR, clrSilver);
|
||
|
ObjectSetInteger(0, counterName, OBJPROP_XDISTANCE, m_x_pos + 85);
|
||
|
ObjectSetInteger(0, counterName, OBJPROP_YDISTANCE, m_y_pos + 42);
|
||
|
}
|
||
|
|
||
|
// Display current story
|
||
|
void DisplayCurrentStory()
|
||
|
{
|
||
|
int activeCount = GetActiveStoriesCount();
|
||
|
if (activeCount == 0) return;
|
||
|
|
||
|
// Ensure current story index is valid
|
||
|
if (m_current_story >= activeCount)
|
||
|
{
|
||
|
m_current_story = 0;
|
||
|
}
|
||
|
|
||
|
StoryEntry currentStory = m_stories[m_current_story];
|
||
|
|
||
|
// Update story counter
|
||
|
string counterName = m_dashboard_prefix + "counter";
|
||
|
ObjectSetString(0, counterName, OBJPROP_TEXT,
|
||
|
IntegerToString(m_current_story + 1) + "/" + IntegerToString(activeCount));
|
||
|
|
||
|
// Story title
|
||
|
string titleName = m_dashboard_prefix + "story_title";
|
||
|
ObjectDelete(0, titleName);
|
||
|
ObjectCreate(0, titleName, OBJ_LABEL, 0, 0, 0);
|
||
|
ObjectSetString(0, titleName, OBJPROP_TEXT, currentStory.title);
|
||
|
ObjectSetString(0, titleName, OBJPROP_FONT, "Arial Bold");
|
||
|
ObjectSetInteger(0, titleName, OBJPROP_FONTSIZE, 11);
|
||
|
ObjectSetInteger(0, titleName, OBJPROP_COLOR, currentStory.text_color);
|
||
|
ObjectSetInteger(0, titleName, OBJPROP_XDISTANCE, m_x_pos + 10);
|
||
|
ObjectSetInteger(0, titleName, OBJPROP_YDISTANCE, m_y_pos + 70);
|
||
|
|
||
|
// Story content (split into multiple lines)
|
||
|
string lines[];
|
||
|
SplitString(currentStory.content, StringGetCharacter("\\n", 0), lines);
|
||
|
|
||
|
for (int i = 0; i < ArraySize(lines) && i < 15; i++) // Max 15 lines
|
||
|
{
|
||
|
string lineName = m_dashboard_prefix + "story_line_" + IntegerToString(i);
|
||
|
ObjectDelete(0, lineName);
|
||
|
ObjectCreate(0, lineName, OBJ_LABEL, 0, 0, 0);
|
||
|
ObjectSetString(0, lineName, OBJPROP_TEXT, lines[i]);
|
||
|
ObjectSetString(0, lineName, OBJPROP_FONT, "Arial");
|
||
|
ObjectSetInteger(0, lineName, OBJPROP_FONTSIZE, 9);
|
||
|
ObjectSetInteger(0, lineName, OBJPROP_COLOR, clrWhite);
|
||
|
ObjectSetInteger(0, lineName, OBJPROP_XDISTANCE, m_x_pos + 10);
|
||
|
ObjectSetInteger(0, lineName, OBJPROP_YDISTANCE, m_y_pos + 95 + (i * 18));
|
||
|
}
|
||
|
|
||
|
// Clear unused line objects
|
||
|
for (int i = ArraySize(lines); i < 15; i++)
|
||
|
{
|
||
|
string lineName = m_dashboard_prefix + "story_line_" + IntegerToString(i);
|
||
|
ObjectDelete(0, lineName);
|
||
|
}
|
||
|
|
||
|
// Timestamp
|
||
|
string timestampName = m_dashboard_prefix + "timestamp";
|
||
|
ObjectDelete(0, timestampName);
|
||
|
ObjectCreate(0, timestampName, OBJ_LABEL, 0, 0, 0);
|
||
|
ObjectSetString(0, timestampName, OBJPROP_TEXT,
|
||
|
"⏰ " + TimeToString(currentStory.timestamp, TIME_SECONDS));
|
||
|
ObjectSetString(0, timestampName, OBJPROP_FONT, "Arial");
|
||
|
ObjectSetInteger(0, timestampName, OBJPROP_FONTSIZE, 8);
|
||
|
ObjectSetInteger(0, timestampName, OBJPROP_COLOR, clrSilver);
|
||
|
ObjectSetInteger(0, timestampName, OBJPROP_XDISTANCE, m_x_pos + 10);
|
||
|
ObjectSetInteger(0, timestampName, OBJPROP_YDISTANCE, m_y_pos + m_height - 25);
|
||
|
}
|
||
|
|
||
|
// Convert AI signal enum to string
|
||
|
string AISignalToString(ENUM_AI_SIGNAL signal)
|
||
|
{
|
||
|
switch(signal)
|
||
|
{
|
||
|
case AI_SIGNAL_BUY: return "BUY";
|
||
|
case AI_SIGNAL_SELL: return "SELL";
|
||
|
case AI_SIGNAL_HOLD: return "HOLD";
|
||
|
default: return "NONE";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Split string function
|
||
|
void SplitString(string text, ushort delimiter, string &result[])
|
||
|
{
|
||
|
StringSplit(text, delimiter, result);
|
||
|
}
|
||
|
|
||
|
// Required methods for EA v4 compatibility
|
||
|
TradingIntelligence GetTradingIntelligence(void)
|
||
|
{
|
||
|
TradingIntelligence intel;
|
||
|
// Get latest AI analysis
|
||
|
if (m_aiManager != NULL) {
|
||
|
AIAnalysisResult analysis = m_aiManager->GetLatestAnalysis();
|
||
|
intel.signal = (analysis.signal == AI_SIGNAL_BUY) ? SIGNAL_BUY :
|
||
|
(analysis.signal == AI_SIGNAL_SELL) ? SIGNAL_SELL : SIGNAL_NONE;
|
||
|
intel.conviction = (analysis.confidence > 0.8) ? CONVICTION_VERY_STRONG :
|
||
|
(analysis.confidence > 0.7) ? CONVICTION_STRONG :
|
||
|
(analysis.confidence > 0.6) ? CONVICTION_MODERATE : CONVICTION_WEAK;
|
||
|
intel.reason = analysis.analysis_summary;
|
||
|
intel.risk_reward_ratio = 2.0; // Default R/R
|
||
|
intel.probability_success = analysis.confidence;
|
||
|
intel.optimal_position_size = 0.1; // Default lot size
|
||
|
intel.key_level = "";
|
||
|
intel.market_narrative = analysis.market_regime;
|
||
|
}
|
||
|
return intel;
|
||
|
}
|
||
|
|
||
|
MarketEdge GetMarketEdge(void)
|
||
|
{
|
||
|
MarketEdge edge;
|
||
|
edge.strength = EDGE_MODERATE; // Default
|
||
|
edge.confidence = 0.75;
|
||
|
edge.reason = "Multi-timeframe analysis";
|
||
|
edge.trend_alignment = true;
|
||
|
edge.supporting_timeframes = 3;
|
||
|
return edge;
|
||
|
}
|
||
|
|
||
|
RiskScenario GetRiskScenario(void)
|
||
|
{
|
||
|
RiskScenario scenario;
|
||
|
scenario.best_case_profit = 5.0;
|
||
|
scenario.base_case_profit = 2.0;
|
||
|
scenario.base_case_loss = -1.5;
|
||
|
scenario.worst_case_loss = -3.0;
|
||
|
scenario.max_account_risk = 2.0;
|
||
|
scenario.risk_level = "Moderate";
|
||
|
scenario.exit_strategy = "Dynamic TP/SL based on market conditions";
|
||
|
return scenario;
|
||
|
}
|
||
|
|
||
|
// UpdateLive method for dashboard updates
|
||
|
void UpdateLive(void)
|
||
|
{
|
||
|
UpdateDashboard();
|
||
|
}
|
||
|
};
|