refactor(dashboard): move multi_swarm_core/dashboard → strategy_crypto/frontend
- git mv data.py + nicegui_app.py al frontend strategy_crypto - Cancellato src/multi_swarm_core/multi_swarm_core/dashboard/ - Patch import in data.py: ..persistence → multi_swarm_core.persistence - Patch nicegui_app.py: * Import: multi_swarm_core.dashboard.data → strategy_crypto.frontend.data * Dual-DB: split DB_PATH in GA_DB_PATH + PAPER_DB_PATH (env separati) * Subpath routing: DASHBOARD_ROOT_PATH passato a ui.run(root_path=...) * Header dashboard mostra entrambi i DB * Docstring di avvio aggiornata: python -m strategy_crypto.frontend.nicegui_app * Title rinominato "Strategy Crypto Dashboard" - 6 occorrenze get_repo(DB_PATH) → get_repo(GA_DB_PATH) - 6 occorrenze paper_*_df(DB_PATH, ...) → paper_*_df(PAPER_DB_PATH, ...) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@ from typing import Any
|
||||
|
||||
import pandas as pd # type: ignore[import-untyped]
|
||||
|
||||
from ..persistence.repository import Repository
|
||||
from multi_swarm_core.persistence.repository import Repository
|
||||
|
||||
|
||||
def get_repo(db_path: str | Path) -> Repository:
|
||||
+30
-19
@@ -1,6 +1,6 @@
|
||||
"""NiceGUI dashboard — port progressivo da Streamlit.
|
||||
|
||||
Avvio: ``uv run python -m multi_swarm_core.dashboard.nicegui_app``
|
||||
Avvio: ``uv run python -m strategy_crypto.frontend.nicegui_app``
|
||||
Default port 8080. Streamlit resta su 8501 durante la migrazione.
|
||||
|
||||
Riusa ``dashboard.data`` (Repository helpers) senza modifiche al backend.
|
||||
@@ -28,7 +28,7 @@ import pandas as pd # type: ignore[import-untyped]
|
||||
import plotly.graph_objects as go # type: ignore[import-untyped]
|
||||
from nicegui import app, ui
|
||||
|
||||
from multi_swarm_core.dashboard.data import (
|
||||
from strategy_crypto.frontend.data import (
|
||||
evaluations_df,
|
||||
generations_df,
|
||||
genomes_df,
|
||||
@@ -43,7 +43,11 @@ from multi_swarm_core.dashboard.data import (
|
||||
paper_trades_df,
|
||||
)
|
||||
|
||||
DB_PATH = os.environ.get("DB_PATH", "./runs.db")
|
||||
# Dual-DB: GA core e paper strategy_crypto vivono in DB separati.
|
||||
GA_DB_PATH = os.environ.get("GA_DB_PATH", "./state/runs.db")
|
||||
PAPER_DB_PATH = os.environ.get("STRATEGY_CRYPTO_DB_PATH", "./state/strategy_crypto.db")
|
||||
# Subpath per Traefik: "" in dev, "/strategy_crypto_gui" in prod.
|
||||
DASHBOARD_ROOT_PATH = os.environ.get("DASHBOARD_ROOT_PATH", "")
|
||||
REFRESH_INTERVAL_S = 3.0
|
||||
|
||||
# --- Neon Trading Dashboard palette ---
|
||||
@@ -384,11 +388,11 @@ def _build_header(active: str) -> None:
|
||||
with ui.row().classes("items-center gap-3"):
|
||||
ui.html(f'<span style="color:{COLOR_TEXT_MUTED};font-size:12px;'
|
||||
f'font-family:JetBrains Mono,monospace;">'
|
||||
f'⛁ {Path(DB_PATH).resolve().name}</span>')
|
||||
f'⛁ {Path(GA_DB_PATH).resolve().name} + {Path(PAPER_DB_PATH).resolve().name}</span>')
|
||||
|
||||
|
||||
def _runs_options() -> dict[str, str]:
|
||||
repo = get_repo(DB_PATH)
|
||||
repo = get_repo(GA_DB_PATH)
|
||||
runs = list_runs_df(repo)
|
||||
if runs.empty:
|
||||
return {}
|
||||
@@ -399,7 +403,7 @@ def _runs_options() -> dict[str, str]:
|
||||
|
||||
|
||||
def _snapshot(run_id: str) -> dict[str, Any]:
|
||||
repo = get_repo(DB_PATH)
|
||||
repo = get_repo(GA_DB_PATH)
|
||||
ov = get_run_overview(repo, run_id)
|
||||
evals = evaluations_df(repo, run_id)
|
||||
gens = generations_df(repo, run_id)
|
||||
@@ -632,8 +636,8 @@ def convergence() -> None:
|
||||
)
|
||||
ui.button("🔄 Refresh", on_click=lambda: refresh()).props("outline color=primary")
|
||||
|
||||
fitness_plot = ui.plotly(_convergence_figure(generations_df(get_repo(DB_PATH), state["run_id"]))).classes("w-full")
|
||||
entropy_plot = ui.plotly(_entropy_figure(generations_df(get_repo(DB_PATH), state["run_id"]))).classes("w-full q-mt-md")
|
||||
fitness_plot = ui.plotly(_convergence_figure(generations_df(get_repo(GA_DB_PATH), state["run_id"]))).classes("w-full")
|
||||
entropy_plot = ui.plotly(_entropy_figure(generations_df(get_repo(GA_DB_PATH), state["run_id"]))).classes("w-full q-mt-md")
|
||||
|
||||
ui.separator()
|
||||
ui.label("Tabella generazioni").classes("text-subtitle1 q-mt-md")
|
||||
@@ -656,8 +660,8 @@ def convergence() -> None:
|
||||
if not run_id:
|
||||
return
|
||||
try:
|
||||
gens = generations_df(get_repo(DB_PATH), run_id)
|
||||
ov = get_run_overview(get_repo(DB_PATH), run_id)
|
||||
gens = generations_df(get_repo(GA_DB_PATH), run_id)
|
||||
ov = get_run_overview(get_repo(GA_DB_PATH), run_id)
|
||||
except Exception as e: # noqa: BLE001
|
||||
ui.notify(f"Errore: {e}", type="negative")
|
||||
return
|
||||
@@ -801,7 +805,7 @@ def genomes() -> None:
|
||||
if not run_id:
|
||||
return
|
||||
try:
|
||||
repo = get_repo(DB_PATH)
|
||||
repo = get_repo(GA_DB_PATH)
|
||||
evals = evaluations_df(repo, run_id)
|
||||
gens = genomes_df(repo, run_id)
|
||||
except Exception as e: # noqa: BLE001
|
||||
@@ -874,7 +878,7 @@ def genomes() -> None:
|
||||
|
||||
|
||||
def _paper_runs_options(only_running: bool = False) -> dict[str, str]:
|
||||
runs = paper_runs_df(DB_PATH)
|
||||
runs = paper_runs_df(PAPER_DB_PATH)
|
||||
if runs.empty:
|
||||
return {}
|
||||
if only_running:
|
||||
@@ -1014,11 +1018,11 @@ def paper() -> None:
|
||||
if not run_id:
|
||||
return
|
||||
try:
|
||||
summary = paper_run_summary(DB_PATH, run_id)
|
||||
eq = paper_equity_df(DB_PATH, run_id)
|
||||
positions = paper_positions_df(DB_PATH, run_id)
|
||||
ticks = paper_ticks_df(DB_PATH, run_id, limit=30)
|
||||
trades = paper_trades_df(DB_PATH, run_id, limit=50)
|
||||
summary = paper_run_summary(PAPER_DB_PATH, run_id)
|
||||
eq = paper_equity_df(PAPER_DB_PATH, run_id)
|
||||
positions = paper_positions_df(PAPER_DB_PATH, run_id)
|
||||
ticks = paper_ticks_df(PAPER_DB_PATH, run_id, limit=30)
|
||||
trades = paper_trades_df(PAPER_DB_PATH, run_id, limit=50)
|
||||
except Exception as e: # noqa: BLE001
|
||||
ui.notify(f"Errore: {e}", type="negative")
|
||||
return
|
||||
@@ -1081,14 +1085,21 @@ def paper() -> None:
|
||||
|
||||
|
||||
def main() -> None:
|
||||
app.on_startup(lambda: print(f"DB: {Path(DB_PATH).resolve()}"))
|
||||
app.on_startup(
|
||||
lambda: print(
|
||||
f"GA DB: {Path(GA_DB_PATH).resolve()} | "
|
||||
f"Paper DB: {Path(PAPER_DB_PATH).resolve()} | "
|
||||
f"root_path: {DASHBOARD_ROOT_PATH or '/'}"
|
||||
)
|
||||
)
|
||||
ui.run(
|
||||
host="0.0.0.0",
|
||||
port=int(os.environ.get("SWARM_DASHBOARD_PORT", "8080")),
|
||||
title="Multi-Swarm Dashboard",
|
||||
title="Strategy Crypto Dashboard",
|
||||
reload=False,
|
||||
show=False,
|
||||
dark=True,
|
||||
root_path=DASHBOARD_ROOT_PATH,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user