Per-symbol calibration shipped
Until this date every symbol ran on BTC/ETH-fit thresholds. After the sweep each of the remaining eighteen gets its own thresholds, lifting balanced F1 by 2–6 points for alts (LINK highest at 0.45).
Exactly how the regime label for a given symbol is computed. If anything on this page becomes wrong, it's a bug — tell us.
For each (symbol, timeframe):
rt = ln(closet / closet-1).RVt = stdev(rt-29..t) × √(bars_per_year). Bars-per-year at the bar interval — annualized for comparability across timeframes.μt and σt over the last 240 values of RV.zt = (RVt − μt) / σt.Three states — low, normal, high. Starts in normal. Transitions require enter_k consecutive observations past the threshold; exits require exit_k observations back inside. Hysteresis prevents single-bar wicks from flipping the state.
normal → high when z ≥ high_enter for enter_k bars normal → low when z ≤ low_enter for enter_k bars high → normal when z ≤ high_exit for exit_k bars low → normal when z ≥ low_exit for exit_k bars
Per symbol, per timeframe, we grid-sweep 2,304 (high_enter, high_exit, low_enter, low_exit, enter_k, exit_k) combinations against 180 days of 1m klines, using a smoothed-percentile ground truth (top/bottom 10% of forward-window RV). For each combination we compute macro-F1 across the three classes and the mean alerts-per-day. The three named presets (conservative, balanced, aggressive) are picks on the Pareto front of (F1, alerts/day).
Per-symbol presets are stored at data/calibration/{symbol}/presets.json and loaded by the service at boot. Nightly CI reruns the sweep and opens a PR if F1 moved more than 0.001 on any preset — see changelog.
Alongside the close-to-close RV that drives the FSM, each /v1/regime/{symbol} response includes two intraday-efficient estimators computed over the same 30-bar window:
parkinson_vol — √( Σ ln(H/L)² / (4 N ln 2) ), annualized. Uses the full bar range; 5× more statistically efficient than close-to-close but assumes no drift inside the bar.yang_zhang_vol — Yang & Zhang (2000): combines overnight variance, open-to-close variance, and Rogers-Satchell. Robust to both drift and open/close gaps.These are informational — useful for anyone who wants to sanity-check the RV signal or build their own thresholds off a more efficient estimator. The FSM deliberately stays on close-to-close because it's the broadly understood benchmark and every venue we read reports it cleanly. Values come through as null when the bar source (e.g. Coinbase fallback) didn't provide OHLC.
A second engine polls Binance, Coinbase and Bybit independently, computes a stateless (no FSM hysteresis) regime label per venue, and reports the majority. When the three agree you're seeing structural vol; when they diverge, one venue has a book anomaly.
aggressive (or your own /regime/{sym}/custom call).Until this date every symbol ran on BTC/ETH-fit thresholds. After the sweep each of the remaining eighteen gets its own thresholds, lifting balanced F1 by 2–6 points for alts (LINK highest at 0.45).
Shares the same thresholds as the shorter timeframes for now. Per-tf calibration is on the list; the scale-free z framing makes the shared values reasonable in the meantime.
Added Coinbase and Bybit to the poller. Stateless classification only — hysteresis would require tracking FSM state per venue, which is on the list.
BTC/ETH swept over 180 days, three Pareto-front presets published. F1 0.37 / 0.39 / 0.41 at conservative / balanced / aggressive.