Refresh-during-run no longer wipes the dashboard
- pipeline now keeps in-memory rolling logs of ai_thinking, param_changes,
validation events, and the current early-termination state. Logs reset at
the start of each new run (capped: 200 thinking / 50 param-change records /
40 validation events)
- new GET /api/live_activity returns those logs + current phase + running
state in one shot — the dashboard hits it on page load
- restoreHistory() in dashboard.js now replays each event into addThinking /
addParamChanges / validationRunStart-Complete-Done / showEarlyTermination,
and re-applies the active phase via setPhaseActive. Reload F5 mid-run no
longer shows a fresh empty dashboard
- addThinking() preserves the original ts on replay (was using nowStr() so
every replayed entry got the refresh time)
Reports page (/reports) rebuilt
- previous template crashed with 500 on legacy summary.json files that
pre-date the win_rate / drawdown_pct fields. Server now backfills sane
defaults for every metric the template touches
- runs now sorted by ts (was filesystem-iterdir order)
- new template: search bar + filter chips (All / Exploration / AI Iteration
/ Validation / AI insight / Has .set), phase tags, AI/.set badges, three
action buttons per card (View Params / Download .set / Full Report)
- per-card detail modal shows metrics grid + full parameters table +
AI reasoning + Download .set button — the missing "click to see params
+ download" path the user reported
- has_set detected per-run by globbing run_dir/*.set; AI insight tag shown
when ai_insight.json exists on disk
API + data integrity
- /api/settings GET no longer leaks the active Anthropic API key — returns a
masked preview (sk-ant-XX…YYYY) plus a boolean `anthropic_api_key_set` flag
- /api/settings POST won't overwrite a real key with the masked placeholder
the client receives back on GET (length<30 / "…" / "..." / "***" markers
trigger a preserve-existing path)
- /api/best_result, /api/status, _make_run_dict, _result_to_dict, all AI-loop
emits, validation_run_complete, optimization_complete, ai_iteration_complete,
ai_targets_met, run_complete: max_drawdown and win_rate are now consistently
emitted as PERCENTAGES (0–100), matching the dashboard's existing display
formatters. They were previously emitted as fractions (0.13 = 13%) so the UI
rendered "0.13%" instead of "13%"
- ResultRanker.make_result() now sets `passing` and `raw_score` on every result
it produces. Previously these were only set during a full ranker.rank() pass,
so individual Phase 2 / Phase 3 runs hit _make_run_dict with passing=False
even when they cleared all gates (history showed "0 passing" when 22/22
actually passed)
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
PROBLEM: Old system repeated identical params, all scores flat at 0.2500,
user had zero control over symbol/TF/dates. Not smart, not dynamic.
NEW ARCHITECTURE:
optimizer/ (NEW package)
├── __init__.py
├── session_config.py User choices (EA, symbol, TF, dates, budget, objective)
├── lhs_sampler.py Latin Hypercube Sampling — diverse exploration
├── result_ranker.py Relative scoring (best in session=1.0, worst=0.0)
├── budget.py Time budget tracker
└── pipeline.py 3-phase orchestrator
Phase 1 — Broad Discovery (LHS, 20-26 runs):
Samples FULL parameter space, not just defaults±tiny step
LHS guarantees coverage: all 17 optimizable LEGSTECH params explored
Relative ranking: profitable configs float top, losers score 0
Phase 2 — Refinement (9 runs):
Neighbor search around top 3 configs at ±20% range (not ±0.5 step)
Keeps best of Phase1 vs Phase2 — never regresses
Phase 3 — Validation (5 runs):
OOS backtest on unseen data period
Sensitivity test: nudge params ±20%, detect fragility
Verdict: RECOMMENDED / RISKY / NOT_RELIABLE
Output: Clean downloadable .set file via /download_set/<run_id>
UI REDESIGN:
ui/templates/landing.html New / homepage (was old dashboard)
ui/templates/setup.html New /setup — EA, symbol, TF, dates, budget, objective
ui/templates/dashboard.html Updated /dashboard with:
- 5-step phase indicator
- Real progress bar per run
- Phase 1 results table (top 5 after phase1)
- Verdict banner with download button
- No-profitable-config warning
ui/static/js/dashboard.js Handles 8 new pipeline SocketIO events
app.py New routes: /, /setup, /dashboard
/api/start accepts full SessionConfig JSON
/download_set/<id> serves optimized .set
ea/registry.py +list_all() for setup page dropdown
ui/templates/reports_index.html Back to Dashboard → /dashboard (was /)
ui/static/css/style.css +dot-warn, dot-done, profit-pos/neg, aliases
FIXES:
Score no longer flat 0.2500 (was: absolute thresholds on losing EA)
User now controls: symbol, timeframe, dates, budget, objective
Parameters now span full range (was: tiny step from defaults)
Verdict is actionable: RECOMMENDED / RISKY / NOT_RELIABLE with reason
TESTED:
8/8 pre-flight checks pass
Browser test: landing ✓, setup form ✓, /dashboard ✓,
phase indicator active ✓, /reports ✓, back link ✓