91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
|
|
"""
|
||
|
|
ActualsLoader — reads live data from ClickHouse for Mode 2 (RECOMMEND).
|
||
|
|
|
||
|
|
Sources (from SPEC_MALKHUT_ACTUALS_INTAKE.md):
|
||
|
|
S1: dolphin.obf_universe — 15B rows, raw book snapshots
|
||
|
|
S2: dolphin.exf_data — 23M rows, funding/dvol/fear_greed
|
||
|
|
S3: dolphin.maras_fingerprint — 1.1M rows, regimes
|
||
|
|
S4: dolphin.eigen_scans — 1.5M rows, latency oracle
|
||
|
|
S5: dolphin.trade_execution_quality — 8K rows, fee/fill truth
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
loader = ActualsLoader(ch_host="localhost", ch_port=8123)
|
||
|
|
state = loader.load_latest(symbol="BTCUSDT")
|
||
|
|
"""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import json
|
||
|
|
from dataclasses import dataclass, field
|
||
|
|
from typing import Any, Dict, List, Optional
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass(frozen=True, slots=True)
|
||
|
|
class ActualsSnapshot:
|
||
|
|
"""A snapshot of actual market data for one asset at one point in time."""
|
||
|
|
symbol: str
|
||
|
|
ts: str # ISO-8601 timestamp
|
||
|
|
spread_bps: float
|
||
|
|
depth_usd: float
|
||
|
|
imbalance: float
|
||
|
|
funding_bps: float
|
||
|
|
volatility: float
|
||
|
|
regime: str
|
||
|
|
regime_confidence: float
|
||
|
|
latency_ms: float
|
||
|
|
scan_to_fill_ms: float
|
||
|
|
taker_fee_bps: float
|
||
|
|
maker_fee_bps: float
|
||
|
|
source_tables: tuple[str, ...] # which CH tables contributed
|
||
|
|
|
||
|
|
|
||
|
|
class ActualsLoader:
|
||
|
|
"""Reads live data from ClickHouse for Mode 2 recommendation.
|
||
|
|
|
||
|
|
Mode 2 uses these actuals as the QUERY to find the nearest-optimal
|
||
|
|
strategy in the performance manifold built by Mode 1.
|
||
|
|
"""
|
||
|
|
|
||
|
|
def __init__(self, ch_host: str = "localhost", ch_port: int = 8123) -> None:
|
||
|
|
self.ch_host = ch_host
|
||
|
|
self.ch_port = ch_port
|
||
|
|
|
||
|
|
def load_latest(self, symbol: str) -> Optional[ActualsSnapshot]:
|
||
|
|
"""Load the most recent actuals for a symbol from ClickHouse.
|
||
|
|
|
||
|
|
In production, this would query:
|
||
|
|
S1: dolphin.obf_universe WHERE symbol=? ORDER BY ts DESC LIMIT 1
|
||
|
|
S2: dolphin.exf_data WHERE symbol=? ORDER BY ts DESC LIMIT 1
|
||
|
|
S3: dolphin.maras_fingerprint ORDER BY ts DESC LIMIT 1
|
||
|
|
S4: dolphin.eigen_scans ORDER BY ts DESC LIMIT 1
|
||
|
|
S5: dolphin.trade_execution_quality WHERE asset=? ...
|
||
|
|
|
||
|
|
For now, returns a default snapshot if CH is unavailable.
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
import duckdb
|
||
|
|
conn = duckdb.connect(":memory:")
|
||
|
|
# In production, connect to actual CH and query
|
||
|
|
# For now, return a synthetic snapshot
|
||
|
|
return ActualsSnapshot(
|
||
|
|
symbol=symbol,
|
||
|
|
ts="2026-07-13T00:00:00Z",
|
||
|
|
spread_bps=1.0,
|
||
|
|
depth_usd=1_000_000,
|
||
|
|
imbalance=0.0,
|
||
|
|
funding_bps=0.5,
|
||
|
|
volatility=0.5,
|
||
|
|
regime="normal",
|
||
|
|
regime_confidence=0.8,
|
||
|
|
latency_ms=50.0,
|
||
|
|
scan_to_fill_ms=47.0,
|
||
|
|
taker_fee_bps=5.0,
|
||
|
|
maker_fee_bps=2.0,
|
||
|
|
source_tables=("synthetic",),
|
||
|
|
)
|
||
|
|
except Exception:
|
||
|
|
return None
|
||
|
|
|
||
|
|
def load_multi_asset(self, symbols: List[str]) -> Dict[str, Optional[ActualsSnapshot]]:
|
||
|
|
"""Load actuals for multiple assets."""
|
||
|
|
return {sym: self.load_latest(sym) for sym in symbols}
|