//+------------------------------------------------------------------+ //| MultiTradeReporter_v71.mqh | //| Institutional Grade Multi-Source Reporting | //| Performance Attribution, Risk Analytics, Compliance | //+------------------------------------------------------------------+ #ifndef MULTI_TRADE_REPORTER_V71_MQH #define MULTI_TRADE_REPORTER_V71_MQH #include "DataTypes_v71.mqh" #include #include //+------------------------------------------------------------------+ //| Report Types | //+------------------------------------------------------------------+ enum ENUM_REPORT_TYPE { REPORT_DAILY = 0, REPORT_WEEKLY = 1, REPORT_MONTHLY = 2, REPORT_QUARTERLY = 3, REPORT_ANNUAL = 4, REPORT_CUSTOM = 5 }; //+------------------------------------------------------------------+ //| Performance Attribution | //+------------------------------------------------------------------+ struct PerformanceAttribution { double strategy_contribution; double timing_contribution; double selection_contribution; double allocation_effect; double interaction_effect; double currency_effect; double total_attribution; }; //+------------------------------------------------------------------+ //| Risk Attribution | //+------------------------------------------------------------------+ struct RiskAttribution { double systematic_risk; double specific_risk; double concentration_risk; double correlation_risk; double liquidity_risk; double operational_risk; double model_risk; }; //+------------------------------------------------------------------+ //| Compliance Metrics | //+------------------------------------------------------------------+ struct ComplianceMetrics { int violations_count; double max_position_breach; double max_drawdown_breach; double max_var_breach; int unauthorized_trades; datetime last_violation_time; string violation_details[]; }; //+------------------------------------------------------------------+ //| Multi-Trade Reporter Class - Institutional | //+------------------------------------------------------------------+ class CMultiTradeReporterV71 { private: //--- Configuration string m_report_path; ENUM_REPORT_TYPE m_report_type; bool m_csv_export; bool m_html_export; bool m_json_export; bool m_fix_export; int m_report_frequency; //--- Tracking datetime m_last_report_time; int m_report_count; //--- Performance attribution PerformanceAttribution m_attribution; RiskAttribution m_risk_attribution; ComplianceMetrics m_compliance; //--- Report templates string m_daily_template; string m_institutional_template; string m_regulatory_template; //--- Helper methods void GenerateHTMLReport(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance); void GenerateJSONReport(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance); void GenerateFIXReport(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance); void GenerateComplianceReport(ComplianceMetrics &compliance); //--- Analysis methods void CalculatePerformanceAttribution(ManagedTradeV71 &trades[]); void CalculateRiskAttribution(ManagedTradeV71 &trades[]); void AnalyzeTradesByStrategy(ManagedTradeV71 &trades[], string &output); void AnalyzeTradesByTimeframe(ManagedTradeV71 &trades[], string &output); void AnalyzeExecutionQuality(ManagedTradeV71 &trades[], string &output); //--- Statistical analysis double CalculateInformationRatio(double returns[], double benchmark[]); double CalculateMaximumLikelihoodEstimate(double data[]); void CalculateRegressionAnalysis(double x[], double y[], double &alpha, double &beta); public: CMultiTradeReporterV71(); ~CMultiTradeReporterV71(); //--- Initialization bool Initialize(string report_path, ENUM_REPORT_TYPE type = REPORT_DAILY); void SetExportFormats(bool csv, bool html, bool json, bool fix); void SetReportFrequency(int minutes) { m_report_frequency = minutes; } //--- Main reporting void GenerateInstitutionalReport(PerformanceMetricsV71 &performance, ManagedTradeV71 &trades[], ExecutionMetrics &execution); void GenerateRegulatoryReport(ManagedTradeV71 &trades[], ComplianceMetrics &compliance); void GenerateRiskReport(ManagedTradeV71 &trades[], SystemStateV71 &state); //--- Performance attribution void UpdatePerformanceAttribution(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance); PerformanceAttribution GetAttribution() { return m_attribution; } //--- Specialized reports void GenerateVaRReport(ManagedTradeV71 &trades[], double var, double cvar); void GenerateStressTestReport(ManagedTradeV71 &trades[], double scenarios[]); void GenerateCorrelationReport(CorrelationMatrix &correlations); void GenerateLiquidityReport(ManagedTradeV71 &trades[]); //--- Trade analysis void GenerateTradeAnalysis(ManagedTradeV71 &trades[]); void GenerateMLPerformanceReport(ManagedTradeV71 &trades[]); void GenerateOrderFlowReport(OrderFlowData &flow_data[]); //--- Compliance and audit void CheckCompliance(ManagedTradeV71 &trades[], ComplianceMetrics &metrics); void GenerateAuditTrail(ManagedTradeV71 &trades[]); void LogComplianceViolation(string violation_type, string details); //--- Export methods void ExportToBloomberg(ManagedTradeV71 &trades[]); void ExportToFIX(ManagedTradeV71 &trades[]); void ExportToREDI(ManagedTradeV71 &trades[]); //--- Real-time updates void SendRealtimeUpdate(string metric, double value); void BroadcastPerformance(PerformanceMetricsV71 &performance); //--- Getters datetime GetLastReportTime() { return m_last_report_time; } int GetReportCount() { return m_report_count; } }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CMultiTradeReporterV71::CMultiTradeReporterV71() { m_report_path = "InstitutionalReports\\"; m_report_type = REPORT_DAILY; m_csv_export = true; m_html_export = true; m_json_export = true; m_fix_export = false; m_report_frequency = 3600; // Hourly m_last_report_time = 0; m_report_count = 0; //--- Initialize attribution ZeroMemory(m_attribution); ZeroMemory(m_risk_attribution); ZeroMemory(m_compliance); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CMultiTradeReporterV71::~CMultiTradeReporterV71() { } //+------------------------------------------------------------------+ //| Initialize reporter | //+------------------------------------------------------------------+ bool CMultiTradeReporterV71::Initialize(string report_path, ENUM_REPORT_TYPE type) { m_report_path = report_path; m_report_type = type; //--- Create directory structure if(!FileIsExist(m_report_path)) { Print("Please create directory: ", m_report_path); } //--- Load report templates m_daily_template = "Daily Institutional Report"; m_institutional_template = "Institutional Trading Report"; m_regulatory_template = "Regulatory Compliance Report"; Print("MultiTradeReporterV71 initialized: Path=", m_report_path, ", Type=", EnumToString(m_report_type)); return true; } //+------------------------------------------------------------------+ //| Generate institutional report | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::GenerateInstitutionalReport(PerformanceMetricsV71 &performance, ManagedTradeV71 &trades[], ExecutionMetrics &execution) { //--- Check report frequency if(TimeCurrent() - m_last_report_time < m_report_frequency && m_report_frequency > 0) return; m_report_count++; string timestamp = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES); StringReplace(timestamp, ":", "_"); StringReplace(timestamp, " ", "_"); //--- Main report content string report = ""; report += "╔══════════════════════════════════════════════════════════════╗\n"; report += "║ INSTITUTIONAL TRADING REPORT - ERMT 7.1 ║\n"; report += "╚══════════════════════════════════════════════════════════════╝\n\n"; report += "Report Date: " + TimeToString(TimeCurrent()) + "\n"; report += "Report Number: " + IntegerToString(m_report_count) + "\n"; report += "Reporting Period: " + EnumToString(m_report_type) + "\n\n"; //--- Executive Summary report += "┌─────────────────────────────────────────────────────────────┐\n"; report += "│ EXECUTIVE SUMMARY │\n"; report += "└─────────────────────────────────────────────────────────────┘\n"; double starting_balance = AccountInfoDouble(ACCOUNT_BALANCE) - performance.net_profit; double roi = (starting_balance > 0) ? (performance.net_profit / starting_balance * 100) : 0; report += "Starting Capital: $" + DoubleToString(starting_balance, 2) + "\n"; report += "Current Capital: $" + DoubleToString(AccountInfoDouble(ACCOUNT_BALANCE), 2) + "\n"; report += "Net P&L: $" + DoubleToString(performance.net_profit, 2) + "\n"; report += "Return on Investment: " + DoubleToString(roi, 2) + "%\n"; report += "Sharpe Ratio: " + DoubleToString(performance.sharpe_ratio, 3) + "\n"; report += "Information Ratio: " + DoubleToString(performance.information_ratio, 3) + "\n\n"; //--- Risk Analytics report += "┌─────────────────────────────────────────────────────────────┐\n"; report += "│ RISK ANALYTICS │\n"; report += "└─────────────────────────────────────────────────────────────┘\n"; report += "Value at Risk (95%): " + DoubleToString(performance.var_95, 2) + "%\n"; report += "Conditional VaR (95%): " + DoubleToString(performance.cvar_95, 2) + "%\n"; report += "Maximum Drawdown: " + DoubleToString(performance.max_drawdown_percent, 2) + "%\n"; report += "Beta: " + DoubleToString(performance.beta, 3) + "\n"; report += "Tracking Error: " + DoubleToString(performance.tracking_error, 3) + "%\n\n"; //--- Performance Attribution if(m_attribution.total_attribution != 0) { report += "┌─────────────────────────────────────────────────────────────┐\n"; report += "│ PERFORMANCE ATTRIBUTION │\n"; report += "└─────────────────────────────────────────────────────────────┘\n"; report += "Strategy Selection: " + DoubleToString(m_attribution.selection_contribution * 100, 2) + "%\n"; report += "Market Timing: " + DoubleToString(m_attribution.timing_contribution * 100, 2) + "%\n"; report += "Asset Allocation: " + DoubleToString(m_attribution.allocation_effect * 100, 2) + "%\n"; report += "Currency Effect: " + DoubleToString(m_attribution.currency_effect * 100, 2) + "%\n"; report += "Total Attribution: " + DoubleToString(m_attribution.total_attribution * 100, 2) + "%\n\n"; } //--- Execution Quality report += "┌─────────────────────────────────────────────────────────────┐\n"; report += "│ EXECUTION QUALITY │\n"; report += "└─────────────────────────────────────────────────────────────┘\n"; report += "Total Executions: " + IntegerToString(execution.fills_count) + "\n"; report += "Average Slippage: " + DoubleToString(execution.avg_slippage, 2) + " pips\n"; report += "Positive Slippage Rate: " + DoubleToString(execution.positive_slippage_rate * 100, 1) + "%\n"; report += "Average Fill Time: " + DoubleToString(execution.avg_fill_time_ms, 0) + " ms\n"; report += "VWAP Tracking Error: " + DoubleToString(execution.vwap_tracking_error, 3) + "\n"; report += "Price Improvement: $" + DoubleToString(execution.improvement_amount, 2) + "\n\n"; //--- Position Analysis report += "┌─────────────────────────────────────────────────────────────┐\n"; report += "│ POSITION ANALYSIS │\n"; report += "└─────────────────────────────────────────────────────────────┘\n"; int trade_count = ArraySize(trades); report += "Active Positions: " + IntegerToString(trade_count) + "\n"; if(trade_count > 0) { //--- Group by symbol string symbols[]; double exposures[]; int symbol_count = 0; for(int i = 0; i < trade_count; i++) { int idx = -1; for(int j = 0; j < symbol_count; j++) { if(symbols[j] == trades[i].symbol) { idx = j; break; } } if(idx < 0) { ArrayResize(symbols, symbol_count + 1); ArrayResize(exposures, symbol_count + 1); symbols[symbol_count] = trades[i].symbol; exposures[symbol_count] = trades[i].risk_percent; symbol_count++; } else { exposures[idx] += trades[i].risk_percent; } } report += "\nExposure by Symbol:\n"; for(int i = 0; i < symbol_count; i++) { report += " " + symbols[i] + ": " + DoubleToString(exposures[i], 2) + "%\n"; } } //--- Trade Analysis string trade_analysis; AnalyzeTradesByStrategy(trades, trade_analysis); report += "\n" + trade_analysis; //--- Compliance Check if(m_compliance.violations_count > 0) { report += "\n┌─────────────────────────────────────────────────────────────┐\n"; report += "│ COMPLIANCE ALERTS │\n"; report += "└─────────────────────────────────────────────────────────────┘\n"; report += "Total Violations: " + IntegerToString(m_compliance.violations_count) + "\n"; for(int i = 0; i < ArraySize(m_compliance.violation_details); i++) { report += " - " + m_compliance.violation_details[i] + "\n"; } } //--- Save report string filename = m_report_path + "Institutional_" + timestamp; //--- Text format int handle = FileOpen(filename + ".txt", FILE_WRITE|FILE_TXT|FILE_ANSI); if(handle != INVALID_HANDLE) { FileWrite(handle, report); FileClose(handle); } //--- Additional formats if(m_csv_export) GenerateCSVReport(trades, performance); if(m_html_export) GenerateHTMLReport(trades, performance); if(m_json_export) GenerateJSONReport(trades, performance); if(m_fix_export) GenerateFIXReport(trades, performance); m_last_report_time = TimeCurrent(); Print("Institutional report generated: ", filename); } //+------------------------------------------------------------------+ //| Generate CSV report | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::GenerateCSVReport(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance) { string timestamp = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES); StringReplace(timestamp, ":", "_"); StringReplace(timestamp, " ", "_"); string filename = m_report_path + "Trades_" + timestamp + ".csv"; int handle = FileOpen(filename, FILE_WRITE|FILE_CSV|FILE_ANSI, ','); if(handle == INVALID_HANDLE) return; //--- Header with extended fields FileWrite(handle, "Ticket", "Symbol", "Type", "Volume", "Entry", "Current", "SL", "TP", "Profit", "Commission", "Swap", "Risk%", "RMultiple", "MAE", "MFE", "ExpectedReturn", "PredictedVol", "MLConfidence", "VaRContribution", "CorrelationRisk", "LiquidityScore", "ExecutionQuality", "EntryAlgo", "Magic", "OpenTime", "BarsHeld", "Comment"); //--- Trade data int trade_count = ArraySize(trades); for(int i = 0; i < trade_count; i++) { double current_price = (trades[i].type == POSITION_TYPE_BUY) ? SymbolInfoDouble(trades[i].symbol, SYMBOL_BID) : SymbolInfoDouble(trades[i].symbol, SYMBOL_ASK); FileWrite(handle, trades[i].ticket, trades[i].symbol, (trades[i].type == POSITION_TYPE_BUY) ? "BUY" : "SELL", trades[i].volume, trades[i].open_price, current_price, trades[i].sl, trades[i].tp, trades[i].profit, trades[i].commission, trades[i].swap, trades[i].risk_percent, trades[i].r_multiple, trades[i].mae, trades[i].mfe, trades[i].expected_return, trades[i].predicted_volatility, trades[i].ml_confidence, trades[i].var_contribution, trades[i].correlation_risk, trades[i].liquidity_score, trades[i].execution_quality, trades[i].entry_algo, trades[i].magic, TimeToString(trades[i].open_time), trades[i].bars_in_trade, trades[i].comment); } FileClose(handle); } //+------------------------------------------------------------------+ //| Calculate performance attribution | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::CalculatePerformanceAttribution(ManagedTradeV71 &trades[]) { int trade_count = ArraySize(trades); if(trade_count == 0) return; //--- Group trades by strategy double strategy_returns[]; double benchmark_returns[]; //--- Calculate selection effect (simplified) double total_return = 0; double strategy_weighted_return = 0; for(int i = 0; i < trade_count; i++) { double trade_return = trades[i].profit / (trades[i].volume * trades[i].open_price); total_return += trade_return; //--- Weight by ML confidence if(trades[i].ml_enhanced) { strategy_weighted_return += trade_return * trades[i].ml_confidence; } } m_attribution.selection_contribution = strategy_weighted_return - total_return / trade_count; //--- Timing contribution (simplified) double entry_timing_score = 0; double exit_timing_score = 0; for(int i = 0; i < trade_count; i++) { //--- Entry timing: compare to average price in next few bars double avg_price_after = trades[i].open_price; // Simplified if(trades[i].type == POSITION_TYPE_BUY) { entry_timing_score += (avg_price_after - trades[i].open_price) / trades[i].open_price; } else { entry_timing_score += (trades[i].open_price - avg_price_after) / trades[i].open_price; } } m_attribution.timing_contribution = entry_timing_score / trade_count; //--- Allocation effect (position sizing) double equal_weight_return = total_return / trade_count; double actual_weighted_return = 0; double total_risk = 0; for(int i = 0; i < trade_count; i++) { total_risk += trades[i].risk_percent; } for(int i = 0; i < trade_count; i++) { double weight = trades[i].risk_percent / total_risk; double trade_return = trades[i].profit / (trades[i].volume * trades[i].open_price); actual_weighted_return += trade_return * weight; } m_attribution.allocation_effect = actual_weighted_return - equal_weight_return; //--- Currency effect (for non-base currency pairs) m_attribution.currency_effect = 0; // Simplified //--- Interaction effect m_attribution.interaction_effect = 0; // Simplified //--- Total attribution m_attribution.total_attribution = m_attribution.selection_contribution + m_attribution.timing_contribution + m_attribution.allocation_effect + m_attribution.currency_effect + m_attribution.interaction_effect; } //+------------------------------------------------------------------+ //| Update performance attribution | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::UpdatePerformanceAttribution(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance) { //--- Calculate attribution CalculatePerformanceAttribution(trades); //--- Calculate risk attribution CalculateRiskAttribution(trades); //--- Store for reporting m_attribution.strategy_contribution = performance.alpha; // Simplified mapping } //+------------------------------------------------------------------+ //| Calculate risk attribution | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::CalculateRiskAttribution(ManagedTradeV71 &trades[]) { int trade_count = ArraySize(trades); if(trade_count == 0) return; //--- Systematic risk (market beta exposure) double total_beta_exposure = 0; for(int i = 0; i < trade_count; i++) { total_beta_exposure += trades[i].risk_percent * 0.8; // Assume 0.8 beta } m_risk_attribution.systematic_risk = total_beta_exposure / trade_count; //--- Specific risk (idiosyncratic) m_risk_attribution.specific_risk = 100 - m_risk_attribution.systematic_risk; //--- Concentration risk double max_single_risk = 0; for(int i = 0; i < trade_count; i++) { if(trades[i].risk_percent > max_single_risk) max_single_risk = trades[i].risk_percent; } m_risk_attribution.concentration_risk = max_single_risk; //--- Correlation risk double total_correlation_risk = 0; for(int i = 0; i < trade_count; i++) { total_correlation_risk += trades[i].correlation_risk; } m_risk_attribution.correlation_risk = total_correlation_risk / trade_count; //--- Liquidity risk double avg_liquidity_score = 0; for(int i = 0; i < trade_count; i++) { avg_liquidity_score += trades[i].liquidity_score; } avg_liquidity_score /= trade_count; m_risk_attribution.liquidity_risk = (1.0 - avg_liquidity_score) * 100; //--- Model risk (based on ML confidence) double avg_ml_confidence = 0; int ml_trades = 0; for(int i = 0; i < trade_count; i++) { if(trades[i].ml_enhanced) { avg_ml_confidence += trades[i].ml_confidence; ml_trades++; } } if(ml_trades > 0) { avg_ml_confidence /= ml_trades; m_risk_attribution.model_risk = (1.0 - avg_ml_confidence) * 100; } } //+------------------------------------------------------------------+ //| Analyze trades by strategy | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::AnalyzeTradesByStrategy(ManagedTradeV71 &trades[], string &output) { output = "STRATEGY BREAKDOWN\n"; output += "─────────────────\n"; //--- Group by entry algorithm struct StrategyGroup { string name; int count; double profit; double win_rate; double avg_r_multiple; }; StrategyGroup strategies[]; int strategy_count = 0; int trade_count = ArraySize(trades); for(int i = 0; i < trade_count; i++) { //--- Find or create strategy group int idx = -1; for(int j = 0; j < strategy_count; j++) { if(strategies[j].name == trades[i].entry_algo) { idx = j; break; } } if(idx < 0) { ArrayResize(strategies, strategy_count + 1); strategies[strategy_count].name = trades[i].entry_algo; strategies[strategy_count].count = 0; strategies[strategy_count].profit = 0; strategies[strategy_count].win_rate = 0; strategies[strategy_count].avg_r_multiple = 0; idx = strategy_count; strategy_count++; } //--- Update metrics strategies[idx].count++; strategies[idx].profit += trades[i].profit; strategies[idx].avg_r_multiple += trades[i].r_multiple; if(trades[i].profit > 0) strategies[idx].win_rate++; } //--- Calculate averages and format output for(int i = 0; i < strategy_count; i++) { strategies[i].win_rate = (strategies[i].count > 0) ? strategies[i].win_rate / strategies[i].count * 100 : 0; strategies[i].avg_r_multiple = (strategies[i].count > 0) ? strategies[i].avg_r_multiple / strategies[i].count : 0; output += "\n" + strategies[i].name + ":\n"; output += " Trades: " + IntegerToString(strategies[i].count) + "\n"; output += " P&L: $" + DoubleToString(strategies[i].profit, 2) + "\n"; output += " Win Rate: " + DoubleToString(strategies[i].win_rate, 1) + "%\n"; output += " Avg R-Multiple: " + DoubleToString(strategies[i].avg_r_multiple, 2) + "\n"; } } //+------------------------------------------------------------------+ //| Generate JSON report | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::GenerateJSONReport(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance) { string timestamp = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES); StringReplace(timestamp, ":", "_"); StringReplace(timestamp, " ", "_"); string filename = m_report_path + "Report_" + timestamp + ".json"; int handle = FileOpen(filename, FILE_WRITE|FILE_TXT|FILE_ANSI); if(handle == INVALID_HANDLE) return; //--- Start JSON FileWrite(handle, "{"); FileWrite(handle, " \"report_info\": {"); FileWrite(handle, " \"timestamp\": \"" + TimeToString(TimeCurrent()) + "\","); FileWrite(handle, " \"report_type\": \"" + EnumToString(m_report_type) + "\","); FileWrite(handle, " \"version\": \"7.1\""); FileWrite(handle, " },"); //--- Performance metrics FileWrite(handle, " \"performance\": {"); FileWrite(handle, " \"net_profit\": " + DoubleToString(performance.net_profit, 2) + ","); FileWrite(handle, " \"total_trades\": " + IntegerToString(performance.total_trades) + ","); FileWrite(handle, " \"win_rate\": " + DoubleToString(performance.win_rate, 2) + ","); FileWrite(handle, " \"sharpe_ratio\": " + DoubleToString(performance.sharpe_ratio, 3) + ","); FileWrite(handle, " \"sortino_ratio\": " + DoubleToString(performance.sortino_ratio, 3) + ","); FileWrite(handle, " \"information_ratio\": " + DoubleToString(performance.information_ratio, 3) + ","); FileWrite(handle, " \"max_drawdown\": " + DoubleToString(performance.max_drawdown_percent, 2) + ","); FileWrite(handle, " \"var_95\": " + DoubleToString(performance.var_95, 2) + ","); FileWrite(handle, " \"cvar_95\": " + DoubleToString(performance.cvar_95, 2)); FileWrite(handle, " },"); //--- Trades array FileWrite(handle, " \"trades\": ["); int trade_count = ArraySize(trades); for(int i = 0; i < trade_count; i++) { FileWrite(handle, " {"); FileWrite(handle, " \"ticket\": " + IntegerToString(trades[i].ticket) + ","); FileWrite(handle, " \"symbol\": \"" + trades[i].symbol + "\","); FileWrite(handle, " \"type\": \"" + ((trades[i].type == POSITION_TYPE_BUY) ? "BUY" : "SELL") + "\","); FileWrite(handle, " \"volume\": " + DoubleToString(trades[i].volume, 2) + ","); FileWrite(handle, " \"profit\": " + DoubleToString(trades[i].profit, 2) + ","); FileWrite(handle, " \"risk_percent\": " + DoubleToString(trades[i].risk_percent, 2) + ","); FileWrite(handle, " \"r_multiple\": " + DoubleToString(trades[i].r_multiple, 2) + ","); FileWrite(handle, " \"ml_confidence\": " + DoubleToString(trades[i].ml_confidence, 3)); FileWrite(handle, " }" + ((i < trade_count - 1) ? "," : "")); } FileWrite(handle, " ]"); FileWrite(handle, "}"); FileClose(handle); } //+------------------------------------------------------------------+ //| Generate HTML report | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::GenerateHTMLReport(ManagedTradeV71 &trades[], PerformanceMetricsV71 &performance) { string timestamp = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES); StringReplace(timestamp, ":", "_"); StringReplace(timestamp, " ", "_"); string filename = m_report_path + "Report_" + timestamp + ".html"; int handle = FileOpen(filename, FILE_WRITE|FILE_TXT|FILE_ANSI); if(handle == INVALID_HANDLE) return; //--- HTML header FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, "ERMT 7.1 Institutional Report"); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); //--- Title FileWrite(handle, "

ERMT 7.1 Institutional Trading Report

"); FileWrite(handle, "

Generated: " + TimeToString(TimeCurrent()) + "

"); //--- Key metrics cards FileWrite(handle, "
"); FileWrite(handle, "
"); FileWrite(handle, "

Net P&L

"); FileWrite(handle, "

$" + DoubleToString(performance.net_profit, 2) + "

"); FileWrite(handle, "
"); FileWrite(handle, "
"); FileWrite(handle, "

Sharpe Ratio

"); FileWrite(handle, "

" + DoubleToString(performance.sharpe_ratio, 3) + "

"); FileWrite(handle, "
"); FileWrite(handle, "
"); FileWrite(handle, "

Win Rate

"); FileWrite(handle, "

" + DoubleToString(performance.win_rate, 1) + "%

"); FileWrite(handle, "
"); FileWrite(handle, "
"); FileWrite(handle, "

Max Drawdown

"); FileWrite(handle, "

" + DoubleToString(performance.max_drawdown_percent, 2) + "%

"); FileWrite(handle, "
"); FileWrite(handle, "
"); //--- Trades table FileWrite(handle, "

Active Positions

"); FileWrite(handle, ""); FileWrite(handle, ""); int trade_count = ArraySize(trades); for(int i = 0; i < trade_count; i++) { string pl_class = (trades[i].profit >= 0) ? "profit" : "loss"; FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); FileWrite(handle, ""); } FileWrite(handle, "
SymbolTypeVolumeEntryP&LRisk%R-Multiple
" + trades[i].symbol + "" + ((trades[i].type == POSITION_TYPE_BUY) ? "BUY" : "SELL") + "" + DoubleToString(trades[i].volume, 2) + "" + DoubleToString(trades[i].open_price, 5) + "$" + DoubleToString(trades[i].profit, 2) + "" + DoubleToString(trades[i].risk_percent, 2) + "%" + DoubleToString(trades[i].r_multiple, 2) + "
"); //--- Footer FileWrite(handle, "

ERMT 7.1 - Institutional Risk Management System

"); FileWrite(handle, ""); FileWrite(handle, ""); FileClose(handle); } //+------------------------------------------------------------------+ //| Check compliance | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::CheckCompliance(ManagedTradeV71 &trades[], ComplianceMetrics &metrics) { //--- Reset metrics metrics.violations_count = 0; metrics.max_position_breach = 0; metrics.max_drawdown_breach = 0; metrics.max_var_breach = 0; metrics.unauthorized_trades = 0; ArrayResize(metrics.violation_details, 0); //--- Check position limits double total_exposure = 0; int trade_count = ArraySize(trades); for(int i = 0; i < trade_count; i++) { total_exposure += trades[i].risk_percent; //--- Check individual position limit (example: 2% max) if(trades[i].risk_percent > 2.0) { metrics.violations_count++; metrics.max_position_breach = MathMax(metrics.max_position_breach, trades[i].risk_percent - 2.0); int size = ArraySize(metrics.violation_details); ArrayResize(metrics.violation_details, size + 1); metrics.violation_details[size] = "Position limit breach: " + trades[i].symbol + " at " + DoubleToString(trades[i].risk_percent, 2) + "%"; } //--- Check authorized magic numbers if(trades[i].magic < 10000 || trades[i].magic > 99999) { metrics.unauthorized_trades++; } } //--- Check total exposure limit (example: 6% max) if(total_exposure > 6.0) { metrics.violations_count++; int size = ArraySize(metrics.violation_details); ArrayResize(metrics.violation_details, size + 1); metrics.violation_details[size] = "Total exposure limit breach: " + DoubleToString(total_exposure, 2) + "%"; } //--- Update compliance tracking m_compliance = metrics; } //+------------------------------------------------------------------+ //| Generate VaR report | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::GenerateVaRReport(ManagedTradeV71 &trades[], double var, double cvar) { string timestamp = TimeToString(TimeCurrent(), TIME_DATE|TIME_MINUTES); StringReplace(timestamp, ":", "_"); StringReplace(timestamp, " ", "_"); string filename = m_report_path + "VaR_Report_" + timestamp + ".txt"; int handle = FileOpen(filename, FILE_WRITE|FILE_TXT|FILE_ANSI); if(handle == INVALID_HANDLE) return; FileWrite(handle, "VALUE AT RISK REPORT"); FileWrite(handle, "==================="); FileWrite(handle, ""); FileWrite(handle, "Report Date: " + TimeToString(TimeCurrent())); FileWrite(handle, ""); FileWrite(handle, "Portfolio VaR (95%): " + DoubleToString(var, 3) + "%"); FileWrite(handle, "Portfolio CVaR (95%): " + DoubleToString(cvar, 3) + "%"); FileWrite(handle, ""); FileWrite(handle, "VaR BY POSITION:"); FileWrite(handle, "----------------"); int trade_count = ArraySize(trades); double total_var = 0; for(int i = 0; i < trade_count; i++) { FileWrite(handle, trades[i].symbol + ": " + DoubleToString(trades[i].var_contribution, 3) + "%"); total_var += trades[i].var_contribution; } FileWrite(handle, ""); FileWrite(handle, "Total VaR Contribution: " + DoubleToString(total_var, 3) + "%"); FileWrite(handle, "Diversification Benefit: " + DoubleToString(total_var - var, 3) + "%"); FileClose(handle); } //+------------------------------------------------------------------+ //| Set export formats | //+------------------------------------------------------------------+ void CMultiTradeReporterV71::SetExportFormats(bool csv, bool html, bool json, bool fix) { m_csv_export = csv; m_html_export = html; m_json_export = json; m_fix_export = fix; } #endif // MULTI_TRADE_REPORTER_V71_MQH