#!/usr/bin/env python3 """DOLPHIN live status — zero-dependency rolling display. Polls HZ every 5s, prints a compact status block. No curses, no textual. Run: source /home/dolphin/siloqy_env/bin/activate && python dolphin_status.py """ import json, os, time, sys from datetime import datetime, timezone import hazelcast CLEAR = "\033[2J\033[H" BOLD = "\033[1m"; DIM = "\033[2m"; RST = "\033[0m" GREEN = "\033[32m"; YELLOW = "\033[33m"; RED = "\033[31m"; CYAN = "\033[36m" PC = {"APEX": GREEN, "STALKER": YELLOW, "TURTLE": "\033[38;5;208m", "HIBERNATE": RED} SC = {"GREEN": GREEN, "DEGRADED": YELLOW, "CRITICAL": "\033[38;5;208m", "DEAD": RED} START_CAP = None CAP_PEAK = None def _age(ts): if not ts: return "?" s = time.time() - ts if s < 0: return "0s" if s < 60: return f"{s:.0f}s" if s < 3600: return f"{s/60:.0f}m" return f"{s/3600:.1f}h" def _bar(v, w=20): v = max(0.0, min(1.0, v)) f = round(v * w) return "█" * f + "░" * (w - f) def _get(hz, map_name, key): try: raw = hz.get_map(map_name).blocking().get(key) return json.loads(raw) if raw else {} except Exception: return {} def render(hz): global START_CAP, CAP_PEAK eng = _get(hz, "DOLPHIN_STATE_BLUE", "engine_snapshot") cap = _get(hz, "DOLPHIN_STATE_BLUE", "capital_checkpoint") safe = _get(hz, "DOLPHIN_SAFETY", "latest") hb = _get(hz, "DOLPHIN_HEARTBEAT", "nautilus_flow_heartbeat") mh = _get(hz, "DOLPHIN_META_HEALTH", "latest") acb = _get(hz, "DOLPHIN_FEATURES", "acb_boost") now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC") capital = float(eng.get("capital", 0) or cap.get("capital", 0)) posture = safe.get("posture") or eng.get("posture") or "?" rm = float(safe.get("Rm", 0)) bd = safe.get("breakdown", {}) hb_ts = hb.get("ts") hb_age = _age(hb_ts) phase = hb.get("phase", "?") trader_up = hb_ts and (time.time() - hb_ts) < 30 trades = eng.get("trades_executed", "—") scans = eng.get("scans_processed", "—") lev = float(eng.get("current_leverage", 0)) notional = float(eng.get("open_notional", 0)) mhs_st = mh.get("status", "?") rm_meta = float(mh.get("rm_meta", 0)) boost = float(acb.get("boost", acb.get("cut", 0))) vel_div = float(eng.get("last_vel_div", 0)) if capital > 0: if START_CAP is None: START_CAP = capital if CAP_PEAK is None or capital > CAP_PEAK: CAP_PEAK = capital roi = ((capital - START_CAP) / START_CAP * 100) if START_CAP and capital else 0 dd = ((CAP_PEAK - capital) / CAP_PEAK * 100) if CAP_PEAK and capital < CAP_PEAK else 0 pc = PC.get(posture, DIM) sc = SC.get(mhs_st, DIM) tc = GREEN if trader_up else RED roi_c = GREEN if roi >= 0 else RED dd_c = RED if dd > 15 else (YELLOW if dd > 5 else GREEN) svc = mh.get("service_status", {}) hz_ks = mh.get("hz_key_status", {}) lines = [] lines.append(f"{BOLD}{CYAN}🐬 DOLPHIN-NAUTILUS{RST} {DIM}{now}{RST}") lines.append(f"{'─' * 60}") # TRADER lines.append(f"{BOLD}TRADER{RST} {tc}{'● LIVE' if trader_up else '● DOWN'}{RST}" f" phase:{phase} hb:{hb_age}") lines.append(f" vel_div:{vel_div:+.5f} scan:#{eng.get('last_scan_number', '?')}") lines.append("") # CAPITAL lines.append(f"{BOLD}CAPITAL{RST} {CYAN}${capital:,.2f}{RST}") lines.append(f" ROI: {roi_c}{roi:+.2f}%{RST} DD: {dd_c}{dd:.2f}%{RST}" f" start: ${START_CAP:,.0f}" if START_CAP else "") lines.append(f" trades:{trades} scans:{scans} bar:{eng.get('bar_idx', '?')}") lines.append(f" lev:{lev:.2f}x notional:${notional:,.0f}") # Open positions positions = eng.get("open_positions", []) if positions: lines.append(f" {BOLD}OPEN POSITIONS:{RST}") for p in positions: side_c = GREEN if p.get("side") == "LONG" else RED lines.append(f" {side_c}{p.get('asset','?')} {p.get('side','?')}{RST}" f" qty:{p.get('quantity',0):.4f}" f" entry:{p.get('entry_price',0):.2f}" f" pnl:{p.get('unrealized_pnl',0):+.2f}") else: lines.append(f" {DIM}no open positions{RST}") lines.append("") # POSTURE lines.append(f"{BOLD}POSTURE{RST} {pc}{posture}{RST} Rm:{pc}{_bar(rm, 20)}{RST} {rm:.4f}") cats = " ".join(f"C{i}:{float(bd.get(f'Cat{i}', 0)):.2f}" for i in range(1, 6)) lines.append(f" {cats}") lines.append(f" f_env:{float(bd.get('f_env', 0)):.3f} f_exe:{float(bd.get('f_exe', 0)):.3f}" f" boost:{boost:.2f}") lines.append("") # SYS HEALTH lines.append(f"{BOLD}SYS HEALTH{RST} {sc}{mhs_st}{RST} rm_meta:{rm_meta:.3f}") for m in ("m1_data_infra", "m1_trader", "m2_heartbeat", "m3_data_freshness", "m4_control_plane", "m5_coherence"): v = float(mh.get(m, 0)) c = GREEN if v >= 0.9 else (YELLOW if v >= 0.5 else RED) lines.append(f" {m}: {c}{v:.3f}{RST}") # Services lines.append(f" {DIM}services:{RST}") for name, st in sorted(svc.items()): dot = f"{GREEN}●{RST}" if st == "RUNNING" else f"{RED}●{RST}" lines.append(f" {dot} {name}") # HZ keys lines.append(f" {DIM}hz keys:{RST}") for name, info in sorted(hz_ks.items()): score = float(info.get("score", 0)) c = GREEN if score >= 0.9 else (YELLOW if score >= 0.5 else RED) lines.append(f" {c}●{RST} {name}: {info.get('status', '?')}") lines.append(f"\n{'─' * 60}") lines.append(f"{DIM}polling 5s • q to quit • {now}{RST}") return "\n".join(lines) def main(): print("Connecting to HZ...") hz = hazelcast.HazelcastClient( cluster_name="dolphin", cluster_members=["localhost:5701"], connection_timeout=5.0) print("Connected. Starting status display...\n") try: while True: try: out = render(hz) sys.stdout.write(CLEAR + out + "\n") sys.stdout.flush() except Exception as e: sys.stdout.write(f"\n{RED}Render error: {e}{RST}\n") sys.stdout.flush() time.sleep(5) except KeyboardInterrupt: print(f"\n{DIM}Bye.{RST}") finally: hz.shutdown() if __name__ == "__main__": main()