"""ENTRYPOINT #3 — quick CLI summary of holdings, PnL, orders, and last night's theses. The dashboard covers this visually; this is a terminal-friendly glance. uv run python -m reporting.report """ from __future__ import annotations import json import sqlite3 import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from config.settings import get_settings # noqa: E402 def main() -> int: s = get_settings() print("=== Overnight Trading Agent — report ===\n") if s.db_path.exists(): con = sqlite3.connect(str(s.db_path)) con.row_factory = sqlite3.Row snap = con.execute("SELECT * FROM snapshots ORDER BY ts DESC LIMIT 1").fetchone() if snap: print(f"Equity ${snap['equity']:,.2f} | cash ${snap['cash']:,.2f} | " f"buying power ${snap['buying_power']:,.2f}") print(f" (as of {snap['ts']})") positions = con.execute( "SELECT * FROM positions ORDER BY market_value DESC" ).fetchall() if positions: print("\nHoldings:") for p in positions: print(f" {p['symbol']:6} qty {p['qty']:>6} @ {p['avg_entry']:>8} " f"→ mv {p['market_value']:>10} | uPnL {p['unrealized_pl']:>8}") orders = con.execute("SELECT * FROM orders ORDER BY submitted_at DESC LIMIT 10").fetchall() if orders: print("\nRecent orders:") for o in orders: print(f" {o['trade_date']} {o['agent']:12} {o['ticker']:6} x{o['qty']:<4} " f"{o['status']}") con.close() else: print("No state DB yet — run execution once to populate it.") dates = ( sorted((p.name for p in s.output_dir.iterdir() if p.is_dir()), reverse=True) if s.output_dir.exists() else [] ) if dates: d = dates[0] print(f"\nLatest theses ({d}):") for f in sorted((s.output_dir / d).glob("*.json")): if f.name.startswith("_"): continue j = json.loads(f.read_text()) picks = ", ".join(f"{p['ticker']}({p['conviction']:.2f})" for p in j["picks"]) print(f" {j['agent_name']:35} [{j['status']:8}] {picks or '(no picks)'}") else: print("\nNo nightly output yet.") return 0 if __name__ == "__main__": raise SystemExit(main())