From e58a4a425f22ba32085c906a1f1242100301193e Mon Sep 17 00:00:00 2001 From: Garfield Date: Sat, 21 Mar 2026 19:42:16 -0400 Subject: [PATCH] Add export-to-browser utility - export-report-html.py: Converts MT5 report to clean, styled HTML - export-to-browser.sh: Wrapper script for easy usage - Generates beautiful HTML report viewable in any browser - Includes performance summary, trade stats, and risk metrics --- export-report-html.py | 381 ++++++++++++++++++++++++++++++++++++++++++ export-to-browser.sh | 38 +++++ 2 files changed, 419 insertions(+) create mode 100755 export-report-html.py create mode 100755 export-to-browser.sh diff --git a/export-report-html.py b/export-report-html.py new file mode 100755 index 0000000..47e4ef1 --- /dev/null +++ b/export-report-html.py @@ -0,0 +1,381 @@ +#!/usr/bin/env python3 +"""Export MT5 HTML report to a clean, browser-viewable HTML file""" + +import re +import sys +import os +from datetime import datetime + +def parse_report(html_file): + """Parse MT5 HTML report and extract data""" + try: + with open(html_file, 'rb') as f: + content = f.read().decode('utf-16-le', errors='ignore') + except Exception as e: + print(f"Error reading file: {e}") + return None + + # Clean text for parsing + text = re.sub('<[^<]+?>', ' ', content) + text = text.replace(' ', ' ') + + def extract_value(pattern, text, group=1): + match = re.search(pattern, text) + return match.group(group).strip() if match else "N/A" + + def parse_num(s): + if not s or s == "N/A": + return 0 + try: + s = str(s).replace(' ', '').replace(',', '.') + parts = s.split('.') + if len(parts) > 2: + s = ''.join(parts[:-1]) + '.' + parts[-1] + return float(s) + except: + return 0 + + data = { + 'filename': os.path.basename(html_file), + 'account': extract_value(r'Account:\s*(\d+)', text), + 'name': extract_value(r'Name:\s*([^\d]+?)(?:\s+Account|\s*$)', text), + 'company': extract_value(r'Company:\s*([^\d]+?)(?:\s+Date|\s*$)', text), + 'net_profit': extract_value(r'Total Net Profit[^\d\-]*([\-\d\s,\.]+)', text), + 'gross_profit': extract_value(r'Gross Profit[^\d]*([\d\s,\.]+)', text), + 'gross_loss': extract_value(r'Gross Loss[^\d\-]*([\-\d\s,\.]+)', text), + 'profit_factor': extract_value(r'Profit Factor[^\d]*([\d\.]+)', text), + 'expected_payoff': extract_value(r'Expected Payoff[^\d]*([\d\s,\.]+)', text), + 'total_trades': extract_value(r'Total Trades[^\d]*(\d+)', text), + 'profit_trades': extract_value(r'Profit Trades \(%[^)]*\)[^\d]*(\d+)', text), + 'loss_trades': extract_value(r'Loss Trades \(%[^)]*\)[^\d]*(\d+)', text), + 'win_pct': extract_value(r'Profit Trades \(%[^)]*\)[^\d]*\d+[^\d]*\((\d+\.?\d*)%', text), + 'largest_profit': extract_value(r'Largest profit trade[^\d]*([\d\s,\.]+)', text), + 'largest_loss': extract_value(r'Largest loss trade[^\d\-]*([\-\d\s,\.]+)', text), + 'max_drawdown': extract_value(r'Balance Drawdown Maximal[^\d]*([\d\s,\.]+)', text), + } + + # Calculate values + net = parse_num(data['net_profit']) + data['starting_balance'] = 100000.00 + data['current_balance'] = 100000.00 + net + data['return_pct'] = (net / 100000.00) * 100 + + return data + +def generate_html(data, output_file): + """Generate clean HTML report""" + + html_content = f''' + + + + + MT5 Trading Report - Account {data['account']} + + + +
+
+

📊 MT5 Trading Report

+

Account {data['account']} | {data['name']} | Generated on {datetime.now().strftime('%Y-%m-%d %H:%M')}

+
+ +
+ +
+

💰 Performance Summary

+
+
{'+' if data['return_pct'] > 0 else ''}{data['return_pct']:.2f}%
+
Total Return
+
+ +
+
+
Starting Balance
+
${data['starting_balance']:,.2f}
+
+
+
Current Balance
+
${data['current_balance']:,.2f}
+
+
+
Net Profit
+
${data['net_profit']}
+
+
+
Profit Factor
+
{data['profit_factor']}
+
+
+
Gross Profit
+
${data['gross_profit']}
+
+
+
Gross Loss
+
${data['gross_loss']}
+
+
+
+ + +
+

📈 Trade Statistics

+
+
+
{data['total_trades']}
+
Total Trades
+
+
+
{data['profit_trades']}
+
Winning Trades
+
+
+
{data['loss_trades']}
+
Losing Trades
+
+
+
{data['win_pct']}%
+
Win Rate
+
+
+
${data['largest_profit']}
+
Largest Win
+
+
+
${data['largest_loss']}
+
Largest Loss
+
+
+
+ + +
+

⚠️ Risk Metrics

+
+
+
Expected Payoff
+
${data['expected_payoff']}
+
+
+
Max Drawdown
+
${data['max_drawdown']}
+
+
+
+
+ + +
+ +''' + + with open(output_file, 'w', encoding='utf-8') as f: + f.write(html_content) + + return output_file + +def main(): + # Find latest report if no argument provided + if len(sys.argv) > 1: + report_file = sys.argv[1] + else: + report_dir = os.path.expanduser("~/mt5-docker/config/.wine/drive_c/users/abc/Desktop") + import glob + reports = glob.glob(f"{report_dir}/ReportHistory-*.html") + if not reports: + print("❌ No report files found!") + print(f"Searched: {report_dir}") + sys.exit(1) + report_file = max(reports, key=os.path.getmtime) + + if not os.path.exists(report_file): + print(f"❌ File not found: {report_file}") + sys.exit(1) + + print(f"📊 Parsing report: {os.path.basename(report_file)}") + + data = parse_report(report_file) + if not data: + print("❌ Failed to parse report") + sys.exit(1) + + # Generate output filename + timestamp = datetime.now().strftime('%Y%m%d-%H%M%S') + output_file = os.path.expanduser(f"~/mt5-report-{data['account']}-{timestamp}.html") + + # Generate HTML + generate_html(data, output_file) + + print(f"✅ Report exported to: {output_file}") + print("") + print(f"📊 Summary:") + print(f" Account: {data['account']}") + print(f" Name: {data['name']}") + print(f" Profit: ${data['net_profit']}") + print(f" Return: {data['return_pct']:.2f}%") + print(f" Win Rate: {data['win_pct']}%") + print("") + print("🌐 Open in browser:") + print(f" file://{output_file}") + + return output_file + +if __name__ == "__main__": + main() diff --git a/export-to-browser.sh b/export-to-browser.sh new file mode 100755 index 0000000..6fde3c8 --- /dev/null +++ b/export-to-browser.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# export-to-browser.sh - Export MT5 report to browser-viewable HTML +# Usage: ./export-to-browser.sh [path/to/report.html] + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${BLUE}=== MT5 Report to Browser Export ===${NC}" +echo "" + +# Run the Python exporter +if [ -f "${SCRIPT_DIR}/export-report-html.py" ]; then + OUTPUT=$(python3 "${SCRIPT_DIR}/export-report-html.py" "$@" 2>&1) + echo "$OUTPUT" + + # Extract the output file path + OUTPUT_FILE=$(echo "$OUTPUT" | grep "Report exported to:" | sed 's/.*exported to: //') + + if [ -n "$OUTPUT_FILE" ] && [ -f "$OUTPUT_FILE" ]; then + echo "" + echo -e "${GREEN}✅ Export complete!${NC}" + echo "" + echo "To view in browser:" + echo " 1. Copy the HTML file to your local machine" + echo " 2. Open it in any web browser" + echo "" + echo "Or on this server with a text browser:" + echo " lynx $OUTPUT_FILE" + echo " w3m $OUTPUT_FILE" + fi +else + echo "❌ export-report-html.py not found" + exit 1 +fi