Initial commit: MT5 EA Optimizer v1.0
Full optimization system for LEGSTECH_EA_V2: - Flask + SocketIO live dashboard (dark premium UI) - MT5 process control (auto-kill, clean launch, retry) - HTML report parser (UTF-16 LE, 597 trades, metrics) - Pre-run validation and actionable error messages - Analysis engines: Reversal, TimePerfomance, EntryExit, EquityCurve - Composite scoring (Calmar-primary) - Mutation engine with knowledge_base.yaml - Validation gate: IS + Walk-Forward - Reports folder with HTML/CSV per run - Double-click launcher batch file
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MT5 EA Optimizer — Live Dashboard</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- ── HEADER ── -->
|
||||
<header class="header">
|
||||
<div class="header-left">
|
||||
<div class="logo">
|
||||
<span class="logo-icon">⚡</span>
|
||||
<div>
|
||||
<div class="logo-title">MT5 EA Optimizer</div>
|
||||
<div class="logo-sub">LEGSTECH_EA_V2 · XAUUSD · H1</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<div class="stat-pill" id="pill-state">
|
||||
<span class="dot dot-idle" id="state-dot"></span>
|
||||
<span id="state-label">Ready</span>
|
||||
</div>
|
||||
<div class="stat-pill">
|
||||
<span class="pill-label">Iteration</span>
|
||||
<span class="pill-val" id="hdr-iter">0</span>
|
||||
</div>
|
||||
<div class="stat-pill">
|
||||
<span class="pill-label">Best Score</span>
|
||||
<span class="pill-val score-val" id="hdr-score">—</span>
|
||||
</div>
|
||||
<div class="stat-pill">
|
||||
<span class="pill-label">Elapsed</span>
|
||||
<span class="pill-val" id="hdr-elapsed">0:00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button class="btn btn-secondary" id="btn-reports" onclick="window.open('/reports','_blank')">
|
||||
📁 Reports
|
||||
</button>
|
||||
<button class="btn btn-pause hidden" id="btn-pause" onclick="pauseOptimizer()">
|
||||
⏸ Pause
|
||||
</button>
|
||||
<button class="btn btn-stop hidden" id="btn-stop" onclick="stopOptimizer()">
|
||||
⏹ Stop
|
||||
</button>
|
||||
<button class="btn btn-start" id="btn-start" onclick="startOptimizer()">
|
||||
▶ Start Optimizer
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ── MAIN GRID ── -->
|
||||
<main class="main-grid">
|
||||
|
||||
<!-- LEFT COLUMN -->
|
||||
<div class="col-left">
|
||||
|
||||
<!-- Score Chart -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">📈 Score History</span>
|
||||
<span class="card-badge" id="chart-badge">Waiting...</span>
|
||||
</div>
|
||||
<div class="chart-wrap">
|
||||
<canvas id="scoreChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Current Run Metrics -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">🎯 Current Run Metrics</span>
|
||||
<span class="run-id-badge" id="current-run-id">—</span>
|
||||
</div>
|
||||
<div class="metrics-grid">
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">Net Profit</div>
|
||||
<div class="metric-val" id="m-profit">—</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">Calmar Ratio</div>
|
||||
<div class="metric-val" id="m-calmar">—</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">Profit Factor</div>
|
||||
<div class="metric-val" id="m-pf">—</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">Max Drawdown</div>
|
||||
<div class="metric-val" id="m-dd">—</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">Win Rate</div>
|
||||
<div class="metric-val" id="m-wr">—</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">Total Trades</div>
|
||||
<div class="metric-val" id="m-trades">—</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">MFE Capture</div>
|
||||
<div class="metric-val" id="m-mfe">—</div>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<div class="metric-label">Reversal Rate</div>
|
||||
<div class="metric-val" id="m-rev">—</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-bar-wrap">
|
||||
<div class="score-bar-label">
|
||||
<span>Composite Score</span>
|
||||
<span class="score-big" id="m-score">—</span>
|
||||
</div>
|
||||
<div class="score-bar-track">
|
||||
<div class="score-bar-fill" id="score-bar-fill" style="width:0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- RIGHT COLUMN -->
|
||||
<div class="col-right">
|
||||
|
||||
<!-- Phase tracker -->
|
||||
<div class="card phase-card">
|
||||
<div class="phase-steps">
|
||||
<div class="phase-step" id="phase-baseline">
|
||||
<div class="phase-dot"></div>
|
||||
<div class="phase-name">Baseline</div>
|
||||
</div>
|
||||
<div class="phase-line"></div>
|
||||
<div class="phase-step" id="phase-analyze">
|
||||
<div class="phase-dot"></div>
|
||||
<div class="phase-name">Analyze</div>
|
||||
</div>
|
||||
<div class="phase-line"></div>
|
||||
<div class="phase-step" id="phase-explore">
|
||||
<div class="phase-dot"></div>
|
||||
<div class="phase-name">Test</div>
|
||||
</div>
|
||||
<div class="phase-line"></div>
|
||||
<div class="phase-step" id="phase-validate">
|
||||
<div class="phase-dot"></div>
|
||||
<div class="phase-name">Validate</div>
|
||||
</div>
|
||||
<div class="phase-line"></div>
|
||||
<div class="phase-step" id="phase-oos">
|
||||
<div class="phase-dot"></div>
|
||||
<div class="phase-name">OOS</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Findings feed -->
|
||||
<div class="card findings-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">🔍 Analysis Findings</span>
|
||||
<span class="card-badge" id="findings-count">0 findings</span>
|
||||
</div>
|
||||
<div class="findings-feed" id="findings-feed">
|
||||
<div class="finding-empty">Findings will appear here after each analysis run...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Parameter changes -->
|
||||
<div class="card params-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">🔧 Parameter Changes</span>
|
||||
<span class="card-badge" id="hyp-badge">Waiting...</span>
|
||||
</div>
|
||||
<div class="hyp-desc" id="hyp-desc">No hypothesis being tested yet.</div>
|
||||
<div class="params-table-wrap" id="params-table-wrap">
|
||||
<table class="params-table">
|
||||
<thead><tr><th>Parameter</th><th>Before</th><th>After</th></tr></thead>
|
||||
<tbody id="params-tbody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Live log -->
|
||||
<div class="card log-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">📋 Live Log</span>
|
||||
<button class="clear-btn" onclick="clearLog()">Clear</button>
|
||||
</div>
|
||||
<div class="log-feed" id="log-feed">
|
||||
<div class="log-line log-info">System ready. Click Start Optimizer to begin.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- ── CANDIDATES PANEL ── -->
|
||||
<section class="candidates-section">
|
||||
<div class="card candidates-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">🏆 Promoted Candidates</span>
|
||||
<span class="card-badge" id="cand-count">0 candidates</span>
|
||||
</div>
|
||||
<div class="candidates-list" id="candidates-list">
|
||||
<div class="cand-empty">Validated candidates will appear here...</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ── SCRIPTS ── -->
|
||||
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<script src="/static/js/dashboard.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,192 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Run {{ run_id }} — MT5 Optimizer Report</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=JetBrains+Mono&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { background: #0a0d14; color: #e2e8f8; font-family: 'Inter', sans-serif; font-size: 13px; padding: 32px; }
|
||||
h1 { font-size: 22px; font-weight: 800; margin-bottom: 4px; }
|
||||
.sub { color: #6b7fa3; font-size: 12px; font-family: 'JetBrains Mono', monospace; margin-bottom: 24px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 28px; }
|
||||
.card { background: #111621; border: 1px solid #1e2740; border-radius: 10px; padding: 14px 18px; }
|
||||
.card-label { font-size: 10px; color: #6b7fa3; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
|
||||
.card-val { font-size: 24px; font-weight: 700; font-family: 'JetBrains Mono', monospace; }
|
||||
.green { color: #22d3a5; } .red { color: #f44; } .blue { color: #4f8ef7; }
|
||||
.section-title { font-size: 14px; font-weight: 700; margin: 24px 0 12px; border-left: 3px solid #4f8ef7; padding-left: 10px; }
|
||||
table { width: 100%; border-collapse: collapse; font-size: 12px; margin-bottom: 24px; }
|
||||
th { text-align: left; padding: 8px 12px; color: #6b7fa3; font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; border-bottom: 1px solid #1e2740; }
|
||||
td { padding: 8px 12px; border-bottom: 1px solid rgba(30,39,64,0.4); font-family: 'JetBrains Mono', monospace; }
|
||||
tr:hover td { background: rgba(79,142,247,0.04); }
|
||||
.badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 700; }
|
||||
.high { background: rgba(244,68,68,0.15); color: #f44; }
|
||||
.medium { background: rgba(251,191,36,0.15); color: #fbbf24; }
|
||||
.low { background: rgba(79,142,247,0.1); color: #4f8ef7; }
|
||||
.win { color: #22d3a5; } .loss { color: #f44; } .reversal { color: #fbbf24; }
|
||||
.score-big { font-size: 48px; font-weight: 800; color: #22d3a5; text-align: center; padding: 20px 0; }
|
||||
.back-link { display: inline-block; margin-bottom: 20px; color: #4f8ef7; text-decoration: none; font-size: 12px; }
|
||||
.back-link:hover { text-decoration: underline; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a class="back-link" href="javascript:history.back()">← Back to Dashboard</a>
|
||||
<h1>Run Report: {{ run_id }}</h1>
|
||||
<div class="sub">Generated: {{ generated }} · Phase: {{ summary.phase }}</div>
|
||||
|
||||
<!-- Score -->
|
||||
<div class="score-big">{{ "%.4f"|format(summary.score) }}</div>
|
||||
|
||||
<!-- Key Metrics -->
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<div class="card-label">Net Profit</div>
|
||||
<div class="card-val {% if metrics.net_profit >= 0 %}green{% else %}red{% endif %}">
|
||||
${{ "%.2f"|format(metrics.net_profit) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Calmar Ratio</div>
|
||||
<div class="card-val blue">{{ "%.3f"|format(metrics.calmar_ratio) }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Profit Factor</div>
|
||||
<div class="card-val {% if metrics.profit_factor >= 1.3 %}green{% else %}red{% endif %}">
|
||||
{{ "%.3f"|format(metrics.profit_factor) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Max Drawdown</div>
|
||||
<div class="card-val red">{{ "%.1f"|format(metrics.max_drawdown_pct * 100) }}%</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Win Rate</div>
|
||||
<div class="card-val">{{ "%.1f"|format(metrics.win_rate * 100) }}%</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Total Trades</div>
|
||||
<div class="card-val">{{ metrics.total_trades }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Sharpe Ratio</div>
|
||||
<div class="card-val">{{ "%.3f"|format(metrics.sharpe_ratio) }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Recovery Factor</div>
|
||||
<div class="card-val">{{ "%.2f"|format(metrics.recovery_factor) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if metrics.avg_mfe_capture is not none %}
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<div class="card-label">MFE Capture</div>
|
||||
<div class="card-val green">{{ "%.1f"|format(metrics.avg_mfe_capture * 100) }}%</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Reversal Rate</div>
|
||||
<div class="card-val {% if (metrics.reversal_rate or 0) > 0.2 %}red{% else %}green{% endif %}">
|
||||
{{ "%.1f"|format((metrics.reversal_rate or 0) * 100) }}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Avg MFE Pips</div>
|
||||
<div class="card-val">{{ "%.1f"|format(metrics.avg_mfe_pips or 0) }}</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-label">Avg MAE Pips</div>
|
||||
<div class="card-val">{{ "%.1f"|format(metrics.avg_mae_pips or 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Score vs Baseline -->
|
||||
{% if baseline_score %}
|
||||
<div class="card" style="margin-bottom:24px">
|
||||
<div class="card-label">Score vs Baseline</div>
|
||||
<div style="font-size:18px;font-weight:700;font-family:'JetBrains Mono',monospace;margin-top:6px">
|
||||
{{ "%.4f"|format(baseline_score) }} →
|
||||
<span class="{% if summary.score > baseline_score %}green{% else %}red{% endif %}">
|
||||
{{ "%.4f"|format(summary.score) }}
|
||||
({{ "%+.4f"|format(summary.score - baseline_score) }})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Hypothesis info -->
|
||||
{% if hypothesis %}
|
||||
<div class="section-title">Hypothesis</div>
|
||||
<div class="card" style="margin-bottom:24px">
|
||||
<div style="margin-bottom:8px;font-weight:600">{{ hypothesis.description }}</div>
|
||||
<div style="color:#6b7fa3;font-size:11px">Strategy: {{ hypothesis.strategy }} · Rule: {{ hypothesis.kb_rule_id }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Findings -->
|
||||
{% if findings %}
|
||||
<div class="section-title">Analysis Findings ({{ findings|length }})</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Analyzer</th><th>Severity</th><th>Confidence</th><th>Finding</th><th>Est. Impact</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for f in findings %}
|
||||
<tr>
|
||||
<td>{{ f.analyzer }}</td>
|
||||
<td><span class="badge {{ f.severity }}">{{ f.severity.upper() }}</span></td>
|
||||
<td>{{ "%.0f"|format(f.confidence * 100) }}%</td>
|
||||
<td style="max-width:400px;white-space:normal;font-family:'Inter',sans-serif">{{ f.description }}</td>
|
||||
<td>${{ "%.0f"|format(f.impact_estimate_pnl) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
<!-- Parameters -->
|
||||
{% if params %}
|
||||
<div class="section-title">Parameter Configuration</div>
|
||||
<table>
|
||||
<thead><tr><th>Parameter</th><th>Value</th><th>Changed</th></tr></thead>
|
||||
<tbody>
|
||||
{% for p in params %}
|
||||
<tr>
|
||||
<td {% if p.changed %}class="green"{% endif %}>{{ p.name }}</td>
|
||||
<td {% if p.changed %}class="green"{% endif %}>{{ p.new }}</td>
|
||||
<td>{% if p.changed %}✅ {{ p.old }} → {{ p.new }}{% else %}—{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
<!-- Trade sample -->
|
||||
{% if trades_sample %}
|
||||
<div class="section-title">Trade Sample (first 50)</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>#</th><th>Open</th><th>Close</th><th>Dir</th><th>Net $</th><th>MFE pip</th><th>MAE pip</th><th>Session</th><th>Result</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for t in trades_sample %}
|
||||
<tr>
|
||||
<td>{{ loop.index }}</td>
|
||||
<td>{{ t.open_time }}</td>
|
||||
<td>{{ t.close_time }}</td>
|
||||
<td>{{ t.direction }}</td>
|
||||
<td class="{% if t.net_money >= 0 %}win{% else %}loss{% endif %}">
|
||||
${{ "%.2f"|format(t.net_money) }}
|
||||
</td>
|
||||
<td>{{ t.mfe_pips or '—' }}</td>
|
||||
<td>{{ t.mae_pips or '—' }}</td>
|
||||
<td>{{ t.session or '—' }}</td>
|
||||
<td class="{{ t.result_class or '' }}">{{ t.result_class or '—' }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,93 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Reports — MT5 Optimizer</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { background: #0a0d14; color: #e2e8f8; font-family: 'Inter', sans-serif; font-size: 13px; padding: 32px; }
|
||||
header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 32px; }
|
||||
h1 { font-size: 22px; font-weight: 800; }
|
||||
.sub { color: #6b7fa3; font-size: 12px; margin-top: 4px; }
|
||||
.back-link { color: #4f8ef7; text-decoration: none; font-size: 12px; }
|
||||
.back-link:hover { text-decoration: underline; }
|
||||
.empty { color: #3d4f70; text-align: center; padding: 80px 0; font-size: 16px; }
|
||||
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
|
||||
.run-card {
|
||||
background: #111621; border: 1px solid #1e2740; border-radius: 12px; padding: 18px 20px;
|
||||
transition: border-color 0.2s, transform 0.2s;
|
||||
text-decoration: none; color: inherit; display: block;
|
||||
}
|
||||
.run-card:hover { border-color: #4f8ef7; transform: translateY(-2px); }
|
||||
.run-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
|
||||
.run-id { font-family: 'JetBrains Mono', monospace; font-size: 11px; color: #6b7fa3; }
|
||||
.run-score { font-size: 28px; font-weight: 800; font-family: 'JetBrains Mono', monospace; color: #22d3a5; }
|
||||
.run-phase { font-size: 10px; padding: 2px 8px; border-radius: 4px; background: rgba(79,142,247,0.15); color: #4f8ef7; font-weight: 700; text-transform: uppercase; }
|
||||
.metrics-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 10px; }
|
||||
.m { text-align: center; background: #161c2a; border-radius: 6px; padding: 6px 8px; }
|
||||
.m-label { font-size: 9px; color: #6b7fa3; text-transform: uppercase; letter-spacing: 0.5px; }
|
||||
.m-val { font-size: 14px; font-weight: 700; font-family: 'JetBrains Mono', monospace; margin-top: 2px; }
|
||||
.delta-up { color: #22d3a5; } .delta-dn { color: #f44; }
|
||||
.run-ts { font-size: 10px; color: #3d4f70; margin-top: 10px; font-family: 'JetBrains Mono', monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div>
|
||||
<h1>📁 Optimization Reports</h1>
|
||||
<div class="sub">{{ runs|length }} run(s) recorded · Click any card to open the full report</div>
|
||||
</div>
|
||||
<a class="back-link" href="/">← Back to Dashboard</a>
|
||||
</header>
|
||||
|
||||
{% if not runs %}
|
||||
<div class="empty">No reports yet.<br>Start the optimizer to generate your first run report.</div>
|
||||
{% else %}
|
||||
<div class="cards">
|
||||
{% for r in runs %}
|
||||
<a class="run-card" href="/reports/{{ r.run_id }}/summary.html" target="_blank">
|
||||
<div class="run-header">
|
||||
<div>
|
||||
<div class="run-id">{{ r.run_id }}</div>
|
||||
<div class="run-score">{{ "%.4f"|format(r.score) }}</div>
|
||||
</div>
|
||||
<span class="run-phase">{{ r.phase }}</span>
|
||||
</div>
|
||||
<div class="metrics-row">
|
||||
<div class="m">
|
||||
<div class="m-label">Net Profit</div>
|
||||
<div class="m-val {% if r.net_profit >= 0 %}delta-up{% else %}delta-dn{% endif %}">
|
||||
${{ "%.0f"|format(r.net_profit) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="m">
|
||||
<div class="m-label">Calmar</div>
|
||||
<div class="m-val">{{ "%.2f"|format(r.calmar) }}</div>
|
||||
</div>
|
||||
<div class="m">
|
||||
<div class="m-label">Drawdown</div>
|
||||
<div class="m-val delta-dn">{{ "%.1f"|format(r.drawdown_pct) }}%</div>
|
||||
</div>
|
||||
<div class="m">
|
||||
<div class="m-label">PF</div>
|
||||
<div class="m-val">{{ "%.2f"|format(r.profit_factor) }}</div>
|
||||
</div>
|
||||
<div class="m">
|
||||
<div class="m-label">Trades</div>
|
||||
<div class="m-val">{{ r.total_trades }}</div>
|
||||
</div>
|
||||
<div class="m">
|
||||
<div class="m-label">Score Δ</div>
|
||||
<div class="m-val {% if r.score_delta >= 0 %}delta-up{% else %}delta-dn{% endif %}">
|
||||
{{ "%+.4f"|format(r.score_delta) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="run-ts">{{ r.ts[:19].replace("T"," ") }} UTC</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user