Adriano Dal Pastro 4b9cded966 fix(dashboard): leggi righe selezionate da e.args nel callback selection
Il callback registrato via top_table.on("selection", ...) riceve un
GenericEventArguments di NiceGUI, non un TableSelectionEventArguments,
quindi l'attributo .selection non esiste e il click su una riga della
tabella "Top genomi" generava AttributeError. Le righe selezionate
arrivano nel payload Quasar come e.args["rows"].

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 05:38:42 +00:00

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. Il tutto è ispirato alla filosofia di Renaissance Technologies adattata a un contesto retail single-author con LLM agents.

Repository

Gitea Tielogic (privato, accesso SSH):

git clone ssh://git@git.tielogic.xyz:222/Adriano/Multi_Swarm_Coevolutive.git

Stato del progetto

Phase 3 (paper-trading forward-test) in corso dal 13 maggio 2026 su VPS. Runner scripts/run_paper_trading.py live 24/7 in Docker (https://swarm.tielogic.xyz per la dashboard) con due strategie freezate:

  • strategies/btc_fb63e851.json — BTC-PERPETUAL, true alpha hour-gated (RSI estremi + ATR vs SMA + filtro orario 9-17), Sharpe OOS +0,26 su 7,33 anni di storia.
  • strategies/eth_facd6af85d5d.json — ETH-PERPETUAL, trend-following long-bias + vol regime, Sharpe OOS +0,19 su 6,75 anni.

Phase 1 → 2.7 tutte chiuse (30 run GA, $3.74 cumulato LLM, cap originale $700 → margine 99%+). Vedi il documento di sintesi consolidato per il dettaglio:

Documenti chiave per fase:

Documenti di contesto pre-implementazione: 00_documento_zero.md (framework concettuale Renaissance → swarm), coevolutive_swarm_system.md (Filone A, sistema completo), poc_trading_swarm.md (Filone B, PoC trading).

Architettura

src/multi_swarm/
├── config.py                Settings Pydantic (.env)
├── data/
│   ├── cerbero_ohlcv.py     OHLCV loader via Cerbero MCP + cache parquet
│   └── splits.py            Walk-forward expanding splits (Phase 2.6)
├── backtest/
│   ├── orders.py            Side/Order/Position/Trade
│   └── engine.py            Event-driven backtest, 1-bar exec delay
├── metrics/
│   ├── basic.py             Sharpe, max drawdown, total return
│   ├── dsr.py               Deflated Sharpe Ratio (Bailey & López 2014)
│   └── diversity.py         Entropy/diversity metrics popolazione (Phase 2.5)
├── cerbero/
│   ├── client.py            HTTP client (bearer + bot-tag + retry tenacity)
│   └── tools.py             Wrapper tool MCP (sma/rsi/atr/macd/realized_vol/funding)
├── protocol/
│   ├── grammar.py           Vocabolario operatori, indicatori, feature (incl. hour/dow/is_weekend)
│   ├── parser.py            json.loads → AST dataclass tipizzato
│   ├── validator.py         Arity checks, no-nesting indicators, whitelist
│   └── compiler.py          AST → Callable[[df], Series[Side]]
├── genome/
│   ├── hypothesis.py        HypothesisAgentGenome (id deterministico)
│   ├── mutation.py          4 operatori scalari (temp, lookback, features, style)
│   ├── mutation_prompt_llm.py  5° operatore: riscrittura system_prompt via LLM tier B
│   └── crossover.py         Uniform crossover
├── llm/
│   ├── client.py            Unified LLMClient via OpenRouter (tier S/A/B/C/D)
│   └── cost_tracker.py      Pricing per tier, breakdown + call_kind tracking
├── agents/
│   ├── hypothesis.py        LLM call + JSON extract + retry-with-feedback
│   ├── falsification.py     Compile → backtest → DSR
│   ├── adversarial.py       Red-team heuristics (5 check HIGH parametrici via CLI)
│   └── market_summary.py    Stats di mercato per il prompt
├── ga/
│   ├── selection.py         Tournament + elitism
│   ├── fitness.py           v1 continua + v2 soft-kill + combined IS/OOS opt-in
│   ├── loop.py              next_generation step
│   ├── summary.py           median/max/p90/entropy per gen
│   └── initial.py           Popolazione iniziale (6 cognitive style)
├── persistence/
│   ├── schema.py            SQLite DDL: 6 tabelle GA + 5 tabelle paper_trading_*
│   └── repository.py        CRUD per runs/genomes/evals/cost/findings/gen_summary
├── paper_trading/           Phase 3
│   ├── portfolio.py         Multi-asset portfolio con sleeve uguali per asset
│   ├── executor.py          PaperExecutor: carica strategia JSON, valuta ultimo bar
│   └── persistence.py       PaperRepository (paper_trading_runs/ticks/equity/trades/positions)
├── orchestrator/
│   └── run.py               End-to-end pipeline GA + persistence
└── dashboard/
    ├── nicegui_app.py       NiceGUI dashboard (overview / convergence / genomes)
    └── data.py              Lettura runs.db per le pagine

Stack: Python 3.13, uv, pytest+pytest-mock+responses, openai SDK (verso OpenRouter), requests+tenacity, pandas+numpy+scipy, sqlmodel+sqlite, nicegui+plotly, yfinance (test cross-asset non-crypto).

CLI knobs accumulati (Phase 2.5 → 2.7):

  • --prompt-mutation-weight FLOAT (peso del 5° operatore, sweet spot 0.20-0.30)
  • --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 (filtro OOS in WFA)

Setup

uv sync
cp .env.example .env  # compilare CERBERO_*_TOKEN e OPENROUTER_API_KEY
uv run pytest         # ~180 test attesi (unit + integration)

Variabili .env richieste

# Cerbero MCP (locale o VPS https://cerbero-mcp.tielogic.xyz)
CERBERO_BASE_URL=http://localhost:9001
CERBERO_TESTNET_TOKEN=<testnet bearer>
CERBERO_MAINNET_TOKEN=<mainnet bearer>   # serve per dati storici reali
CERBERO_BOT_TAG=swarm-poc-phase1

# LLM provider (unico endpoint via OpenRouter)
OPENROUTER_API_KEY=<sk-or-v1-...>
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1

# Modelli per tier (default Phase 2.5+: qwen-2.5-72b per tier C, vedi .env.example per gli altri)
LLM_MODEL_TIER_C=qwen/qwen-2.5-72b-instruct

# Deploy Docker (vedi sezione Deploy)
DOMAIN_NAME=tielogic.xyz
SWARM_DASHBOARD_PORT=8080

Cerbero MCP

Tutti i fetch OHLCV passano da Cerbero MCP (sostituisce ccxt). In sviluppo locale:

cd /home/adriano/Documenti/Git_XYZ/CerberoSuite/Cerbero_mcp
uv sync
uv run cerbero-mcp   # ascolta su porta da .env (default 9001 se 9000 è occupato)

In produzione/integrazione: VPS https://cerbero-mcp.tielogic.xyz (richiede bearer) — o internal docker http://cerbero-mcp:9000 se si gira nella stessa rete Traefik.

Comandi principali

# Quality gates
uv run pytest                       # tutti i test
uv run pytest tests/unit -v         # solo unit
uv run pytest tests/integration -v  # solo integration (richiedono Cerbero + OpenRouter)
uv run ruff check src/ tests/ 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

# Backtest standalone di una strategia JSON su range esteso
uv run python scripts/backtest_strategy.py \
  --strategy 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
DB_PATH=./runs.db uv run python -m multi_swarm.dashboard.nicegui_app

Dashboard

NiceGUI dashboard (dark/neon palette) su http://localhost:8080 (override con env SWARM_DASHBOARD_PORT):

  • Overview (/): lista runs, status, costo, metriche aggregate evaluations (parse success %, top fitness, median).
  • GA Convergence (/convergence): fitness median/max/p90 per generazione, entropy con hline a soglia gate (0.5).
  • Genomes (/genomes): top-K ordinati per fitness, click su riga per ispezione system_prompt + raw_text JSON strategy.

In produzione gira dentro Docker dietro Traefik su https://swarm.${DOMAIN_NAME} — vedi sezione Deploy.

Deploy

docker-compose.yml definisce due servizi che condividono la stessa immagine multi-swarm:dev:

  • multi-swarm-paper — runner scripts/run_paper_trading.py long-running (restart: unless-stopped).
  • multi-swarm-dashboard — NiceGUI esposta via Traefik su https://swarm.${DOMAIN_NAME}.

Entrambi joinano la rete external traefik per parlare direttamente con cerbero-mcp:9000 senza giro pubblico+TLS. Persistenza via bind mount:

  • ./data/, ./series/ — cache OHLCV (parquet)
  • ./state/runs.db (+ WAL/SHM)
  • ./strategies/btc_*.json / eth_*.json (read-only nel container)

Bring-up:

docker compose up -d --build
docker compose logs -f multi-swarm-paper   # segui i tick
docker compose ps                           # stato

Note operative:

  • Le bind-mount dir devono essere chown 1000:1000 (uid utente app nel container).
  • Override del command paper-trading via env (PAPER_RUN_NAME, PAPER_INITIAL_CAPITAL, PAPER_POLL_SECONDS, ecc.) — vedi .env.example.
  • SWARM_DASHBOARD_PORT controlla la porta interna del container (Traefik fa il TLS davanti).

Costi

Costo cumulato LLM progetto a oggi: ≈ $3.74 su 30 run GA (Phase 1 → 2.7). Cap originale Phase 1: $700 → margine residuo abbondante.

  • Tier C (qwen-2.5-72b via OpenRouter): ~$0.40/1M token.
  • Run base K=20 × 10gen ≈ $0.07. Con --prompt-mutation-weight 0.30 overhead mutator 3-9%.
  • Phase 3 paper-trading: $0 incrementali LLM (strategie fisse), solo costi Cerbero (servizio esistente).

Sviluppo

Conventional commits con prefix feat: fix: chore: docs: refactor: test:. Body italiano. Footer Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> su ogni commit collaborativo.

Branch attuale: main. Single-author retail R&D, nessun feature branch attivo. Ablation paralleli si gestiscono via CLI knobs sullo stesso branch.

S
Description
No description provided
Readme 2.3 MiB
Languages
Python 99.5%
Dockerfile 0.5%