feat(gui+infra): pagina Strategia, P/L parametrico, profili Conservativa/Aggressiva, dashboard via Traefik
Espone la GUI Streamlit su https://cerbero-bite.tielogic.xyz tramite il Traefik già attivo sull'host (label allineate al pattern di cerbero-mcp, TLS via Let's Encrypt, websocket pass-through). Aggiunge: - nuova tab `📚 Strategia` con stato live dei gate §2 confrontati con l'ultimo tick di market_snapshots, pannello P/L parametrico affiancato Conservativa vs Aggressiva, tabella di sensibilità win-rate → APR e rendering del documento canonico esteso. - doc `13-strategia-spiegata.md` che lega ogni regola §2-§9 al campo di market_snapshots che la alimenta, con sezioni §4-bis (P/L atteso realistico, win-rate empirico, drawdown, Sharpe) e §4-ter (confronto fra i due profili e quando passare dall'uno all'altro). - `strategy.conservativa.yaml` (golden config v1.0.0 esplicita) e `strategy.aggressiva.yaml` (cap_per_trade 4×, max_concurrent 2×, max_contracts 4×, deroga §11 documentata) con config_hash validi. - nel compose: servizio dedicato `cerbero-bite-gui` (Streamlit su 0.0.0.0:8765, healthcheck su /_stcore/health, label Traefik), env condivisi via anchor YAML `x-bite-env`, `--environment mainnet` passato a `start` per allineare il boot check al token del .env (era testnet vs mainnet → kill switch armato all'avvio). - Dockerfile installa anche l'extra `gui` (streamlit) e copia `docs/` + i due nuovi profili nell'immagine; `.dockerignore` non esclude più `docs/` (causa del primo build silenzioso). Fix bonus: `_try_load` nella pagina ritornava `LoadedConfig` ma la GUI leggeva `.sizing.*` direttamente — l'`except: pass` mascherava l'AttributeError facendo cadere sui default conservativi sia nel pannello P/L sia nello stato gate (stesso pattern presente nella Calibrazione). Ora ritorna `.config`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+90
-25
@@ -1,27 +1,48 @@
|
||||
# docker-compose.yml — Cerbero Bite
|
||||
#
|
||||
# Bite runs in its own Compose project but joins the same Docker
|
||||
# network used by Cerbero MCP V2 so it can resolve the in-cluster
|
||||
# service name when running co-located, and otherwise reaches the
|
||||
# public gateway (`https://cerbero-mcp.tielogic.xyz`) over the host
|
||||
# network.
|
||||
# network used by Cerbero MCP V2 and Traefik (`traefik`) so it can
|
||||
# either resolve the in-cluster service name (`cerbero-mcp:9000`)
|
||||
# or reach the public gateway (`https://cerbero-mcp.tielogic.xyz`)
|
||||
# transparently.
|
||||
#
|
||||
# The shared network is declared as external here. Create it once on
|
||||
# the host with `docker network create cerbero-suite` (or rename the
|
||||
# Cerbero_mcp network to `cerbero-suite` and mark it external).
|
||||
# The reverse-proxy network (`traefik`) is declared as external
|
||||
# here. It is created by the Traefik stack at /opt/docker/traefik
|
||||
# and shared by every web-facing service on the host.
|
||||
#
|
||||
# Authentication: a single bearer token is passed through from the
|
||||
# host `.env` file via `CERBERO_BITE_MCP_TOKEN`. The Cerbero MCP V2
|
||||
# server uses the token to decide whether the upstream environment
|
||||
# is testnet or mainnet; switching environment = switching token.
|
||||
#
|
||||
# Two services are defined:
|
||||
# * `cerbero-bite` — the trading engine / CLI worker
|
||||
# * `cerbero-bite-gui` — the Streamlit dashboard, exposed by
|
||||
# Traefik at https://cerbero-bite.<DOMAIN>
|
||||
|
||||
networks:
|
||||
cerbero-suite:
|
||||
traefik:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
bite-data:
|
||||
|
||||
x-bite-env: &bite-env
|
||||
CERBERO_BITE_MCP_TOKEN: ${CERBERO_BITE_MCP_TOKEN:?missing CERBERO_BITE_MCP_TOKEN}
|
||||
CERBERO_BITE_MCP_BOT_TAG: ${CERBERO_BITE_MCP_BOT_TAG:-BOT__CERBERO_BITE}
|
||||
# Two independent runtime flags that decide what each cycle does.
|
||||
# Initial period ("data-only"): DATA_ANALYSIS=true, STRATEGY=false.
|
||||
CERBERO_BITE_ENABLE_DATA_ANALYSIS: ${CERBERO_BITE_ENABLE_DATA_ANALYSIS:-true}
|
||||
CERBERO_BITE_ENABLE_STRATEGY: ${CERBERO_BITE_ENABLE_STRATEGY:-false}
|
||||
# Service URLs — defaults below match the in-cluster Traefik network
|
||||
# DNS (V2 unified image listening on port 9000). Override any of
|
||||
# them via .env to point at the public gateway, a custom host, or
|
||||
# localhost for dev work.
|
||||
CERBERO_BITE_MCP_DERIBIT_URL: ${CERBERO_BITE_MCP_DERIBIT_URL:-http://cerbero-mcp:9000/mcp-deribit}
|
||||
CERBERO_BITE_MCP_HYPERLIQUID_URL: ${CERBERO_BITE_MCP_HYPERLIQUID_URL:-http://cerbero-mcp:9000/mcp-hyperliquid}
|
||||
CERBERO_BITE_MCP_MACRO_URL: ${CERBERO_BITE_MCP_MACRO_URL:-http://cerbero-mcp:9000/mcp-macro}
|
||||
CERBERO_BITE_MCP_SENTIMENT_URL: ${CERBERO_BITE_MCP_SENTIMENT_URL:-http://cerbero-mcp:9000/mcp-sentiment}
|
||||
|
||||
services:
|
||||
cerbero-bite:
|
||||
build:
|
||||
@@ -29,24 +50,12 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
image: cerbero-bite:dev
|
||||
restart: unless-stopped
|
||||
networks: [cerbero-suite]
|
||||
networks: [traefik]
|
||||
cap_drop: [ALL]
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
environment:
|
||||
# MCP auth — token is sourced from the host .env (compose
|
||||
# interpolation). The `X-Bot-Tag` value below is the audit
|
||||
# identifier the MCP server logs for every write call.
|
||||
CERBERO_BITE_MCP_TOKEN: ${CERBERO_BITE_MCP_TOKEN:?missing CERBERO_BITE_MCP_TOKEN}
|
||||
CERBERO_BITE_MCP_BOT_TAG: ${CERBERO_BITE_MCP_BOT_TAG:-BOT__CERBERO_BITE}
|
||||
# Service URLs — defaults below match the in-cluster cerbero-suite
|
||||
# network DNS (V2 unified image listening on port 9000). Override
|
||||
# any of them to point at the public gateway, a custom host, or
|
||||
# localhost for dev work.
|
||||
CERBERO_BITE_MCP_DERIBIT_URL: ${CERBERO_BITE_MCP_DERIBIT_URL:-http://cerbero-mcp:9000/mcp-deribit}
|
||||
CERBERO_BITE_MCP_HYPERLIQUID_URL: ${CERBERO_BITE_MCP_HYPERLIQUID_URL:-http://cerbero-mcp:9000/mcp-hyperliquid}
|
||||
CERBERO_BITE_MCP_MACRO_URL: ${CERBERO_BITE_MCP_MACRO_URL:-http://cerbero-mcp:9000/mcp-macro}
|
||||
CERBERO_BITE_MCP_SENTIMENT_URL: ${CERBERO_BITE_MCP_SENTIMENT_URL:-http://cerbero-mcp:9000/mcp-sentiment}
|
||||
<<: *bite-env
|
||||
# Telegram and Portfolio are no longer shared MCP services. The
|
||||
# bot now calls the Telegram Bot API directly and aggregates
|
||||
# portfolio in-process from Deribit + Hyperliquid + Macro.
|
||||
@@ -62,6 +71,62 @@ services:
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 120s
|
||||
# Default command runs the engine status check; override with the
|
||||
# CLI subcommand of choice (start, ping, dry-run, ...).
|
||||
command: ["status"]
|
||||
# Engine main loop (scheduler + monitoring). Switch to `status`,
|
||||
# `ping`, `dry-run`, ... for one-shot diagnostics. The MCP token in
|
||||
# `.env` decides the upstream environment server-side; the `start`
|
||||
# flag below tells the local boot check what to expect (must match,
|
||||
# otherwise the engine arms the kill switch).
|
||||
command: ["start", "--environment", "mainnet"]
|
||||
|
||||
# Streamlit dashboard published by Traefik on
|
||||
# https://cerbero-bite.${DOMAIN_NAME:-tielogic.xyz}
|
||||
#
|
||||
# The CLI sub-command `cerbero-bite gui` hard-codes the listen
|
||||
# address to 127.0.0.1, so we bypass the entrypoint and invoke
|
||||
# Streamlit directly. The two `CERBERO_BITE_GUI_*` env vars match
|
||||
# what the CLI normally injects (see src/cerbero_bite/cli.py).
|
||||
cerbero-bite-gui:
|
||||
image: cerbero-bite:dev
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- cerbero-bite
|
||||
networks: [traefik]
|
||||
cap_drop: [ALL]
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
environment:
|
||||
<<: *bite-env
|
||||
CERBERO_BITE_GUI_DB: /app/data/state.sqlite
|
||||
CERBERO_BITE_GUI_AUDIT: /app/data/log/audit.jsonl
|
||||
volumes:
|
||||
- bite-data:/app/data
|
||||
entrypoint:
|
||||
- python
|
||||
- -m
|
||||
- streamlit
|
||||
- run
|
||||
- /app/src/cerbero_bite/gui/main.py
|
||||
- --server.address=0.0.0.0
|
||||
- --server.port=8765
|
||||
- --server.headless=true
|
||||
- --browser.gatherUsageStats=false
|
||||
command: []
|
||||
healthcheck:
|
||||
test:
|
||||
- "CMD"
|
||||
- "python"
|
||||
- "-c"
|
||||
- "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8765/_stcore/health', timeout=3).close()"
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.docker.network=traefik
|
||||
- "traefik.http.routers.cerbero-bite.rule=Host(`cerbero-bite.${DOMAIN_NAME:-tielogic.xyz}`)"
|
||||
- traefik.http.routers.cerbero-bite.tls=true
|
||||
- traefik.http.routers.cerbero-bite.entrypoints=websecure
|
||||
- traefik.http.routers.cerbero-bite.tls.certresolver=mytlschallenge
|
||||
- traefik.http.services.cerbero-bite.loadbalancer.server.port=8765
|
||||
- com.centurylinklabs.watchtower.enable=true
|
||||
|
||||
Reference in New Issue
Block a user