Major upgrade making the AI loop visible and the project ready for public release. UI / UX - Live AI Thinking Feed: streams reasoning, decisions, and outcomes per iteration - Parameter Changes panel: prev → new + reason for every AI-driven edit - Validation Activity panel: out-of-sample + sensitivity runs with live metrics - Early Termination banner: surfaces why optimization stopped (targets met, no profit, budget, stuck, user stop) - 3-phase tracker renamed Exploration / Iteration / Validation with live N/total - Best Result modal exposes Evolution Path showing how the AI arrived at the winner - Run-detail modal accessible from every recent run row - Setup form validation (dates, walk-forward order, params selection, AI targets) - Pause button removed; misleading sidebar nav consolidated to Dashboard / New Run / Reports / Source Backend - AIGuidedLoop streams ai_thinking, param_changes, ai_targets_met, ai_stuck - Pipeline emits validation_start / validation_run_start / validation_run_complete / validation_done - Pipeline emits early_termination on every early-stop path - /api/best_result returns best run + full evolution chain - /api/run/<id> + /api/runs sorted by ts - AIReasoner falls back to ANTHROPIC_API_KEY env var when config is a placeholder - Demo mode (APEX_DEMO_MODE=1) generates deterministic synthetic backtests so judges can run end-to-end without MT5 Open-source readiness - README.md with pitch, demo flow, architecture diagram, quickstart, event reference - LICENSE (MIT) - config.example.yaml template (config.yaml now git-ignored) - requirements.txt: added anthropic / requests / psutil / beautifulsoup4, capped majors - .gitignore: secrets, *.set, scratch screenshots, ea_registry.yaml - demo/run_demo.py: one-command offline demo runner - 10 polished screenshots for README + judge review
457 lines
14 KiB
HTML
457 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>APEX — AI-Powered EA Optimizer</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--bg: #080d1a;
|
|
--accent: #4f46e5;
|
|
--accent2: #7c6dfa;
|
|
--teal: #00d4aa;
|
|
--text: #e2e8f0;
|
|
--muted: #64748b;
|
|
}
|
|
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
body {
|
|
font-family: 'Inter', sans-serif;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
min-height: 100vh;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
/* Grid overlay */
|
|
body::before {
|
|
content: '';
|
|
position: fixed; inset: 0;
|
|
background-image:
|
|
linear-gradient(rgba(0,212,170,0.03) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(0,212,170,0.03) 1px, transparent 1px);
|
|
background-size: 50px 50px;
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
}
|
|
|
|
/* Glow orb */
|
|
body::after {
|
|
content: '';
|
|
position: fixed;
|
|
top: 20%;
|
|
left: 10%;
|
|
width: 600px;
|
|
height: 600px;
|
|
background: radial-gradient(circle, rgba(79,70,229,0.08) 0%, transparent 70%);
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
}
|
|
|
|
.page {
|
|
position: relative;
|
|
z-index: 1;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 2rem;
|
|
}
|
|
|
|
/* Navbar */
|
|
.navbar {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 1.5rem 0;
|
|
margin-bottom: 4rem;
|
|
}
|
|
|
|
.nav-logo {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.nav-logo-text {
|
|
font-size: 1.25rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.05em;
|
|
background: linear-gradient(135deg, #fff 0%, #94a3b8 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
}
|
|
|
|
.status-pill {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.4rem 1rem;
|
|
background: rgba(255,255,255,0.05);
|
|
border: 1px solid rgba(255,255,255,0.1);
|
|
border-radius: 999px;
|
|
font-size: 0.8rem;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.status-dot {
|
|
width: 8px; height: 8px;
|
|
border-radius: 50%;
|
|
background: var(--muted);
|
|
flex-shrink: 0;
|
|
}
|
|
.status-dot.running {
|
|
background: var(--teal);
|
|
box-shadow: 0 0 8px var(--teal);
|
|
animation: pulse 1.5s infinite;
|
|
}
|
|
.status-dot.idle { background: #475569; }
|
|
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.5} }
|
|
|
|
/* Hero */
|
|
.hero {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 4rem;
|
|
align-items: center;
|
|
min-height: 70vh;
|
|
}
|
|
|
|
.hero-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
padding: 0.35rem 0.9rem;
|
|
background: rgba(79,70,229,0.15);
|
|
border: 1px solid rgba(79,70,229,0.3);
|
|
border-radius: 999px;
|
|
font-size: 0.72rem;
|
|
font-weight: 600;
|
|
color: var(--accent2);
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.hero-logo-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1.25rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.hero-title {
|
|
font-size: 5rem;
|
|
font-weight: 900;
|
|
letter-spacing: -0.04em;
|
|
line-height: 1;
|
|
background: linear-gradient(135deg, #ffffff 0%, #c7d2fe 50%, #00d4aa 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
}
|
|
|
|
.hero-subtitle-row {
|
|
font-size: 0.85rem;
|
|
font-weight: 700;
|
|
letter-spacing: 0.2em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.hero-tagline {
|
|
font-size: 1.5rem;
|
|
font-weight: 300;
|
|
color: #94a3b8;
|
|
margin-bottom: 2.5rem;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.hero-tagline strong {
|
|
color: var(--teal);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.hero-ctas {
|
|
display: flex;
|
|
gap: 1rem;
|
|
margin-bottom: 3rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.btn-primary {
|
|
display: inline-flex; align-items: center; gap: 0.5rem;
|
|
padding: 0.9rem 2rem;
|
|
background: linear-gradient(135deg, var(--accent), var(--accent2));
|
|
color: white; border: none; border-radius: 10px;
|
|
font-size: 0.95rem; font-weight: 700; cursor: pointer;
|
|
text-decoration: none; font-family: inherit;
|
|
box-shadow: 0 4px 24px rgba(79,70,229,0.4);
|
|
transition: all 0.2s;
|
|
}
|
|
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 8px 36px rgba(79,70,229,0.5); }
|
|
|
|
.btn-secondary {
|
|
display: inline-flex; align-items: center; gap: 0.5rem;
|
|
padding: 0.9rem 1.75rem;
|
|
background: rgba(255,255,255,0.06);
|
|
border: 1px solid rgba(255,255,255,0.12);
|
|
color: var(--text); border-radius: 10px;
|
|
font-size: 0.95rem; font-weight: 600;
|
|
text-decoration: none; font-family: inherit;
|
|
transition: all 0.2s;
|
|
}
|
|
.btn-secondary:hover { background: rgba(255,255,255,0.1); }
|
|
|
|
.hero-stats {
|
|
display: flex;
|
|
gap: 2rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.hero-stat { display: flex; flex-direction: column; }
|
|
.hero-stat-val {
|
|
font-size: 1.5rem; font-weight: 800;
|
|
background: linear-gradient(135deg, var(--teal), var(--accent2));
|
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
|
}
|
|
.hero-stat-lbl {
|
|
font-size: 0.72rem; color: var(--muted); margin-top: 0.1rem;
|
|
}
|
|
|
|
/* Features panel */
|
|
.features-panel {
|
|
background: rgba(15,22,41,0.8);
|
|
border: 1px solid rgba(255,255,255,0.1);
|
|
border-radius: 20px;
|
|
padding: 2rem;
|
|
backdrop-filter: blur(10px);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.features-panel::before {
|
|
content: 'APEX';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
font-size: 4rem;
|
|
font-weight: 900;
|
|
letter-spacing: 0.1em;
|
|
background: linear-gradient(135deg, #4f46e5, #00d4aa);
|
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
|
opacity: 0.15;
|
|
pointer-events: none;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.features-panel-title {
|
|
font-size: 0.75rem; font-weight: 700;
|
|
text-transform: uppercase; letter-spacing: 0.15em;
|
|
color: var(--muted); margin-bottom: 1.5rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.features-list { display: flex; flex-direction: column; gap: 1.25rem; }
|
|
|
|
.feature-item { display: flex; align-items: flex-start; gap: 1rem; }
|
|
|
|
.feature-icon-wrap {
|
|
width: 40px; height: 40px;
|
|
border-radius: 10px;
|
|
display: flex; align-items: center; justify-content: center;
|
|
flex-shrink: 0;
|
|
font-size: 1.1rem;
|
|
}
|
|
.feature-icon-wrap.purple { background: rgba(79,70,229,0.2); border: 1px solid rgba(79,70,229,0.3); }
|
|
.feature-icon-wrap.teal { background: rgba(0,212,170,0.15); border: 1px solid rgba(0,212,170,0.3); }
|
|
.feature-icon-wrap.blue { background: rgba(59,130,246,0.15); border: 1px solid rgba(59,130,246,0.3); }
|
|
.feature-icon-wrap.green { background: rgba(16,185,129,0.15); border: 1px solid rgba(16,185,129,0.3); }
|
|
|
|
.feature-name {
|
|
font-size: 0.72rem; font-weight: 700;
|
|
letter-spacing: 0.1em; text-transform: uppercase;
|
|
margin-bottom: 0.2rem;
|
|
}
|
|
.feature-name.purple { color: var(--accent2); }
|
|
.feature-name.teal { color: var(--teal); }
|
|
.feature-name.blue { color: #60a5fa; }
|
|
.feature-name.green { color: #34d399; }
|
|
|
|
.feature-desc { font-size: 0.8rem; color: #94a3b8; line-height: 1.5; }
|
|
|
|
/* Footer */
|
|
.footer {
|
|
margin-top: 4rem;
|
|
padding-top: 2rem;
|
|
border-top: 1px solid rgba(255,255,255,0.06);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
color: var(--muted);
|
|
font-size: 0.8rem;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.hero { grid-template-columns: 1fr; min-height: auto; }
|
|
.hero-title { font-size: 3rem; }
|
|
.features-panel { display: none; }
|
|
.hero-stats { gap: 1.25rem; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="page">
|
|
|
|
<!-- Navbar -->
|
|
<nav class="navbar">
|
|
<div class="nav-logo">
|
|
<svg width="32" height="32" viewBox="0 0 36 36" fill="none">
|
|
<polygon points="18,2 34,32 2,32" fill="url(#logoGradL)" opacity="0.15"/>
|
|
<polygon points="18,8 30,30 6,30" fill="url(#logoGradL)" opacity="0.3"/>
|
|
<path d="M18 6L22 14H14L18 6Z" fill="url(#logoGradL)"/>
|
|
<rect x="11" y="22" width="3" height="8" rx="1" fill="#00d4aa"/>
|
|
<rect x="16" y="18" width="3" height="12" rx="1" fill="#00d4aa" opacity="0.8"/>
|
|
<rect x="21" y="14" width="3" height="16" rx="1" fill="#00d4aa" opacity="0.6"/>
|
|
<defs>
|
|
<linearGradient id="logoGradL" x1="0" y1="0" x2="1" y2="1">
|
|
<stop offset="0%" stop-color="#4f46e5"/>
|
|
<stop offset="100%" stop-color="#00d4aa"/>
|
|
</linearGradient>
|
|
</defs>
|
|
</svg>
|
|
<span class="nav-logo-text">APEX</span>
|
|
</div>
|
|
<div class="status-pill" id="status-pill">
|
|
<div class="status-dot idle" id="status-dot"></div>
|
|
<span id="status-text">Ready</span>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Hero -->
|
|
<div class="hero">
|
|
<div class="hero-left">
|
|
<div class="hero-badge">✦ Hackathon Edition 2026</div>
|
|
|
|
<div class="hero-logo-row">
|
|
<svg width="72" height="72" viewBox="0 0 72 72" fill="none">
|
|
<polygon points="36,4 68,64 4,64" fill="url(#heroGrad)" opacity="0.12"/>
|
|
<polygon points="36,16 60,60 12,60" fill="url(#heroGrad)" opacity="0.25"/>
|
|
<path d="M36 12L44 28H28L36 12Z" fill="url(#heroGrad)"/>
|
|
<path d="M33 20L36 13L39 20" stroke="#00d4aa" stroke-width="1.5" fill="none" stroke-linecap="round"/>
|
|
<rect x="22" y="44" width="6" height="16" rx="2" fill="#00d4aa" opacity="0.9"/>
|
|
<rect x="33" y="36" width="6" height="24" rx="2" fill="#00d4aa" opacity="0.7"/>
|
|
<rect x="44" y="28" width="6" height="32" rx="2" fill="#00d4aa" opacity="0.5"/>
|
|
<defs>
|
|
<linearGradient id="heroGrad" x1="0" y1="0" x2="1" y2="1">
|
|
<stop offset="0%" stop-color="#4f46e5"/>
|
|
<stop offset="100%" stop-color="#7c6dfa"/>
|
|
</linearGradient>
|
|
</defs>
|
|
</svg>
|
|
</div>
|
|
|
|
<div class="hero-title">APEX</div>
|
|
<div class="hero-subtitle-row">AI Powered EA Optimizer</div>
|
|
|
|
<div class="hero-tagline">
|
|
Optimize. <strong>Understand.</strong> Evolve.<br>
|
|
<span style="font-size:1rem">The first optimizer that tells you <em>why</em> — not just what.</span>
|
|
</div>
|
|
|
|
<div class="hero-ctas">
|
|
<a href="/setup" class="btn-primary">⚡ Start Optimizing →</a>
|
|
<a href="/dashboard" class="btn-secondary">📊 Live Dashboard</a>
|
|
<a href="/reports" class="btn-secondary">📋 Reports</a>
|
|
</div>
|
|
|
|
<div class="hero-stats">
|
|
<div class="hero-stat">
|
|
<div class="hero-stat-val">3</div>
|
|
<div class="hero-stat-lbl">Phase Pipeline</div>
|
|
</div>
|
|
<div class="hero-stat">
|
|
<div class="hero-stat-val">AI</div>
|
|
<div class="hero-stat-lbl">Claude-Powered</div>
|
|
</div>
|
|
<div class="hero-stat">
|
|
<div class="hero-stat-val">IS/OOS</div>
|
|
<div class="hero-stat-lbl">Walk-Forward Validated</div>
|
|
</div>
|
|
<div class="hero-stat">
|
|
<div class="hero-stat-val">Any EA</div>
|
|
<div class="hero-stat-lbl">Works with any .set file</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="hero-right">
|
|
<div class="features-panel">
|
|
<div class="features-panel-title">What makes APEX different</div>
|
|
<div class="features-list">
|
|
|
|
<div class="feature-item">
|
|
<div class="feature-icon-wrap purple">🧠</div>
|
|
<div>
|
|
<div class="feature-name purple">AI Reasoning</div>
|
|
<div class="feature-desc">Analyzes results, detects patterns and explains performance in plain language using Claude AI.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="feature-item">
|
|
<div class="feature-icon-wrap teal">🎯</div>
|
|
<div>
|
|
<div class="feature-name teal">Smart Optimization</div>
|
|
<div class="feature-desc">Finds the best parameters using 3-phase search: broad discovery → refinement → out-of-sample validation.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="feature-item">
|
|
<div class="feature-icon-wrap blue" style="font-size:0.85rem;font-weight:700;font-family:monospace;color:#60a5fa"></></div>
|
|
<div>
|
|
<div class="feature-name blue">Strategy Evolution</div>
|
|
<div class="feature-desc">Suggests improvements and helps evolve your trading systems based on behavioral pattern analysis.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="feature-item">
|
|
<div class="feature-icon-wrap green">🛡</div>
|
|
<div>
|
|
<div class="feature-name green">Robust & Reliable</div>
|
|
<div class="feature-desc">Built-in validation (IS/OOS/WFV) and sensitivity testing to ensure real market reliability.</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="footer">
|
|
<span>APEX — AI-Powered EA Optimizer</span>
|
|
<span>Powered by Claude AI + MetaTrader 5</span>
|
|
</footer>
|
|
</div>
|
|
|
|
<script>
|
|
// Fetch optimizer status and update the live pill
|
|
fetch('/api/status')
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(s) {
|
|
var dot = document.getElementById('status-dot');
|
|
var txt = document.getElementById('status-text');
|
|
if (s.state === 'running') {
|
|
dot.className = 'status-dot running';
|
|
txt.textContent = 'Running: ' + (s.phase || '') + ' (' + (s.run_count || 0) + ' runs)';
|
|
} else if (s.verdict) {
|
|
dot.className = 'status-dot';
|
|
dot.style.background = '#10b981';
|
|
txt.textContent = 'Last: ' + s.verdict;
|
|
}
|
|
})
|
|
.catch(function() {});
|
|
</script>
|
|
</body>
|
|
</html>
|