✅ Complete Expert Advisor with AI intelligence ✅ Professional MQL5 library structure ✅ Advanced risk management and trade execution ✅ Comprehensive installation documentation 🎯 MQL5 Features: - Conviction-based trading intelligence - Probability-driven position sizing (Kelly Criterion) - Market edge strength analysis - Dynamic TP/SL management based on risk scenarios - AI-powered market narratives dashboard - Multi-layered risk management system 📦 Installation: - Copy RevolutionaryAI_EA_FINAL.mq5 to MQL5/Experts/ - Copy Include/ folder to MQL5/Include/ - Compile and attach to chart - Works standalone - no external dependencies required 🧠 Built for the MQL5 community with professional standards Co-Authored-By: Claude <noreply@anthropic.com>
495 lines
No EOL
16 KiB
MQL5
495 lines
No EOL
16 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| AIIntegrationManager.mqh - AI Server Integration Manager |
|
|
//| Handles all communication with Revolutionary AI server |
|
|
//+------------------------------------------------------------------+
|
|
#include <Utils/JAson.mqh>
|
|
|
|
enum ENUM_AI_SIGNAL
|
|
{
|
|
AI_SIGNAL_NONE,
|
|
AI_SIGNAL_BUY,
|
|
AI_SIGNAL_SELL,
|
|
AI_SIGNAL_HOLD
|
|
};
|
|
|
|
struct AIAnalysisResult
|
|
{
|
|
ENUM_AI_SIGNAL signal;
|
|
double confidence;
|
|
double entry_price;
|
|
double stop_loss;
|
|
double take_profit;
|
|
string market_regime;
|
|
string analysis_summary;
|
|
double risk_score;
|
|
string timestamp;
|
|
};
|
|
|
|
struct StrategyModeInfo
|
|
{
|
|
string current_mode;
|
|
double banker_confidence;
|
|
double wallstreet_confidence;
|
|
double hybrid_confidence;
|
|
string recommended_action;
|
|
datetime last_update;
|
|
};
|
|
|
|
class AIIntegrationManager
|
|
{
|
|
private:
|
|
string m_serverURL;
|
|
string m_symbol;
|
|
int m_timeout;
|
|
|
|
// Communication buffers
|
|
char m_post_data[];
|
|
char m_result[];
|
|
string m_headers;
|
|
string m_cookie;
|
|
string m_referer;
|
|
|
|
// Connection status
|
|
bool m_isConnected;
|
|
datetime m_lastConnectionCheck;
|
|
|
|
public:
|
|
// Constructor
|
|
AIIntegrationManager(string serverURL, string symbol)
|
|
{
|
|
m_serverURL = serverURL;
|
|
m_symbol = symbol;
|
|
m_timeout = 10000; // 10 seconds timeout
|
|
m_isConnected = false;
|
|
m_lastConnectionCheck = 0;
|
|
|
|
// Initialize headers
|
|
m_headers = "Content-Type: application/json\r\n";
|
|
m_cookie = NULL;
|
|
m_referer = NULL;
|
|
|
|
// Test initial connection
|
|
TestConnection();
|
|
}
|
|
|
|
// Destructor
|
|
~AIIntegrationManager()
|
|
{
|
|
// Cleanup if needed
|
|
}
|
|
|
|
// Set symbol for existing manager
|
|
void SetSymbol(string symbol)
|
|
{
|
|
m_symbol = symbol;
|
|
}
|
|
|
|
// Initialize connection
|
|
bool Initialize(string serverURL, string symbol)
|
|
{
|
|
m_serverURL = serverURL;
|
|
m_symbol = symbol;
|
|
return TestConnection();
|
|
}
|
|
|
|
// Test server connection
|
|
bool TestConnection()
|
|
{
|
|
string url = m_serverURL + "/health";
|
|
|
|
// Prepare empty POST data
|
|
ArrayResize(m_post_data, 0);
|
|
ArrayResize(m_result, 0);
|
|
|
|
// Make request
|
|
int result = WebRequest("GET", url, m_headers, m_timeout, m_post_data, m_result, m_headers);
|
|
|
|
if (result == 200)
|
|
{
|
|
m_isConnected = true;
|
|
m_lastConnectionCheck = TimeCurrent();
|
|
Print("✅ AI Server connection successful");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
m_isConnected = false;
|
|
Print("❌ AI Server connection failed. Error: " + IntegerToString(result));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Check if server is online
|
|
bool IsServerOnline()
|
|
{
|
|
// Check every 5 minutes
|
|
if (TimeCurrent() - m_lastConnectionCheck > 300)
|
|
{
|
|
TestConnection();
|
|
}
|
|
return m_isConnected;
|
|
}
|
|
|
|
// Get Revolutionary Analysis (Multi-Spectrum)
|
|
AIAnalysisResult GetRevolutionaryAnalysis(double currentPrice, string timeframe)
|
|
{
|
|
AIAnalysisResult result;
|
|
result.signal = AI_SIGNAL_NONE;
|
|
result.confidence = 0;
|
|
|
|
if (!IsServerOnline())
|
|
{
|
|
Print("❌ Server offline - cannot get revolutionary analysis");
|
|
return result;
|
|
}
|
|
|
|
// Prepare request data
|
|
string requestData = PrepareAnalysisRequest(currentPrice, timeframe, "revolutionary");
|
|
|
|
// Make API call
|
|
string response = MakeAPICall("/api/revolutionary-analysis", requestData);
|
|
|
|
if (response != "")
|
|
{
|
|
result = ParseAnalysisResult(response);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Get Basic Analysis
|
|
AIAnalysisResult GetBasicAnalysis(double currentPrice, string timeframe)
|
|
{
|
|
AIAnalysisResult result;
|
|
result.signal = AI_SIGNAL_NONE;
|
|
result.confidence = 0;
|
|
|
|
if (!IsServerOnline())
|
|
{
|
|
Print("❌ Server offline - cannot get basic analysis");
|
|
return result;
|
|
}
|
|
|
|
// Prepare request data
|
|
string requestData = PrepareAnalysisRequest(currentPrice, timeframe, "basic");
|
|
|
|
// Make API call
|
|
string response = MakeAPICall("/api/basic-analysis", requestData);
|
|
|
|
if (response != "")
|
|
{
|
|
result = ParseAnalysisResult(response);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Get current strategy mode from server
|
|
StrategyModeInfo GetStrategyMode()
|
|
{
|
|
StrategyModeInfo info;
|
|
info.current_mode = "BANKER_STRATEGY";
|
|
info.banker_confidence = 0;
|
|
info.wallstreet_confidence = 0;
|
|
info.hybrid_confidence = 0;
|
|
info.recommended_action = "HOLD";
|
|
info.last_update = TimeCurrent();
|
|
|
|
if (!IsServerOnline())
|
|
{
|
|
Print("❌ Server offline - returning default strategy mode");
|
|
return info;
|
|
}
|
|
|
|
// Prepare request
|
|
string requestData = "{\"symbol\":\"" + m_symbol + "\",\"action\":\"get_strategy_mode\"}";
|
|
|
|
// Make API call
|
|
string response = MakeAPICall("/api/strategy-mode", requestData);
|
|
|
|
if (response != "")
|
|
{
|
|
info = ParseStrategyModeResult(response);
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
// Get current Banker Strategy confidence level
|
|
double GetBankerConfidence()
|
|
{
|
|
StrategyModeInfo mode = GetStrategyMode();
|
|
Print("Banker Confidence: ", mode.banker_confidence);
|
|
return mode.banker_confidence;
|
|
}
|
|
|
|
// Get dynamic TP/SL recommendations
|
|
bool GetDynamicTPSL(int ticket, double &newSL, double &newTP, string &reason)
|
|
{
|
|
if (!IsServerOnline())
|
|
{
|
|
Print("❌ Server offline - cannot get dynamic TP/SL");
|
|
return false;
|
|
}
|
|
|
|
// Prepare request data
|
|
string requestData = "{\"ticket\":" + IntegerToString(ticket) +
|
|
",\"symbol\":\"" + m_symbol + "\"" +
|
|
",\"action\":\"get_dynamic_tpsl\"}";
|
|
|
|
// Make API call
|
|
string response = MakeAPICall("/api/dynamic-tpsl", requestData);
|
|
|
|
if (response != "")
|
|
{
|
|
return ParseDynamicTPSLResult(response, newSL, newTP, reason);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Get smart pending orders recommendations
|
|
string GetSmartPendingOrders()
|
|
{
|
|
if (!IsServerOnline())
|
|
{
|
|
Print("❌ Server offline - cannot get smart pending orders");
|
|
return "";
|
|
}
|
|
|
|
// Prepare request data
|
|
string requestData = "{\"symbol\":\"" + m_symbol + "\",\"action\":\"get_pending_orders\"}";
|
|
|
|
// Make API call
|
|
return MakeAPICall("/api/smart-pending-orders", requestData);
|
|
}
|
|
|
|
// Notify server of trade execution
|
|
bool NotifyTradeExecution(int ticket, string signal, double lotSize, double entryPrice, double stopLoss, double takeProfit)
|
|
{
|
|
if (!IsServerOnline())
|
|
{
|
|
Print("❌ Server offline - cannot notify trade execution");
|
|
return false;
|
|
}
|
|
|
|
// Prepare notification data
|
|
string notificationData = "{\"ticket\":" + IntegerToString(ticket) +
|
|
",\"symbol\":\"" + m_symbol + "\"" +
|
|
",\"signal\":\"" + signal + "\"" +
|
|
",\"lot_size\":" + DoubleToString(lotSize, 2) +
|
|
",\"entry_price\":" + DoubleToString(entryPrice, 5) +
|
|
",\"stop_loss\":" + DoubleToString(stopLoss, 5) +
|
|
",\"take_profit\":" + DoubleToString(takeProfit, 5) +
|
|
",\"timestamp\":" + IntegerToString(TimeCurrent()) + "}";
|
|
|
|
// Make API call
|
|
string response = MakeAPICall("/api/trade-notification", notificationData);
|
|
|
|
return (response != "");
|
|
}
|
|
|
|
// Parse analysis result from JSON response
|
|
AIAnalysisResult ParseAnalysisResult(string jsonResponse)
|
|
{
|
|
AIAnalysisResult result;
|
|
result.signal = AI_SIGNAL_NONE;
|
|
result.confidence = 0;
|
|
|
|
// Parse JSON using JAson library
|
|
CJAVal jsonParser;
|
|
if (jsonParser.Deserialize(jsonResponse))
|
|
{
|
|
// Extract signal
|
|
string signalStr = jsonParser["signal"].ToStr();
|
|
if (signalStr == "BUY")
|
|
result.signal = AI_SIGNAL_BUY;
|
|
else if (signalStr == "SELL")
|
|
result.signal = AI_SIGNAL_SELL;
|
|
else if (signalStr == "HOLD")
|
|
result.signal = AI_SIGNAL_HOLD;
|
|
|
|
// Extract other fields
|
|
result.confidence = jsonParser["confidence"].ToDbl();
|
|
result.entry_price = jsonParser["entry_price"].ToDbl();
|
|
result.stop_loss = jsonParser["stop_loss"].ToDbl();
|
|
result.take_profit = jsonParser["take_profit"].ToDbl();
|
|
result.market_regime = jsonParser["market_regime"].ToStr();
|
|
result.analysis_summary = jsonParser["analysis_summary"].ToStr();
|
|
result.risk_score = jsonParser["risk_score"].ToDbl();
|
|
result.timestamp = jsonParser["timestamp"].ToStr();
|
|
}
|
|
else
|
|
{
|
|
Print("❌ Failed to parse analysis result JSON");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Parse strategy mode result from JSON response
|
|
StrategyModeInfo ParseStrategyModeResult(string jsonResponse)
|
|
{
|
|
StrategyModeInfo info;
|
|
info.current_mode = "BANKER_STRATEGY";
|
|
info.banker_confidence = 0;
|
|
info.wallstreet_confidence = 0;
|
|
info.hybrid_confidence = 0;
|
|
info.recommended_action = "HOLD";
|
|
info.last_update = TimeCurrent();
|
|
|
|
// Parse JSON using JAson library
|
|
CJAVal jsonParser;
|
|
if (jsonParser.Deserialize(jsonResponse))
|
|
{
|
|
info.current_mode = jsonParser["current_mode"].ToStr();
|
|
info.banker_confidence = jsonParser["banker_confidence"].ToDbl();
|
|
info.wallstreet_confidence = jsonParser["wallstreet_confidence"].ToDbl();
|
|
info.hybrid_confidence = jsonParser["hybrid_confidence"].ToDbl();
|
|
info.recommended_action = jsonParser["recommended_action"].ToStr();
|
|
info.last_update = (datetime)jsonParser["last_update"].ToInt();
|
|
}
|
|
else
|
|
{
|
|
Print("❌ Failed to parse strategy mode result JSON");
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
// Parse dynamic TP/SL result from JSON response
|
|
bool ParseDynamicTPSLResult(string jsonResponse, double &newSL, double &newTP, string &reason)
|
|
{
|
|
// Parse JSON using JAson library
|
|
CJAVal jsonParser;
|
|
if (jsonParser.Deserialize(jsonResponse))
|
|
{
|
|
newSL = jsonParser["new_stop_loss"].ToDbl();
|
|
newTP = jsonParser["new_take_profit"].ToDbl();
|
|
reason = jsonParser["reason"].ToStr();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
Print("❌ Failed to parse dynamic TP/SL result JSON");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Parse TP/SL update from JSON response
|
|
bool ParseTPSLUpdate(string jsonResponse, double &newSL, double &newTP)
|
|
{
|
|
string reason;
|
|
return ParseDynamicTPSLResult(jsonResponse, newSL, newTP, reason);
|
|
}
|
|
|
|
// Process pending orders response
|
|
void ProcessPendingOrdersResponse(string jsonResponse)
|
|
{
|
|
// Parse JSON using JAson library
|
|
CJAVal jsonParser;
|
|
if (jsonParser.Deserialize(jsonResponse))
|
|
{
|
|
// Process pending orders recommendations
|
|
if (jsonParser["orders"].m_type == jtARRAY)
|
|
{
|
|
int ordersCount = jsonParser["orders"].Size();
|
|
Print("📊 Smart Pending Orders: " + IntegerToString(ordersCount) + " recommendations");
|
|
|
|
for (int i = 0; i < ordersCount; i++)
|
|
{
|
|
CJAVal order = jsonParser["orders"][i];
|
|
string orderType = order["type"].ToStr();
|
|
double price = order["price"].ToDbl();
|
|
double confidence = order["confidence"].ToDbl();
|
|
string reason = order["reason"].ToStr();
|
|
|
|
Print(" " + IntegerToString(i+1) + ". " + orderType + " @ " +
|
|
DoubleToString(price, 5) + " (Confidence: " +
|
|
DoubleToString(confidence * 100, 1) + "%) - " + reason);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Print("❌ Failed to parse pending orders response JSON");
|
|
}
|
|
}
|
|
|
|
private:
|
|
// Prepare analysis request data
|
|
string PrepareAnalysisRequest(double currentPrice, string timeframe, string analysisType)
|
|
{
|
|
// Get market data
|
|
MqlRates rates[];
|
|
int copied = CopyRates(m_symbol, StringToPeriod(timeframe), 0, 100, rates);
|
|
|
|
// Prepare JSON request
|
|
string requestData = "{";
|
|
requestData += "\"symbol\":\"" + m_symbol + "\",";
|
|
requestData += "\"current_price\":" + DoubleToString(currentPrice, 5) + ",";
|
|
requestData += "\"timeframe\":\"" + timeframe + "\",";
|
|
requestData += "\"analysis_type\":\"" + analysisType + "\",";
|
|
requestData += "\"timestamp\":" + IntegerToString(TimeCurrent()) + ",";
|
|
requestData += "\"rates\":[";
|
|
|
|
// Add recent price data (last 20 bars)
|
|
int barsToSend = MathMin(20, copied);
|
|
for (int i = 0; i < barsToSend; i++)
|
|
{
|
|
if (i > 0) requestData += ",";
|
|
requestData += "{";
|
|
requestData += "\"time\":" + IntegerToString(rates[i].time) + ",";
|
|
requestData += "\"open\":" + DoubleToString(rates[i].open, 5) + ",";
|
|
requestData += "\"high\":" + DoubleToString(rates[i].high, 5) + ",";
|
|
requestData += "\"low\":" + DoubleToString(rates[i].low, 5) + ",";
|
|
requestData += "\"close\":" + DoubleToString(rates[i].close, 5) + ",";
|
|
requestData += "\"volume\":" + IntegerToString(rates[i].tick_volume);
|
|
requestData += "}";
|
|
}
|
|
|
|
requestData += "]}";
|
|
|
|
return requestData;
|
|
}
|
|
|
|
// Make API call to server
|
|
string MakeAPICall(string endpoint, string postData)
|
|
{
|
|
string url = m_serverURL + endpoint;
|
|
|
|
// Convert string to char array
|
|
StringToCharArray(postData, m_post_data, 0, StringLen(postData));
|
|
ArrayResize(m_result, 0);
|
|
|
|
// Make request
|
|
int result = WebRequest("POST", url, m_headers, m_timeout, m_post_data, m_result, m_headers);
|
|
|
|
if (result == 200)
|
|
{
|
|
// Convert response to string
|
|
string response = CharArrayToString(m_result, 0, ArraySize(m_result));
|
|
return response;
|
|
}
|
|
else
|
|
{
|
|
Print("❌ API call failed. Endpoint: " + endpoint + ", Error: " + IntegerToString(result));
|
|
return "";
|
|
}
|
|
}
|
|
|
|
// Convert string to ENUM_TIMEFRAMES
|
|
ENUM_TIMEFRAMES StringToPeriod(string timeframe)
|
|
{
|
|
if (timeframe == "M1") return PERIOD_M1;
|
|
if (timeframe == "M5") return PERIOD_M5;
|
|
if (timeframe == "M15") return PERIOD_M15;
|
|
if (timeframe == "M30") return PERIOD_M30;
|
|
if (timeframe == "H1") return PERIOD_H1;
|
|
if (timeframe == "H4") return PERIOD_H4;
|
|
if (timeframe == "D1") return PERIOD_D1;
|
|
if (timeframe == "W1") return PERIOD_W1;
|
|
if (timeframe == "MN1") return PERIOD_MN1;
|
|
return PERIOD_H1; // Default
|
|
}
|
|
}; |