refactor: Simplify variable names and improve readability in metrics and lifecycle modules
CI / lint-test-build (push) Failing after 11s

This commit is contained in:
2026-06-01 15:44:17 +02:00
parent 0d1f6961d6
commit 6c7dd0a715
3 changed files with 134 additions and 156 deletions
+97 -88
View File
@@ -86,7 +86,7 @@ def _dashboard_overview(request: Request) -> dict[str, object]:
ORDER BY started_at DESC ORDER BY started_at DESC
LIMIT 5 LIMIT 5
""").fetchall() """).fetchall()
pnl_total_row = conn.execute(""" rpnl = conn.execute("""
SELECT COALESCE(SUM(COALESCE(realized_pnl, 0)), 0) SELECT COALESCE(SUM(COALESCE(realized_pnl, 0)), 0)
FROM trades FROM trades
""").fetchone() """).fetchone()
@@ -131,7 +131,7 @@ def _dashboard_overview(request: Request) -> dict[str, object]:
"total_value": total_value, "total_value": total_value,
"open_trade_count": len(open_trade_rows), "open_trade_count": len(open_trade_rows),
"open_trades": open_trade_rows, "open_trades": open_trade_rows,
"realized_pnl_total": f"{float(pnl_total_row[0]):.2f} USD" if pnl_total_row else "", "realized_pnl_total": f"{float(rpnl[0]):.2f} USD" if rpnl else "",
"opportunities": opportunity_rows, "opportunities": opportunity_rows,
} }
@@ -146,21 +146,23 @@ def _dashboard_charts(request: Request) -> dict[str, object]:
LIMIT 10 LIMIT 10
""").fetchall() """).fetchall()
chart_rows = list(reversed(opportunity_rows)) cr = list(reversed(opportunity_rows))
labels = [ labels = []
row[0].isoformat() if isinstance(row[0], datetime) else f"opportunity-{index + 1}" for index, row in enumerate(cr):
for index, row in enumerate(chart_rows) if isinstance(row[0], datetime):
] labels.append(row[0].isoformat())
net_pct_values = [float(row[2]) if row[2] is not None else 0.0 for row in chart_rows] else:
est_profit_values = [float(row[3]) if row[3] is not None else 0.0 for row in chart_rows] labels.append(f"opportunity-{index + 1}")
cycles = [str(row[1]) for row in chart_rows] np = [float(row[2]) if row[2] is not None else 0.0 for row in cr]
ep = [float(row[3]) if row[3] is not None else 0.0 for row in cr]
cycles = [str(row[1]) for row in cr]
return { return {
"labels": labels, "labels": labels,
"net_pct_values": net_pct_values, "net_pct_values": np,
"est_profit_values": est_profit_values, "est_profit_values": ep,
"cycles": cycles, "cycles": cycles,
"has_chart_data": bool(chart_rows), "has_chart_data": bool(cr),
"generated_at": datetime.now(UTC).isoformat(), "generated_at": datetime.now(UTC).isoformat(),
} }
@@ -186,13 +188,17 @@ def _record_audit(
if repository is None: if repository is None:
return return
correlation_id = request.headers.get("x-request-id") correlation_id = request.headers.get("x-request-id")
if payload is not None:
ret_pl = {str(key): payload[key] for key in payload}
else:
ret_pl = None
repository.insert( repository.insert(
AuditRecord( AuditRecord(
occurred_at=datetime.now(UTC), occurred_at=datetime.now(UTC),
actor=actor, actor=actor,
event_type=event_type, event_type=event_type,
decision=decision, decision=decision,
payload=None if payload is None else {str(key): payload[key] for key in payload}, payload=ret_pl,
correlation_id=correlation_id, correlation_id=correlation_id,
) )
) )
@@ -254,8 +260,8 @@ def _alert_status_snapshot(request: Request) -> dict[str, object]:
def _dashboard_controls(request: Request) -> dict[str, object]: def _dashboard_controls(request: Request) -> dict[str, object]:
controls = _dashboard_controls_state(request) ctl = _dashboard_controls_state(request)
settings = request.app.state.settings rs = request.app.state.settings
alert_status = _alert_status_snapshot(request) alert_status = _alert_status_snapshot(request)
last_event = alert_status.get("last_event") last_event = alert_status.get("last_event")
last_event_title = "" last_event_title = ""
@@ -264,44 +270,47 @@ def _dashboard_controls(request: Request) -> dict[str, object]:
if isinstance(title_value, str): if isinstance(title_value, str):
last_event_title = title_value last_event_title = title_value
configured_channels = alert_status.get("configured_channels") cc = alert_status.get("configured_channels")
channels_display = "" cd = ""
if isinstance(configured_channels, list) and configured_channels: if isinstance(cc, list) and cc:
channels_display = ", ".join(str(channel) for channel in configured_channels) cd = ", ".join(str(channel) for channel in cc)
dedup_seconds_raw = alert_status.get("dedup_seconds", 0.0) ddsr = alert_status.get("dedup_seconds", 0.0)
dedup_seconds = float(dedup_seconds_raw) if isinstance(dedup_seconds_raw, int | float) else 0.0 dds = float(ddsr) if isinstance(ddsr, int | float) else 0.0
tradable_pairs_display = ( tpd = ", ".join(ctl.tradable_pairs) if ctl.tradable_pairs else "All"
", ".join(controls.tradable_pairs) if controls.tradable_pairs else "All" max_trade_capital_usd = (
f"{float(rs.max_trade_capital_usd):.2f} USD"
if rs.max_trade_capital_usd is not None
else ""
) )
max_trade_capital_usd_value = (
f"{float(rs.max_trade_capital_usd):.2f}" if rs.max_trade_capital_usd is not None else ""
)
max_concurrent_trades = (
str(rs.max_concurrent_trades) if rs.max_concurrent_trades is not None else ""
)
max_concurrent_trades_value = (
str(rs.max_concurrent_trades) if rs.max_concurrent_trades is not None else ""
)
alerts_last_channel_results = [
str(item) for item in cast(list[object], alert_status.get("last_channel_results", []))
]
return { return {
"execution_status": "running" if controls.is_running else "stopped", "execution_status": "running" if ctl.is_running else "stopped",
"kill_switch_status": "active" if controls.kill_switch.is_active else "inactive", "kill_switch_status": "active" if ctl.kill_switch.is_active else "inactive",
"kill_switch_reason": controls.kill_switch.reason or "", "kill_switch_reason": ctl.kill_switch.reason or "",
"paper_trading_mode": "enabled" if settings.paper_trading_mode else "disabled", "paper_trading_mode": "enabled" if rs.paper_trading_mode else "disabled",
"trade_capital_usd": f"{float(settings.trade_capital_usd):.2f} USD", "trade_capital_usd": f"{float(rs.trade_capital_usd):.2f} USD",
"trade_capital_usd_value": f"{float(settings.trade_capital_usd):.2f}", "trade_capital_usd_value": f"{float(rs.trade_capital_usd):.2f}",
"max_trade_capital_usd": ( "max_trade_capital_usd": max_trade_capital_usd,
"" "max_trade_capital_usd_value": max_trade_capital_usd_value,
if settings.max_trade_capital_usd is None "max_concurrent_trades": max_concurrent_trades,
else f"{float(settings.max_trade_capital_usd):.2f} USD" "max_concurrent_trades_value": max_concurrent_trades_value,
),
"max_trade_capital_usd_value": (
""
if settings.max_trade_capital_usd is None
else f"{float(settings.max_trade_capital_usd):.2f}"
),
"max_concurrent_trades": (
"" if settings.max_concurrent_trades is None else str(settings.max_concurrent_trades)
),
"max_concurrent_trades_value": (
"" if settings.max_concurrent_trades is None else str(settings.max_concurrent_trades)
),
"alerts_enabled": "enabled" if bool(alert_status.get("enabled", False)) else "disabled", "alerts_enabled": "enabled" if bool(alert_status.get("enabled", False)) else "disabled",
"alerts_channels": channels_display, "alerts_channels": cd,
"alerts_min_severity": str(alert_status.get("min_severity", "")), "alerts_min_severity": str(alert_status.get("min_severity", "")),
"alerts_dedup_seconds": f"{dedup_seconds:.0f}", "alerts_dedup_seconds": f"{dds:.0f}",
"alerts_last_result": str(alert_status.get("last_result", "unavailable")), "alerts_last_result": str(alert_status.get("last_result", "unavailable")),
"alerts_last_attempted_at": str(alert_status.get("last_attempted_at") or ""), "alerts_last_attempted_at": str(alert_status.get("last_attempted_at") or ""),
"alerts_last_success_at": str(alert_status.get("last_success_at") or ""), "alerts_last_success_at": str(alert_status.get("last_success_at") or ""),
@@ -310,12 +319,12 @@ def _dashboard_controls(request: Request) -> dict[str, object]:
"alerts_last_channel_results": [ "alerts_last_channel_results": [
str(item) for item in cast(list[object], alert_status.get("last_channel_results", [])) str(item) for item in cast(list[object], alert_status.get("last_channel_results", []))
], ],
"tradable_pairs_display": tradable_pairs_display, "tradable_pairs_display": tpd,
"tradable_pairs_value": ", ".join(controls.tradable_pairs), "tradable_pairs_value": ", ".join(ctl.tradable_pairs),
"strategy_mode": controls.strategy_mode, "strategy_mode": ctl.strategy_mode,
"strategy_profit_threshold": f"{controls.strategy_profit_threshold:.6f}", "strategy_profit_threshold": f"{ctl.strategy_profit_threshold:.6f}",
"strategy_max_depth_levels": str(controls.strategy_max_depth_levels), "strategy_max_depth_levels": str(ctl.strategy_max_depth_levels),
"updated_at": controls.updated_at.isoformat(), "updated_at": ctl.updated_at.isoformat(),
"start_endpoint": "/dashboard/control/start", "start_endpoint": "/dashboard/control/start",
"stop_endpoint": "/dashboard/control/stop", "stop_endpoint": "/dashboard/control/stop",
"kill_switch_endpoint": "/dashboard/control/kill-switch", "kill_switch_endpoint": "/dashboard/control/kill-switch",
@@ -519,34 +528,38 @@ async def dashboard_control_kill_switch(request: Request) -> HTMLResponse:
@router.post("/dashboard/control/config", response_class=HTMLResponse) @router.post("/dashboard/control/config", response_class=HTMLResponse)
async def dashboard_control_config(request: Request) -> HTMLResponse: async def dashboard_control_config(request: Request) -> HTMLResponse:
controls = _dashboard_controls_state(request) ctl = _dashboard_controls_state(request)
settings = request.app.state.settings rs = request.app.state.settings
form = _parse_form_body(await request.body()) form = _parse_form_body(await request.body())
if "trade_capital_usd" in form and form["trade_capital_usd"]: if "trade_capital_usd" in form and form["trade_capital_usd"]:
settings.trade_capital_usd = float(form["trade_capital_usd"]) rs.trade_capital_usd = float(form["trade_capital_usd"])
if "max_trade_capital_usd" in form: if "max_trade_capital_usd" in form:
max_trade_capital_value = form["max_trade_capital_usd"].strip() mtcv = form["max_trade_capital_usd"].strip()
settings.max_trade_capital_usd = ( rs.max_trade_capital_usd = float(mtcv) if mtcv else None
float(max_trade_capital_value) if max_trade_capital_value else None
)
if "max_concurrent_trades" in form: if "max_concurrent_trades" in form:
max_concurrent_value = form["max_concurrent_trades"].strip() mcv = form["max_concurrent_trades"].strip()
settings.max_concurrent_trades = int(max_concurrent_value) if max_concurrent_value else None rs.max_concurrent_trades = int(mcv) if mcv else None
controls.tradable_pairs = _parse_comma_separated_list(form.get("tradable_pairs")) form_pairs = form.get("tradable_pairs")
ctl.tradable_pairs = _parse_comma_separated_list(form_pairs)
if "strategy_mode" in form and form["strategy_mode"].strip(): if "strategy_mode" in form and form["strategy_mode"].strip():
strategy_mode = form["strategy_mode"].strip().lower() strategy_mode = form["strategy_mode"].strip().lower()
if strategy_mode not in {"incremental", "paper", "live"}: if strategy_mode not in {"incremental", "paper", "live"}:
raise ValueError("strategy_mode must be one of: incremental, paper, live") e = "strategy_mode must be one of: incremental, paper, live"
controls.strategy_mode = strategy_mode raise ValueError(e)
if "strategy_profit_threshold" in form and form["strategy_profit_threshold"].strip(): ctl.strategy_mode = strategy_mode
controls.strategy_profit_threshold = float(form["strategy_profit_threshold"]) if "strategy_profit_threshold" in form:
if "strategy_max_depth_levels" in form and form["strategy_max_depth_levels"].strip(): if form["strategy_profit_threshold"].strip():
controls.strategy_max_depth_levels = int(form["strategy_max_depth_levels"]) spt = float(form["strategy_profit_threshold"])
ctl.strategy_profit_threshold = spt
if "strategy_max_depth_levels" in form:
if form["strategy_max_depth_levels"].strip():
smdl = int(form["strategy_max_depth_levels"])
ctl.strategy_max_depth_levels = smdl
settings.paper_trading_mode = _form_bool(form.get("paper_trading_mode")) rs.paper_trading_mode = _form_bool(form.get("paper_trading_mode"))
controls.mark_updated() ctl.mark_updated()
notifier = _alert_notifier(request) notifier = _alert_notifier(request)
if notifier is not None: if notifier is not None:
@@ -556,18 +569,14 @@ async def dashboard_control_config(request: Request) -> HTMLResponse:
title="Runtime config updated", title="Runtime config updated",
message="Dashboard control updated runtime risk and execution settings.", message="Dashboard control updated runtime risk and execution settings.",
details={ details={
"trade_capital_usd": f"{settings.trade_capital_usd}", "trade_capital_usd": f"{rs.trade_capital_usd}",
"max_trade_capital_usd": ( "max_trade_capital_usd": (
"none" "none" if rs.max_trade_capital_usd is None else f"{rs.max_trade_capital_usd}"
if settings.max_trade_capital_usd is None
else f"{settings.max_trade_capital_usd}"
), ),
"max_concurrent_trades": ( "max_concurrent_trades": (
"none" "none" if rs.max_concurrent_trades is None else f"{rs.max_concurrent_trades}"
if settings.max_concurrent_trades is None
else f"{settings.max_concurrent_trades}"
), ),
"paper_trading_mode": "true" if settings.paper_trading_mode else "false", "paper_trading_mode": "true" if rs.paper_trading_mode else "false",
}, },
) )
_record_audit( _record_audit(
@@ -576,14 +585,14 @@ async def dashboard_control_config(request: Request) -> HTMLResponse:
event_type="dashboard.control.config", event_type="dashboard.control.config",
decision="approved", decision="approved",
payload={ payload={
"trade_capital_usd": settings.trade_capital_usd, "trade_capital_usd": rs.trade_capital_usd,
"max_trade_capital_usd": settings.max_trade_capital_usd, "max_trade_capital_usd": rs.max_trade_capital_usd,
"max_concurrent_trades": settings.max_concurrent_trades, "max_concurrent_trades": rs.max_concurrent_trades,
"paper_trading_mode": settings.paper_trading_mode, "paper_trading_mode": rs.paper_trading_mode,
"tradable_pairs": controls.tradable_pairs, "tradable_pairs": ctl.tradable_pairs,
"strategy_mode": controls.strategy_mode, "strategy_mode": ctl.strategy_mode,
"strategy_profit_threshold": controls.strategy_profit_threshold, "strategy_profit_threshold": ctl.strategy_profit_threshold,
"strategy_max_depth_levels": controls.strategy_max_depth_levels, "strategy_max_depth_levels": ctl.strategy_max_depth_levels,
}, },
) )
+25 -57
View File
@@ -24,7 +24,7 @@ class MetricsCalculator:
def compute(self) -> PerformanceMetrics: def compute(self) -> PerformanceMetrics:
with self._store.connect() as conn: with self._store.connect() as conn:
trade_metrics = conn.execute(""" tm = conn.execute("""
SELECT SELECT
COALESCE(SUM(COALESCE(realized_pnl, 0)), 0) AS realized_pnl_usd, COALESCE(SUM(COALESCE(realized_pnl, 0)), 0) AS realized_pnl_usd,
COUNT(*) AS total_trades, COUNT(*) AS total_trades,
@@ -46,7 +46,7 @@ class MetricsCalculator:
WHERE finished_at IS NOT NULL WHERE finished_at IS NOT NULL
""").fetchone() """).fetchone()
opportunity_metrics = conn.execute(""" om = conn.execute("""
SELECT SELECT
COUNT(*) AS opportunity_count, COUNT(*) AS opportunity_count,
MIN(detected_at) AS first_detected_at, MIN(detected_at) AS first_detected_at,
@@ -54,79 +54,47 @@ class MetricsCalculator:
FROM opportunities FROM opportunities
""").fetchone() """).fetchone()
fill_metrics = conn.execute(""" fm = conn.execute("""
SELECT AVG(filled_volume / volume) AS fill_rate SELECT AVG(filled_volume / volume) AS fill_rate
FROM orders FROM orders
WHERE volume > 0 AND filled_volume IS NOT NULL WHERE volume > 0 AND filled_volume IS NOT NULL
""").fetchone() """).fetchone()
realized_pnl_usd = ( r_pnl_usd = float(tm[0]) if tm and tm[0] is not None else 0.0
float(trade_metrics[0]) if trade_metrics and trade_metrics[0] is not None else 0.0 tt = int(tm[1]) if tm and tm[1] is not None else 0
) wt = int(tm[2]) if tm and tm[2] is not None else 0
total_trades = ( wr = wt / tt if tt > 0 else None
int(trade_metrics[1]) if trade_metrics and trade_metrics[1] is not None else 0
)
winning_trades = (
int(trade_metrics[2]) if trade_metrics and trade_metrics[2] is not None else 0
)
win_rate = winning_trades / total_trades if total_trades > 0 else None
avg_trade_duration_seconds = ( atd = float(tm[3]) if tm and tm[3] is not None else None
float(trade_metrics[3]) if trade_metrics and trade_metrics[3] is not None else None
)
opportunity_count = ( oc = int(om[0]) if om is not None and om[0] is not None else 0
int(opportunity_metrics[0]) fo = om[1] if om is not None and isinstance(om[1], datetime) else None
if opportunity_metrics is not None and opportunity_metrics[0] is not None lo = om[2] if om is not None and isinstance(om[2], datetime) else None
else 0
)
first_detected_at = (
opportunity_metrics[1]
if opportunity_metrics is not None and isinstance(opportunity_metrics[1], datetime)
else None
)
last_detected_at = (
opportunity_metrics[2]
if opportunity_metrics is not None and isinstance(opportunity_metrics[2], datetime)
else None
)
opportunities_per_minute: float | None opportunities_per_minute: float | None
if ( if oc >= 2 and fo is not None and lo is not None:
opportunity_count >= 2 span_seconds = (lo - fo).total_seconds()
and first_detected_at is not None
and last_detected_at is not None
):
span_seconds = (last_detected_at - first_detected_at).total_seconds()
opportunities_per_minute = ( opportunities_per_minute = (
opportunity_count / (span_seconds / 60.0) oc / (span_seconds / 60.0) if span_seconds > 0.0 else float(oc)
if span_seconds > 0.0
else float(opportunity_count)
) )
elif opportunity_count == 1: elif oc == 1:
opportunities_per_minute = 60.0 opportunities_per_minute = 60.0
else: else:
opportunities_per_minute = None opportunities_per_minute = None
fill_rate = float(fill_metrics[0]) if fill_metrics and fill_metrics[0] is not None else None fill_rate = float(fm[0]) if fm and fm[0] is not None else None
latency_p50_seconds = ( lp50 = float(tm[4]) if tm and tm[4] is not None else None
float(trade_metrics[4]) if trade_metrics and trade_metrics[4] is not None else None lp95 = float(tm[5]) if tm and tm[5] is not None else None
) lp99 = float(tm[6]) if tm and tm[6] is not None else None
latency_p95_seconds = (
float(trade_metrics[5]) if trade_metrics and trade_metrics[5] is not None else None
)
latency_p99_seconds = (
float(trade_metrics[6]) if trade_metrics and trade_metrics[6] is not None else None
)
return PerformanceMetrics( return PerformanceMetrics(
realized_pnl_usd=realized_pnl_usd, realized_pnl_usd=r_pnl_usd,
win_rate=win_rate, win_rate=wr,
avg_trade_duration_seconds=avg_trade_duration_seconds, avg_trade_duration_seconds=atd,
opportunities_per_minute=opportunities_per_minute, opportunities_per_minute=opportunities_per_minute,
fill_rate=fill_rate, fill_rate=fill_rate,
latency_p50_seconds=latency_p50_seconds, latency_p50_seconds=lp50,
latency_p95_seconds=latency_p95_seconds, latency_p95_seconds=lp95,
latency_p99_seconds=latency_p99_seconds, latency_p99_seconds=lp99,
) )
+12 -11
View File
@@ -127,31 +127,32 @@ def persist_runtime_snapshot(app: FastAPI, *, note: str | None = None) -> Runtim
async def restore_runtime_state(app: FastAPI) -> RuntimeRecoveryReport: async def restore_runtime_state(app: FastAPI) -> RuntimeRecoveryReport:
controls = _controls(app) ctl = _controls(app)
store = _store(app) store = _store(app)
runtime_repository = _runtime_repository(app) repo = _runtime_repository(app)
restored_from_snapshot = False restored_from_snapshot = False
snapshot_at: str | None = None snapshot_at: str | None = None
latest = runtime_repository.latest() if runtime_repository is not None else None latest = repo.latest() if repo is not None else None
if latest is not None: if latest is not None:
restored_from_snapshot = True restored_from_snapshot = True
snapshot_at = latest.snapshot_at.isoformat() snapshot_at = latest.snapshot_at.isoformat()
controls.is_running = latest.is_running ctl.is_running = latest.is_running
if latest.kill_switch_active: if latest.kill_switch_active:
controls.kill_switch.activate(reason=latest.kill_switch_reason or "recovered") r = latest.kill_switch_reason or "recovered"
ctl.kill_switch.activate(reason=r)
else: else:
controls.kill_switch.deactivate() ctl.kill_switch.deactivate()
controls.mark_updated() ctl.mark_updated()
open_trades = _open_trade_count(store) open_trades = _open_trade_count(store)
restart_guard_active = False restart_guard_active = False
if open_trades > 0: if open_trades > 0:
controls.is_running = False ctl.is_running = False
if not controls.kill_switch.is_active: if not ctl.kill_switch.is_active:
controls.kill_switch.activate(reason="recovery_open_trades_detected") ctl.kill_switch.activate(reason="recovery_open_trades_detected")
controls.mark_updated() ctl.mark_updated()
restart_guard_active = True restart_guard_active = True
report = RuntimeRecoveryReport( report = RuntimeRecoveryReport(