# Multi-Swarm Coevolutivo — Stato del progetto e roadmap *Data del documento: 14 maggio 2026 — branch `main` allineato a commit `45f273f`.* Questo documento riepiloga l'intero percorso del proof-of-concept Multi-Swarm Coevolutive dalla Phase 1 (lean spike) fino allo stato corrente di entrata in Phase 3 (paper-trading forward-test). È inteso come punto di sincronizzazione per riprendere il lavoro: cosa è stato deciso, cosa ha funzionato, cosa no, e quali sono le prossime mosse plausibili. --- ## 1. Quadro sintetico | Fase | Periodo | Stato | Esito | |------|---------|-------|-------| | **Phase 1** — lean spike | 9-10 maggio 2026 | ✅ chiusa | GO Phase 2 (5/5 hard gate) | | **Phase 1.5** — adversarial hardening | 11 maggio 2026 | ✅ chiusa | NO-GO sulla combo nemotron, hardening conservato | | **Phase 2** — feature temporali + qwen3-235b | 11 maggio 2026 | ✅ chiusa | NO-GO sul modello (rollback a qwen-2.5-72b) | | **Phase 2.5** — LLM prompt mutator | 11-12 maggio 2026 | ✅ chiusa | Operator integrato, sweet spot weight 0.20-0.30 | | **Phase 2.6** — Walk-Forward Validation | 12-13 maggio 2026 | ✅ chiusa | WFA 70/30 introdotta, min-trades parametrico | | **Phase 2.7** — portabilità cross-asset (BTC/ETH/SOL) | 13 maggio 2026 | ✅ chiusa | BTC strong, ETH adequate, SOL failure | | **Phase 3** — paper-trading forward-test | 13-14 maggio 2026 | 🟢 in corso | Runner BTC+ETH operativo, smoke OK | Dal punto di vista del DB locale: 30 run GA completate, costo cumulato LLM **≈ $3.74**, due paper-trading run avviati (`phase3-smoke-001`, `phase3-papertrade-001`). --- ## 2. Phase 1 — lean spike (chiusa 10 maggio) ### Obiettivo Validare end-to-end l'idea co-evolutiva: GA → popolazione di prompt LLM → strategie JSON → backtest deterministico → fitness → selezione. Cinque hard gate vincolanti. ### Risultato Run di riferimento `phase1-real-005` su BTC-PERPETUAL Deribit 1h, 2024-01-01 → 2026-01-01, K=20, 10 generazioni, **costo $0.069 in 29 minuti**. | Hard gate | Soglia | Misurato | Esito | |-----------|--------|----------|-------| | Loop convergence | median sale | 0.0001 → 0.0188 in 3 gen | ✓ | | Parse success | ≥ 95% | 100% (98/98) post refactor JSON | ✓ | | Top-5 vs median | ≥ 10× | 1116× | ✓ | | Entropy fitness gen 9 | ≥ 0.5 | 0.914 | ✓ | | Costo totale | ≤ $700 | $0.069 | ✓ | Iterazione: 5 run prima del PASS, ognuna ha scoperto un bug strutturale (max_dd su equity assoluta, cap Cerbero 5000 candele, validator arity, switch grammar S-expr→JSON, fitness clip-to-0 troppo dura). ### Caveat critico Il top-1 ha reso **+2.66% in 2 anni vs B&H BTC +106%**, essendo *flat* nel 99,8% del tempo. Conferma che la fitness v1 premiava "non-strategie" sicure invece di alpha vero. Da qui la Phase 1.5. ### Documenti chiave - `docs/decisions/2026-05-10-gate-phase1.md` — decision memo. - `docs/reports/2026-05-10-phase1-technical-report.md` — report tecnico. --- ## 3. Phase 1.5 — adversarial hardening (chiusa 11 maggio) Quattro nuovi check `HIGH` aggiunti all'agente Adversarial per killare strategie degeneri: 1. `overtrading` ricalibrato `n_bars/20` (era `n_bars/5`). 2. `undertrading` promosso a HIGH se `n_trades < 10`. 3. `flat_too_long` (nuovo HIGH) — segnale flat > 95% bar. 4. `fees_eat_alpha` (nuovo HIGH) — `fees / |gross_pnl| > 0.5` con gross positivo. 5. `time_in_market_too_high` (nuovo HIGH) — segnale LONG||SHORT > 80% bar (kill leveraged-B&H camuffato). **Run di test `phase1.5-nemotron-001`** (tier C nemotron, 2h26', $0.12) → **NO-GO**: max fitness 0.0215 stagnante, median 0 su 9 gen, top-5 con DSR=0 e Sharpe ≈ −1.1. I check Phase 1.5 funzionavano (98 findings emessi); il problema era il modello: prompt calibrato su qwen, nemotron produceva materiale qualitativamente più povero. Bugfix collaterale (`9d0deb3`): `EmptyCompletionError` reso retryable + gestione `resp.usage=None` per provider `:free`. --- ## 4. Phase 2 — feature temporali + tier C qwen3-235b (chiusa 11 maggio) Due lavori in parallelo, esiti opposti: **4.1 Feature temporali in protocol layer** — `KNOWN_FEATURES` esteso con `hour`, `dow`, `is_weekend`, `minute_of_hour`. Compiler dispatcher temporale (`9d1f97c`), validator parametrizzato, integration test gating temporale+SMA. Few-shot example nel prompt Hypothesis. **Successo strutturale**: tutte le top strategie successive sfruttano questo asset. **4.2 Upgrade tier C a `qwen/qwen-2.5-72b-instruct` → `qwen3-235b-a22b`** — run `phase2-qwen3-001`: max fitness 0.0238 stuck per 8 gen, entropy 0.199 stuck per 7 gen, 4 dei 5 top genomi con fitness/Sharpe/DD identici. Il **run controllo** identico ma con qwen-2.5-72b: 0.0311 (+30%), median raggiunge top in 4 gen, entropy 0.85, ½ tempo e costo. **Rollback a qwen-2.5-72b** (`8ec45c5`). Lezione consolidata: il prompt è calibrato sulla famiglia qwen-2.5; un modello "più nuovo / più grande" non è automaticamente meglio se il prompt non viene ricalibrato in parallelo. --- ## 5. Phase 2.5 — operator `mutate_prompt_llm` (chiusa 12 maggio) Quinto operatore di mutazione che riscrive il `system_prompt` via LLM tier B (`deepseek-v4-flash`) anziché perturbare scalari. Sei istruzioni atomiche: `tighten_threshold`, `swap_comparator`, `add_condition`, `remove_condition`, `change_timeframe`, `add_temporal_gate`. Validation gate (lunghezza ≥ 50, keyword tecnica, diff Levenshtein > 5%) + fallback `random_mutate`. Dispatcher pesato `weighted_random_mutate` (CLI `--prompt-mutation-weight`, default 0.0). ### Sweet spot empirico (seed 42, pop 20, 10 gen) | weight | max fit | median fin | Sharpe top | trades | verdetto | |--------|---------|-----------|-----------|--------|----------| | 0.00 | 0.0311 | 0.0000 | −1.08 | 274 | baseline | | **0.30** | **0.1012** ⭐ | **0.0745** | **−0.25** | 62 | sweet spot (ma seed-lucky) | | 0.50 | 0.0311 | 0.0000 | −1.08 | 274 | regressione | ### Validazione robustezza Confronti seed multipli (7, 99, 123) hanno mostrato che il **+225%** del run 004 era **outlier seed-specific**. Beneficio medio reale del prompt-mutator: **+10–23%** sopra baseline. La leva più affidabile e seed-indipendente è risultata `fees_eat_alpha_threshold 0.7` (anziché 0.5): +23% stabile, Sharpe top −0.70 vs −1.08. ### Combo vincente (pop=30 + weight=0.30 + fees=0.7) Run `pop30-combo-001`: max fitness 0.0459 (+48% vs control), **median finale = max** (convergenza ≥50% pop), Sharpe top −0.63, 226 trades. Mutator overhead ≈ 5,4% del costo totale. ### Cost attribution (Task 6) `cost_records.call_kind` (`hypothesis` / `mutation`) attivo da `ba4eb09`. Permette breakdown costo per operatore: il prompt-mutator costa 3-9% del totale, trascurabile. --- ## 6. Phase 2.6 — Walk-Forward Validation (chiusa 13 maggio) Aggiunte tre leve metodologiche: - **WFA 70/30**: split temporale `train/OOS` con OOS intoccato durante GA, valutato solo a fine run. - **`--min-trades-threshold`** parametrico: filtra survivors con n_trades insufficiente prima del ranking. - **Fitness v2 soft-kill** (`cf42dd8`): solo `no_trades` + `degenerate` + `undertrading` azzerano hard. Altri HIGH applicano penalty moltiplicativa `1/(1+0.4·n)` (1 HIGH = 0,71×, 2 = 0,56×, 3 = 0,45×). CLI `--fitness-v2` + `--fitness-soft-penalty`. - **Pattern guidance nel system prompt** (`67ae6ff`): forma curve attese + criterio ripetibilità. - **Fitness multi-obiettivo** (`1a1dfb7`): `combined = α·IS + (1−α)·OOS` opt-in. Effetto cumulativo: la pipeline produce strategie con migliore generalizzazione cross-split senza dover degradare le adversarial hard. --- ## 7. Phase 2.7 — backtest 7 anni e portabilità cross-asset (chiusa 13 maggio) ### 7.1 Validazione 7,33 anni su BTC Backtest dei top genome scoperti sulle varie sotto-fasi sui **64.297 bar 1h** completi (2018-09-01 → 2026-01-01), fees 5 bp: | Genome | Origine | Total P/L 7y | CAGR | Sharpe ann | MaxDD | Verdetto | |--------|---------|--------------|------|-----------|-------|----------| | `5226503a` | run004 outlier 2y bull | **−310,69%** | wiped out | −0,155 | 280,9% | crash totale OOS | | `e52604ba` | flat-ablation top 2y | −37,17% | −6,14% | −0,063 | 182,0% | SMA non generalizza | | `ec06a3d4` | fitness-v2-combo top 2y | +142,51% | +12,85% | +0,229 | 64,9% | hour-gated regge | | `4e1be9fa` | 7y-v2-WFA top IS | +67,60% | +7,30% | +0,240 | 79,1% | top IS ingannevole | | `63411199` | 7y-v2-WFA top OOS | **+660,11%** | **+31,88%** | +0,238 | 77,1% | leveraged-B&H camuffato | | **`fb63e851`** ⭐ | 7y multi-seed99 top OOS | +130,37% | +12,06% | **+0,264** | **54,8%** | **true alpha** | Conclusioni: - Il top by `fit_IS` è sistematicamente ingannevole su orizzonti lunghi. - Pattern SMA-puri collassano cross-regime. - Pattern *hour-gated* (filtri intraday) reggono cross-regime. - `fb63e851` è il candidato più robusto: 4 AND × 2 rule × filtro intraday → attiva l'1-2% del tempo, Sharpe cross-regime più alto. ### 7.2 Portabilità BTC → ETH → SOL Tre run **identici** (`population=30`, `n_gen=10`, `prompt_mutation_weight=0.30`, fitness v2, WFA 70/30, `fees_eat_alpha_threshold=0.7`, undertrading 20) su Deribit perpetuals. | Asset | Storia | Top OOS Sharpe | Verdetto | |-------|--------|----------------|----------| | **BTC** | 7,33 y | `fb63e851` +0,50 OOS (+20,16%) | **STRONG** | | **ETH** | 6,75 y | `facd6af85d5d` +0,19 OOS (+16,14%) | **ADEQUATE** | | **SOL** | 3,00 y | **0 survivors / 247 evals** | **FAILURE** | Pattern scoperti **divergenti**: BTC = mean reversion intraday contrarian; ETH = trend-following long-bias + vol regime. **Non esiste "una strategia universale"**: la metodologia (GA + WFA + adversarial v2) è portabile, il pattern no. SOL ha fallito per finestra dati troppo corta (3y) e regime bull-only post-FTX. --- ## 8. Phase 3 — paper-trading forward-test (in corso) ### Componenti implementati (`45f273f`) Modulo `src/multi_swarm/paper_trading/`: - `portfolio.py` — multi-asset portfolio con sleeve uguali per asset, fees in bp. - `executor.py` — `PaperExecutor` carica una strategia JSON, compila, valuta l'ultimo bar. - `persistence.py` — `PaperRepository` su SQLite (tabelle `paper_trading_runs`, `paper_trading_ticks`, `paper_trading_equity`, `paper_trading_trades`, `paper_trading_positions`). Runner `scripts/run_paper_trading.py`: - Loop poll OHLCV Cerbero ogni `--poll-seconds` (default 300). - Riconosce *nuovo bar chiuso* confrontando ultimo timestamp; tick consecutivi su stesso bar = hold. - Snapshot equity ogni tick. - Supporta `--max-ticks N` per smoke test (0 = infinito). Strategie freezate per il forward-test: - `strategies/btc_fb63e851.json` — RSI estremi + ATR vs SMA + filtro orario 9-17. - `strategies/eth_facd6af85d5d.json` — ATR + realized_vol + golden/death cross. ### Stato corrente - Schema DB esteso e validato. - Run smoke completato (`phase3-smoke-001`). - Run live in corso (`phase3-papertrade-001`). --- ## 9. Architettura cumulata ``` src/multi_swarm/ ├── config.py ├── data/{cerbero_ohlcv,splits}.py ← splits.py per WFA ├── backtest/{orders,engine}.py ├── metrics/{basic,dsr,diversity}.py ← diversity per Phase 2.5 ├── cerbero/{client,tools}.py ├── protocol/{grammar,parser,validator,compiler}.py │ └── KNOWN_FEATURES include hour/dow/is_weekend/minute_of_hour ├── genome/ │ ├── hypothesis.py │ ├── mutation.py ← 4 operatori scalari │ ├── mutation_prompt_llm.py ← Phase 2.5: 5° operatore LLM │ └── crossover.py ├── llm/{client,cost_tracker}.py ← cost_kind tracking ├── agents/{hypothesis,falsification,adversarial,market_summary}.py │ └── adversarial: 5 check HIGH parametrici (CLI knobs) ├── ga/ │ ├── selection.py │ ├── fitness.py ← v1 + v2 soft-kill + combined IS/OOS │ ├── loop.py │ ├── summary.py │ └── initial.py ├── persistence/{schema,repository}.py ← +tabelle paper_trading_* ├── paper_trading/ ← NEW Phase 3 │ ├── portfolio.py │ ├── executor.py │ └── persistence.py ├── orchestrator/run.py └── dashboard/ ├── nicegui_app.py ← unica GUI, porta parametrica via SWARM_DASHBOARD_PORT └── data.py ``` CLI knobs accumulati per ablation: - `--prompt-mutation-weight FLOAT` (Phase 2.5) - `--fees-eat-alpha-threshold FLOAT` (default 0.5, suggerito 0.7) - `--flat-too-long-threshold FLOAT` (default 0.95) - `--undertrading-threshold INT` (default 20) - `--fitness-v2` + `--fitness-soft-penalty FLOAT` - `--fitness-combined-alpha FLOAT` (multi-obiettivo IS/OOS) - `--min-trades-threshold INT` (WFA OOS filter) --- ## 10. Cosa resta da fare ### 10.1 Phase 3 — completamento paper-trading - [ ] **Definire criterio di STOP/GO Phase 3**: durata minima forward-test (es. 4-8 settimane), soglie sopravvivenza (Sharpe live > 50% del Sharpe OOS atteso, DD live < 1,5× DD OOS). - [ ] **Pagina dashboard paper-trading**: estendere NiceGUI con tab live equity + open positions + tick log per `paper_trading_runs`. Oggi i dati esistono in DB ma non hanno UI dedicata. - [ ] **Monitoring & alerting**: notifica se il runner si ferma (Cerbero down, processo killato). Considerare systemd unit o supervisor. - [ ] **Robustezza fetch live**: oggi `loader._fetch(req)` bypassa la cache; aggiungere retry esplicito (oltre a quello tenacity già presente nel client) e log strutturato dei fallimenti per asset. - [ ] **Confronto live vs OOS atteso**: script che a fine settimana confronta P/L, Sharpe rolling, hit rate vs i numeri del backtest 7y per individuare *regime mismatch* precoce. ### 10.2 Estensioni metodologiche - [ ] **Multi-seed ensembling**: invece di scegliere un singolo top genome, valutare ensemble (mediana o weighted) dei top-K trovati con seed diversi sullo stesso asset. La varianza seed è il rischio numero uno (vedi sezione 5). - [ ] **Asset universe expansion**: testare la metodologia su asset non-crypto (oro, forex EURUSD) per smentire l'ipotesi che funzioni solo perché BTC/ETH hanno alta volatilità. `yfinance` è già in dipendenze (`9d1ef8a`). - [ ] **Fitness regime-aware**: oggi fitness è single-objective sull'intero train. Considerare fitness condizionata al regime (bull/bear/range) per favorire strategie con performance bilanciata cross-regime invece di top assoluto. - [ ] **Phase 2.7 retry su SOL** con configurazione mirata: train più corto, undertrading_threshold ridotto, prompt few-shot di strategie short-vol-only. Verificare se è davvero il dato a fallire o se è la calibrazione. ### 10.3 Hardening tecnico - [ ] **Cleanup zombie runs**: `phase2-6-flat-wfa-001` è ancora `failed` nel DB. Verificare che il flush di stato sia idempotente per tutti i path di crash. - [x] **Port completo dashboard a NiceGUI** *(chiuso 14 maggio 2026, commit `03f723f`)*: Streamlit deprecata e rimossa insieme ai file legacy (`streamlit_app.py`, `aquarium.py`, `pages/0[1-4]_*.py`); dep `streamlit>=1.40` cancellata da `pyproject.toml` con 10 transitive (pydeck, watchdog, jsonschema, pillow, …). NiceGUI espone 3 pagine (`/`, `/convergence`, `/genomes`) su porta parametrica `SWARM_DASHBOARD_PORT` (default 8080). **Aquarium non riportata per scelta** (decisione utente: non più ritenuta utile). Deploy in produzione via Docker + Traefik su `https://swarm.tielogic.xyz` (compose `docker-compose.yml`, commit `8e5efde`). - [ ] **Pruning DB**: dopo 30+ run la SQLite cresce. Aggiungere uno script di archiviazione/compressione delle run completate più vecchie di N giorni. - [ ] **CI/test coverage**: i 180+ test girano localmente; non c'è ancora CI esterna (Gitea Actions o equivalente). ### 10.4 Documentazione e governance - [ ] **Decision memo Phase 2.5 + Phase 2.6 + Phase 2.7** formalizzati come `docs/decisions/2026-05-1{2,3}-*.md` (esistono solo memory + commit message; manca il pendant pubblico dei due memo già esistenti per Phase 1 e Phase 1.5). - [ ] **Phase 3 charter**: documento che fissa a priori cosa significherà "successo" o "fallimento" del forward-test, per evitare *moving goalposts* a posteriori. - [ ] **Threats to validity update**: il memo Phase 1 ne elencava 6; integrarli con le scoperte successive (varianza seed, portabilità asset-specifica, divergenza pattern BTC/ETH). --- ## 11. Caveat e rischi aperti 1. **Varianza seed**: con seed diversi (7, 99, 123) sullo stesso identico setup il max fitness varia di un fattore 3-4×. Qualunque metrica single-seed è statisticamente debole; finché Phase 3 non raccoglie N≥5 forward-test indipendenti, il vantaggio del prompt-mutator resta nel rumore. 2. **Sharpe OOS positivi ma bassi**: BTC `+0,50` ed ETH `+0,19` sono migliori del coin-flip ma lontani dai target retail "investment-grade" (≥ 1,0). La metodologia è validata, l'alpha catturata è modesta. 3. **`time_in_market_too_high` come red-flag chiave**: `63411199` ha CAGR +31,88% ma esposizione 90% del tempo — è leveraged-B&H camuffato, non alpha. Phase 3 deve preferire `fb63e851` (selettività 1-2%) anche se ha return assoluto minore. 4. **Dipendenza dal modello qwen-2.5-72b**: rollback Phase 2 ha dimostrato che il prompt è calibrato su questa specifica famiglia. Se il modello venisse deprecato da OpenRouter, sarebbe necessario un giro di ricalibrazione prompt → rischio di operatività. 5. **Cerbero MCP come single point of failure**: tutti i fetch OHLCV passano da lì. Da considerare un fallback (ccxt o yfinance) almeno per il paper-trading. --- ## 12. Costi cumulati - **Phase 1 (5 run iterazione)**: $0,19. - **Phase 1.5 nemotron**: $0,12. - **Phase 2 + 2.5 + 2.6 + 2.7**: ≈ $3,24 cumulati su 25+ run. - **Totale LLM progetto a oggi**: ≈ **$3,74** (DB locale). - **Phase 3 paper-trading**: $0 incrementali per LLM (le strategie sono fisse), solo costi Cerbero (incluso nel servizio esistente). Resta amplissimo margine rispetto al cap originale Phase 1 di $700. --- ## 13. Riferimenti - README.md — overview e setup. - `docs/decisions/2026-05-10-gate-phase1.md`, `docs/decisions/2026-05-11-phase1-5-nemotron-run.md`. - `docs/reports/2026-05-10-phase1-technical-report.md`. - `docs/superpowers/specs/2026-05-09-decisione-strategica-design.md`, `docs/superpowers/specs/2026-05-11-temporal-features-design.md`. - `docs/superpowers/plans/2026-05-09-phase1-lean-spike.md`, `docs/superpowers/plans/2026-05-11-mutate-prompt-llm-phase-2-5.md`, `docs/superpowers/plans/2026-05-11-temporal-features.md`. - DB locale `runs.db` per dettaglio run-by-run. --- *Prossimo checkpoint suggerito: rivedere questo documento al termine del primo ciclo completo di Phase 3 (≥ 2 settimane di forward-test continuo) per consolidare i risultati live e decidere GO/NO-GO verso un eventuale Phase 4 (capitale reale ridotto o estensione del universe).*