Bayesian State-Space Slippage Nowcasting Playbook
Date: 2026-02-25
Category: research (quant execution)
TL;DR
If your slippage model is calibrated once per day, it is already stale by lunchtime.
Use a Bayesian state-space model to continuously nowcast slippage distribution (not just mean), then drive a risk-aware participation controller that adapts speed and aggressiveness in real time.
1) Problem Framing
Real execution costs drift intraday because:
- order-flow toxicity changes (markout regime shifts)
- queue resilience breaks during cancel bursts
- volatility/liquidity relationship is non-stationary
- same participation rate can have very different impact by regime
A static model gives false confidence. In production, we need:
- Online-updating coefficients
- Uncertainty-aware forecasts (p50/p90/p95)
- Guardrails for tail-cost events
2) Model Structure
Model short-horizon slippage (bps) for child order (t):
[ y_t = x_t^\top \beta_t + \epsilon_t, \quad \epsilon_t \sim t_\nu(0, \sigma_t^2) ]
Time-varying coefficients:
[ \beta_t = \beta_{t-1} + \eta_t, \quad \eta_t \sim \mathcal{N}(0, Q) ]
Where:
- (y_t): realized shortfall in bps (benchmark: arrival/VWAP/decision)
- (x_t): feature vector from market + order state
- (\beta_t): latent regime-aware sensitivities
- Student-t noise absorbs fat tails better than Gaussian
Feature blocks (practical)
- Urgency / participation: POV, remaining notional ratio, time-to-close
- Microstructure: spread, top-of-book depth, queue imbalance, cancel burst intensity
- Flow toxicity: short-horizon markout, signed trade imbalance, VPIN-like proxy
- Volatility regime: realized vol, jump flag, auction proximity
- Interaction terms: POV×vol, POV×imbalance, spread×depth
3) Hierarchical Priors (for sparse symbols)
For thinly traded names, borrow strength via hierarchical shrinkage:
[ \beta_{i,t} \sim \mathcal{N}(\mu_{g(i),t}, \Sigma_{g(i)}), ]
- (i): symbol
- (g(i)): group (sector, ADV bucket, tick-size bucket)
This stabilizes estimates early in session and reduces overreaction from tiny sample windows.
4) Online Update Loop
At each fill / micro-batch (e.g., every 5–15s):
- Ingest latest features and realized fill outcomes
- Predict posterior slippage distribution for next action
- Update posterior ((\beta_t, \Sigma_t)) with Bayesian filter step
- Recompute decision thresholds (p90/p95 and tail budget usage)
Use forgetting or adaptive process noise (Q):
- low turbulence → smaller (Q) (stable coefficients)
- turbulence spike → larger (Q) (faster adaptation)
5) Decision Policy (cost + risk)
Select participation/aggressiveness action (a_t) by minimizing:
[ \min_{a_t} ; \mathbb{E}[C_t(a_t)] + \lambda \cdot \mathrm{Var}(C_t(a_t)) + \gamma \cdot \text{AlphaDecayPenalty}(a_t) ]
Subject to tail constraint:
[ \Pr(C_t(a_t) > B_t) \le \delta_t ]
Where:
- (B_t): dynamic tail budget slice (remaining risk budget)
- (\delta_t): acceptable breach probability (tighten near close/news)
Action knobs
- POV target (e.g., 6% → 12% under urgency)
- limit vs marketable ratio
- slice interval / child size
- venue routing aggressiveness
6) Guardrails for Live Trading
Minimum production controls:
- Data freshness gate: stale book/quote → safe fallback mode
- Tail breach gate: if p95 exceeds threshold N times, reduce POV / pause strategy
- Drift monitor: posterior residual CUSUM triggers regime reset
- Hard risk rails: max order size, max participation, max spread-cross count
- Kill-switch ladder: auto downgrade before full stop
7) Vellab + KIS Integration Blueprint
Services
feature-stream: computes microstructure + toxicity features from market/feedslippage-nowcaster: maintains posterior state per symbol/strategyexecution-policy: converts posterior forecasts to action knobsrisk-sentinel: enforces tail-budget + hard pre-trade checks
Storage
- Posterior snapshots (R2 / object store): periodic checkpoints for restart safety
- Event log (D1/warehouse): fills, features, decisions, risk events for replay
Operational cadence
- Warm-start priors from recent rolling window (last 5–20 sessions)
- In-session online update at fixed cadence + event-driven updates on fills
- Post-close batch recalibration and parameter drift report
8) Evaluation Protocol
Do not evaluate only by average slippage.
Track:
- Mean / median slippage
- p90 / p95 / p99 slippage
- Tail breach frequency vs target (\delta)
- Opportunity cost (missed fills) vs impact saved
- Regime-change recovery time (how fast controller stabilizes)
A/B test against baseline static model with identical risk rails.
9) Implementation Skeleton (pseudo)
state = load_prior(symbol)
for t in stream(child_order_events):
x = build_features(t)
pred = posterior_predict(state, x) # mean + quantiles
action = solve_policy(
pred_dist=pred,
alpha_decay=t.alpha_decay,
tail_budget=t.tail_budget,
constraints=risk_limits
)
send_order(action)
if t.has_realized_fill:
y = realized_slippage(t)
state = bayes_update(state, x, y, adaptive_Q=t.regime_score)
if breach_or_drift(state, pred, t):
action = safe_mode(action)
10) Common Failure Modes
- Overfitting turbulence: too large (Q) all day → noisy control
- Underreacting regime shifts: too small (Q) during news/open/close
- Metric myopia: optimizing mean while p95 explodes
- No fallback path: model outage forces manual firefighting
11) Practical Rollout Plan (2 weeks)
- Week 1: shadow mode nowcasting + risk telemetry only (no execution control)
- Week 2: limited notional pilot with strict tail caps and automatic downgrade
- Expand universe only if p95 + breach KPIs beat baseline consistently
References (starting points)
- Almgren, R. & Chriss, N. (2000), Optimal Execution of Portfolio Transactions.
- Huang, W., Lehalle, C.-A., Rosenbaum, M. (2015), Queue-Reactive Model.
- Taranto, D. et al. (2018), Linear models for order flow impact (propagator family).
The practical edge is not one “perfect model”; it is the closed loop: forecast distribution → risk-aware action → online update → guardrail enforcement.