feat: Phase 2 — microstructure analytics + 81 tests
New microstructure/ module with pure-function analytics: microstructure/book.py: microprice() — depth-weighted mid price mid_price() — simple bid/ask midpoint order_book_imbalance() — ranged [-1, 1] volume skew depth_imbalance() — imbalance at fixed price distance spread_stats() — spread, spread_bps, mid, bid, ask depth_resiliency() — bid/ask volume within impact radius queue_depletion_prob() — Poisson fill probability at level batch_book_stats() — aggregate stats across snapshots microstructure/trades.py: classify_lee_ready() — Lee-Ready aggressor classification classify_bulk_lee_ready() — batch classification with mids/bids/asks compute_markouts() — forward mid-price change at configurable horizons markout_summary() — mean/std/t-stat per side per horizon trade_volume_profile() — size bucket distribution trade_arrival_rate() — rolling trades/sec with burst detection microstructure/toxicity.py: compute_vpin() — volume-synchronized informed trading probability compute_vpin_time_series() — rolling VPIN with alarm threshold fill_toxicity() — adverse price movement post-trade adverse_selection_ratio() — per-side adverse selection liquidation_clustering() — cluster detection in liquidation events microstructure/funding.py: funding_regime() — classify regime (neutral/positive/negative/high) funding_predictability() — AR(1) autocorrelation analysis funding_carry_pnl() — cumulative carry PnL estimation basis_spread() — perp premium over spot (bps) basis_convergence_speed() — mean-reversion half-life via AR(1) microstructure/signals.py: composite_signal() — weighted OBI + trade + VPIN + funding signal SignalPipeline — stateful pipeline accumulating book/trade updates detect_hft_regime() — regime classifier for HFT strategy selection Bug fixes in Phase 1: - data/latency.py: proper linear-interpolation percentiles - data/normalizer.py: UTC timezone for naive datetimes - data/normalizer.py: detect_sequence_gap returns gap-1 (missing count) - microstructure/toxicity.py: consistent vpin_value key in compute_vpin 81 tests across 4 test files (store, normalizer, latency, microstructure)
This commit is contained in:
+12
-4
@@ -80,11 +80,19 @@ class LatencyTracker:
|
||||
return {"p50": 0, "p90": 0, "p95": 0, "p99": 0, "count": 0}
|
||||
vals = sorted(v for _, v in buffer)
|
||||
n = len(vals)
|
||||
|
||||
def _pct(p: float) -> float:
|
||||
k = (n - 1) * p / 100
|
||||
lo = int(k)
|
||||
hi = min(lo + 1, n - 1)
|
||||
frac = k - lo
|
||||
return vals[lo] + frac * (vals[hi] - vals[lo])
|
||||
|
||||
return {
|
||||
"p50": round(vals[int(n * 0.50)], 2),
|
||||
"p90": round(vals[int(n * 0.90)], 2),
|
||||
"p95": round(vals[int(n * 0.95)], 2),
|
||||
"p99": round(vals[int(n * 0.99)], 2),
|
||||
"p50": round(_pct(50), 2),
|
||||
"p90": round(_pct(90), 2),
|
||||
"p95": round(_pct(95), 2),
|
||||
"p99": round(_pct(99), 2),
|
||||
"max": round(vals[-1], 2),
|
||||
"count": n,
|
||||
}
|
||||
|
||||
+3
-1
@@ -39,6 +39,8 @@ def normalize_timestamp(ts, source: str = "hl") -> int:
|
||||
return _parse_iso_ms(ts)
|
||||
|
||||
if isinstance(ts, datetime):
|
||||
if ts.tzinfo is None:
|
||||
ts = ts.replace(tzinfo=timezone.utc)
|
||||
return int(ts.timestamp() * 1000)
|
||||
|
||||
return int(time.time() * 1000)
|
||||
@@ -120,5 +122,5 @@ def detect_sequence_gap(
|
||||
if diff == 1:
|
||||
return 0
|
||||
if diff > 1:
|
||||
return min(diff, max_gap * 100) # cap reporting size
|
||||
return min(diff - 1, max_gap * 100)
|
||||
return -1 # duplicate or reset
|
||||
|
||||
Reference in New Issue
Block a user