diff --git a/src/multi_swarm_core/multi_swarm_core/dashboard/__init__.py b/src/multi_swarm_core/multi_swarm_core/dashboard/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/multi_swarm_core/multi_swarm_core/dashboard/data.py b/src/strategy_crypto/strategy_crypto/frontend/data.py similarity index 98% rename from src/multi_swarm_core/multi_swarm_core/dashboard/data.py rename to src/strategy_crypto/strategy_crypto/frontend/data.py index 33503ff..738a008 100644 --- a/src/multi_swarm_core/multi_swarm_core/dashboard/data.py +++ b/src/strategy_crypto/strategy_crypto/frontend/data.py @@ -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: diff --git a/src/multi_swarm_core/multi_swarm_core/dashboard/nicegui_app.py b/src/strategy_crypto/strategy_crypto/frontend/nicegui_app.py similarity index 96% rename from src/multi_swarm_core/multi_swarm_core/dashboard/nicegui_app.py rename to src/strategy_crypto/strategy_crypto/frontend/nicegui_app.py index 184cc83..eca9201 100644 --- a/src/multi_swarm_core/multi_swarm_core/dashboard/nicegui_app.py +++ b/src/strategy_crypto/strategy_crypto/frontend/nicegui_app.py @@ -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'' - f'⛁ {Path(DB_PATH).resolve().name}') + f'⛁ {Path(GA_DB_PATH).resolve().name} + {Path(PAPER_DB_PATH).resolve().name}') 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, )