# Multi_Swarm_Coevolutive Proof-of-concept di sistema co-evolutivo multi-agente per trading quantitativo. Un genetic algorithm fa evolvere una popolazione di agenti LLM (Hypothesis swarm) che generano strategie di trading espresse in JSON strutturato; un layer Falsification deterministico le backtesta su dati storici (default BTC-PERPETUAL Deribit) via Cerbero MCP; un layer Adversarial euristico le sottopone a red-team checks; la fitness combina Deflated Sharpe Ratio (Bailey & López 2014), Sharpe normalizzato e penalizzazione di drawdown, con opzioni v2 soft-kill e combined IS/OOS per Walk-Forward Validation. ## Repository Gitea Tielogic (privato, accesso SSH): ```bash git clone ssh://git@git.tielogic.xyz:222/Adriano/Multi_Swarm_Coevolutive.git ``` ## Layout monorepo (uv workspace) Il repo è un **workspace uv** con due member packages indipendenti, principio "**core = framework, strategy = contenuto**": ``` multi_swarm_coevolutive/ repo root (workspace coordinator) ├── pyproject.toml workspace + dev deps + ruff/mypy/pytest ├── docker-compose.yml 3 servizi su immagine condivisa ├── Dockerfile immagine multi-swarm-coevolutive:dev ├── uv.lock lock unico del workspace ├── data/, series/, state/ cache OHLCV + DB (runtime, gitignored) ├── scripts/ CLI entrypoints (run_phase1, run_paper_trading, ...) └── src/ ├── multi_swarm_core/ WORKSPACE MEMBER (wheel: multi-swarm-core) │ ├── pyproject.toml core deps (pandas, numpy, openai, pydantic, nicegui, ...) │ ├── multi_swarm_core/ GA + genome + protocol + backtest + cerbero + │ │ data + llm + agents + ga + orchestrator + │ │ metrics + persistence + config + dashboard (GA-only) │ ├── tests/ unit + integration │ └── docs/ design/ + decisions/ + reports/ │ └── strategy_crypto/ WORKSPACE MEMBER (wheel: strategy-crypto) ├── pyproject.toml deps: multi-swarm-core (workspace) + nicegui + plotly ├── README.md overview strategia + pattern per nuove strategie ├── strategy_crypto/ │ ├── backend/ paper-trading (executor, portfolio, persistence, schema) │ ├── frontend/ NiceGUI paper-only dashboard │ ├── strategies/ JSON freezate (btc_*.json, eth_*.json) │ └── prompts.json v3.2: agent_role/pattern_guidance/instruction/ │ domain_warnings/anti_patterns/output_priorities + │ 7 stili cognitive (directive + focus_metrics) └── tests/ smoke regression ``` **DB separati per dominio:** `state/runs.db` (GA core universale) + `state/strategy_crypto.db` (paper della strategia crypto). Pattern scala a N strategie senza naming collision. **Pattern N strategie future:** aggiungere `src/strategy_/` con stesso scheletro (`backend/`, `frontend/`, `strategies/`, `tests/`, `prompts.json`), DB dedicato `state/strategy_.db`, servizi Docker `strategy--paper` + `strategy--gui`, GUI su `/strategy__gui`. **Zero modifiche al core** richieste. ## Architettura prompt (v3.2) **Compositor**: il SYSTEM prompt al LLM viene COMPOSTO at-runtime da scaffold core + contenuto strategy: ``` [1] agent_role ← strategy (prompts.json — chi è l'agente) [2] cognitive_style + directive ← genome (evoluti dal GA) [3] GRAMMAR_SPEC ← core scaffold (operatori, indicatori, units rules) [4] pattern_guidance ← strategy (forme di curva astratte, no indicatori prescritti) [5] domain_warnings ← strategy (es. "crypto trada 24/7, NON inferire funding rate") [6] CONSTRAINTS ← core scaffold (validator semantics) [7] anti_patterns ← strategy (7 voci: no >4 AND, no chattering, isteresi, ecc.) [8] output_priorities ← strategy (5 voci, #1 coerenza con lente cognitiva) [9] EXAMPLE ← core scaffold ``` **Input USER (calcolato da `build_market_summary`):** - Base (5): mean, std, skew, kurt, vol_regime - Regime recente rolling 500 (6): autocorr_lag1 (recent + baseline), hurst, vol_percentile, seasonality (hour + dow) - Geometria & frattali (7): efficiency_ratio (Kaufman), tail_index (left + right Hill), structural_uptrend (HH/HL), compression, spectral_entropy, dominant_cycle (gated) - Feature accessibili dal genome + lookback_window - **Focus per la tua lente**: blocco style-aware (4 metriche prioritarie da `focus_metrics` di prompts.json) - Instruction finale (da strategy) **Grammar protocol JSON (8 indicatori):** | Indicatore | Output | Range | |------------|--------|-------| | `sma(length)` | media mobile | unità prezzo | | `sma_pct(length)` | (close-sma)/sma | ±0.1 frazione | | `rsi(length)` | oscillator | 0-100 | | `atr(length)` | true range | unità prezzo | | `atr_pct(length)` | atr/close | 0-0.1 frazione | | `realized_vol(window)` | std returns | 0-0.1 frazione | | `macd(fast,slow,signal)` | momentum | unità prezzo | | `macd_pct(...)` | macd/close | ±0.02 frazione | **7 stili cognitive** (in `prompts.json`, editable): physicist, biologist, historian, meteorologist, engineer, military_strategist, psychologist. Ognuno con directive 800-950 char, ASCII-strict, archetipo dominante + lookback consigliato + 4 focus_metrics. ## Stato del progetto **Phase 3 (paper-trading forward-test) in corso** dal 13 maggio 2026 su VPS. Runner `scripts/run_paper_trading.py` long-running in Docker, dashboard NiceGUI su `https://swarm.tielogic.xyz/strategy_crypto_gui/`. Due strategie freezate in `src/strategy_crypto/strategy_crypto/strategies/`: - `btc_fb63e851.json` — BTC-PERPETUAL, RSI estremi + ATR vs SMA + filtro orario 9-17 (Sharpe OOS +0,26 su 7,33 anni). - `eth_facd6af85d5d.json` — ETH-PERPETUAL, regime-based (con `atr_pct` post-fix bug unità). Phase 1 → 2.7 chiuse (30 run GA, $3.74 cumulato LLM). Sessione refactor 15 maggio 2026: - Split repo invertito, monorepo unificato come uv workspace - Family `*_pct` completa (atr_pct, sma_pct, macd_pct) per fix bug unità - Dashboard split: core (GA) vs strategy (paper) - Prompt architecture compositor + prompts.json v3.2 (vedi decision log) Documenti: - [**Stato progetto e roadmap (14 maggio 2026)**](src/multi_swarm_core/docs/reports/2026-05-14-stato-progetto-e-roadmap.md) - Decision log: [`src/multi_swarm_core/docs/decisions/`](src/multi_swarm_core/docs/decisions/) (gate Phase 1, nemotron, atr_pct fix) - Design docs concettuali: [`src/multi_swarm_core/docs/design/`](src/multi_swarm_core/docs/design/) Stack: Python 3.13, uv workspace, hatchling, pytest+pytest-mock+responses, openai SDK (verso OpenRouter), requests+tenacity, pandas+numpy+scipy, sqlmodel+sqlite, nicegui+plotly, yfinance. ## Setup ```bash uv sync # installa entrambi i workspace member come editable cp .env.example .env # compila CERBERO_*_TOKEN e OPENROUTER_API_KEY uv run pytest # 238 test attesi (234 core + 4 smoke strategy_crypto) ``` ### Variabili .env richieste ```bash # Cerbero MCP (locale o VPS https://cerbero-mcp.tielogic.xyz) CERBERO_BASE_URL=http://localhost:9001 CERBERO_TESTNET_TOKEN= CERBERO_MAINNET_TOKEN= # serve per dati storici reali CERBERO_BOT_TAG=swarm-poc-phase1 # LLM provider (unico endpoint via OpenRouter) OPENROUTER_API_KEY= # DB paths (split per dominio: core GA vs paper della strategia) GA_DB_PATH=./state/runs.db STRATEGY_CRYPTO_DB_PATH=./state/strategy_crypto.db # Deploy Docker — DASHBOARD_ROOT_PATH ora per-servizio (vedi docker-compose.yml) DOMAIN_NAME=tielogic.xyz SWARM_DASHBOARD_PORT=8080 ``` Backcompat: `DB_PATH` legacy continua a funzionare come alias di `GA_DB_PATH`. ## Comandi principali ```bash # Quality gates uv run pytest # tutti i test uv run pytest src/multi_swarm_core/tests/unit -v # solo unit core uv run pytest src/strategy_crypto/tests/ -v # smoke strategy_crypto uv run ruff check src/ scripts/ uv run mypy src/ scripts/ # Smoke run (MockLLM + OHLCV sintetico, no API calls) uv run python scripts/smoke_run.py # Run reale Phase 1/2 (Cerbero + OpenRouter, ~$0.07 per run K=20 10gen) uv run python scripts/run_phase1.py \ --name run-XXX \ --exchange deribit --symbol BTC-PERPETUAL --timeframe 1h \ --start 2024-01-01T00:00:00+00:00 \ --end 2026-01-01T00:00:00+00:00 \ --population-size 20 --n-generations 10 \ --prompt-mutation-weight 0.30 --fitness-v2 # Default --prompt-library: importlib.resources del package strategy_crypto/prompts.json # Backtest standalone di una strategia JSON uv run python scripts/backtest_strategy.py \ --strategy src/strategy_crypto/strategy_crypto/strategies/btc_fb63e851.json \ --start 2018-09-01 --end 2026-01-01 # Paper-trading forward-test (Phase 3) uv run python scripts/run_paper_trading.py \ --name phase3-papertrade-XXX \ --initial-capital 1000 --poll-seconds 300 # Dashboard NiceGUI locale (2 distinte) uv run python -m multi_swarm_core.dashboard.nicegui_app # GA core (/, /convergence, /genomes) uv run python -m strategy_crypto.frontend.nicegui_app # Strategy crypto (/ paper) ``` ## Dashboard (split core + strategy) Due NiceGUI dashboard distinte (dark palette, palette neon): **Core GA** — `multi_swarm_core.dashboard.nicegui_app` → `https://swarm.tielogic.xyz/multi_swarm_core_gui/`: - **Overview** (`/`): lista runs GA, costo cumulato, metriche aggregate evaluations. - **GA Convergence** (`/convergence`): fitness median/max/p90 per generazione + entropy. - **Genomes** (`/genomes`): top-K ordinati per fitness, ispezione system_prompt + JSON strategy. **Strategy crypto** — `strategy_crypto.frontend.nicegui_app` → `https://swarm.tielogic.xyz/strategy_crypto_gui/`: - **Paper** (`/`): forward-test live con equity curve, posizioni aperte, trade list, tick log. In produzione subpath gestiti via `DASHBOARD_ROOT_PATH` (per-servizio) + Traefik `replacepathregex` (NB: NON `stripprefix`, vedi sezione Deploy). La root del dominio resta libera per future GUI di altre strategie. ## Deploy `docker-compose.yml` definisce 3 servizi su immagine condivisa `multi-swarm-coevolutive:dev`: - **`strategy-crypto-paper`** — runner `scripts/run_paper_trading.py` long-running. - **`strategy-crypto-gui`** — NiceGUI paper dashboard su `https://swarm.${DOMAIN_NAME}/strategy_crypto_gui/`. - **`multi-swarm-core-gui`** — NiceGUI GA dashboard su `https://swarm.${DOMAIN_NAME}/multi_swarm_core_gui/`. Persistenza via bind mount: `./data/`, `./series/`, `./state/`. Strategie JSON bind-mounted in read-only dal package: `./src/strategy_crypto/strategy_crypto/strategies/`. ```bash docker compose up -d --build docker compose logs -f strategy-crypto-paper docker compose ps ``` Note operative: - Bind-mount dir devono essere `chown 1000:1000` (uid utente `app` nel container). **Anche `src/strategy_crypto/strategy_crypto/strategies/`** (creata da `git mv`, default `root:root`). - Override del command paper via env (`PAPER_RUN_NAME`, `PAPER_INITIAL_CAPITAL`, ecc.). - `SWARM_DASHBOARD_PORT` controlla la porta interna del container (Traefik fa il TLS). - **Traefik subpath**: usa `replacepathregex` middleware (NON `stripprefix`) per evitare doppio root_path (uvicorn legge `X-Forwarded-Prefix` da stripprefix + applica `root_path` di NiceGUI = doppio prefix). Vedi commit `436613b`. - Dopo cambio label Traefik: `docker restart traefik-traefik-1` per forzare refresh discovery. ## Sviluppo Conventional commits con prefix `feat:` `fix:` `chore:` `docs:` `refactor:` `test:`. Body italiano. Footer `Co-Authored-By: Claude Opus 4.7 (1M context) ` su ogni commit collaborativo. Branch attuale: `main`. Workspace single-repo, monorepo unificato dal 15 maggio 2026 (split temporaneo monorepo→figlio invertito, vedi tag `v0.1.0-pre-split` come bookmark). **Modificare il prompt LLM** senza toccare codice: edita `src/strategy_crypto/strategy_crypto/prompts.json`. Schema documentato in `_design_invariants` del JSON stesso. I 3 regression guard test (`test_strategy_crypto_directives_ascii_safe`, `..._have_archetype_marker`, `..._have_lookback_hint`) bloccano regressioni accidentali sulle invarianti di design.