#!/usr/bin/env python3 """ DOLPHIN Paper Trading Monitor ============================== Simple status display for the paper trading system. """ import os import sys import json import time from pathlib import Path from datetime import datetime sys.path.insert(0, '/mnt/dolphinng5_predict') sys.path.insert(0, '/mnt/dolphinng5_predict/nautilus_dolphin') import hazelcast def get_latest_arrow_info(): """Get latest scan info directly from Arrow files.""" arrow_dir = Path('/mnt/ng6_data/arrow_scans') / datetime.now().strftime('%Y-%m-%d') latest_file = None latest_mtime = 0 try: with os.scandir(arrow_dir) as it: for entry in it: if entry.name.endswith('.arrow') and entry.is_file(): mtime = entry.stat().st_mtime if mtime > latest_mtime: latest_mtime = mtime latest_file = entry.path except FileNotFoundError: return None if not latest_file: return None # Read scan info import pyarrow as pa import pyarrow.ipc as ipc with pa.memory_map(latest_file, 'r') as source: table = ipc.open_file(source).read_all() return { 'scan_number': table.column('scan_number')[0].as_py(), 'timestamp_iso': table.column('timestamp_iso')[0].as_py(), 'assets': len(json.loads(table.column('assets_json')[0].as_py())), 'instability': table.column('instability_composite')[0].as_py(), 'age_sec': time.time() - latest_mtime, 'file': os.path.basename(latest_file) } def get_hz_info(client): """Get Hazelcast scan info.""" features_map = client.get_map('DOLPHIN_FEATURES').blocking() val = features_map.get('latest_eigen_scan') if not val: return None data = json.loads(val) mtime = data.get('file_mtime', 0) return { 'scan_number': data.get('scan_number'), 'assets': len(data.get('assets', [])), 'prices': len(data.get('prices', [])), 'instability': data.get('instability_composite'), 'age_sec': time.time() - mtime if mtime else None, 'bridge_ts': data.get('bridge_ts', 'N/A')[:19] if data.get('bridge_ts') else 'N/A' } def main(): print("=" * 70) print("🐬 DOLPHIN PAPER TRADING MONITOR") print("=" * 70) # Arrow file status arrow_info = get_latest_arrow_info() if arrow_info: print(f"\nšŸ“ ARROW FILES:") print(f" Latest: #{arrow_info['scan_number']} ({arrow_info['file']})") print(f" Assets: {arrow_info['assets']} | Instability: {arrow_info['instability']:.4f}") print(f" Age: {arrow_info['age_sec']:.1f}s") else: print("\nšŸ“ ARROW FILES: Not found") # Hazelcast status try: client = hazelcast.HazelcastClient( cluster_name="dolphin", cluster_members=["localhost:5701"], ) hz_info = get_hz_info(client) if hz_info: print(f"\n⚔ HAZELCAST (DOLPHIN_FEATURES):") print(f" Scan: #{hz_info['scan_number']} | Assets: {hz_info['assets']} | Prices: {hz_info['prices']}") print(f" Instability: {hz_info['instability']:.4f}") print(f" File Age: {hz_info['age_sec']:.1f}s | Bridged: {hz_info['bridge_ts']}") # Check if bridge is current if arrow_info and hz_info['scan_number'] == arrow_info['scan_number']: print(f" āœ“ Bridge SYNCED") else: print(f" ⚠ Bridge LAGGING (Arrow: #{arrow_info['scan_number']}, Hz: #{hz_info['scan_number']})") else: print(f"\n⚔ HAZELCAST: No latest_eigen_scan found!") client.shutdown() except Exception as e: print(f"\n⚔ HAZELCAST: Connection failed - {e}") print("\n" + "=" * 70) if __name__ == "__main__": main()