Liquidity Mirage Detection: Cancel-Trade Divergence Slippage Playbook
Date: 2026-02-26
Category: Research (Execution / Slippage Modeling)
Scope: Intraday equity execution (KR-first, portable to other lit venues)
Why this model exists
Top-of-book depth can look healthy right before execution cost blows up.
The failure mode is a liquidity mirage:
- displayed size is large,
- queue appears fillable,
- but most of that liquidity disappears by cancellation before interaction.
If the router trusts displayed depth as if it were durable inventory, it over-allocates passive risk and pays late-stage slippage.
This playbook introduces a production-first detector for that failure mode and links it to live execution controls.
Core concept
Model displayed liquidity as two components:
- Durable liquidity: survives long enough to be meaningfully interactable.
- Ephemeral liquidity: frequently canceled/repriced before interaction.
Define latent mirage state:
[ M_t \in {\text{Normal}, \text{Watch}, \text{Mirage}} ]
The controller switches policy by mirage probability, not by naive visible size.
Signal stack
1) Cancel-Trade Divergence (CTD)
Within short rolling window (w):
- (C_t): canceled displayed volume,
- (X_t): executed volume at touch/near-touch,
- (A_t): newly added displayed volume.
Define:
[ CTD_t = \frac{C_t - \alpha X_t}{\epsilon + X_t + \beta A_t} ]
Interpretation:
- High positive CTD: displayed liquidity is being withdrawn faster than it is actually trading.
- Low/negative CTD: visible size is more conversion-friendly.
Bucket-normalize by symbol × time-of-day:
[ Z^{CTD}t = \frac{CTD_t - \mu{bucket}}{\sigma_{bucket}} ]
2) Queue Half-Life (QHL)
Track resting volume cohorts and estimate survival function (S(\tau)) under cancellations/executions.
Define queue half-life:
[ QHL_t = \inf{\tau : S(\tau) \le 0.5} ]
Very short QHL means the queue decays fast (ephemeral book).
Use robust transformed feature:
[ Z^{QHL}t = -\frac{\log(QHL_t) - \mu{\log QHL,bucket}}{\sigma_{\log QHL,bucket}} ]
(negative sign so higher = worse durability)
3) Refill Quality Ratio (RQR)
Not all replenishment helps. Distinguish refill that survives vs instantly cancels.
[ RQR_t = \frac{\text{added volume surviving }\ge \tau_s}{\epsilon + \text{total added volume}} ]
Low RQR + high CTD is a strong mirage signature.
4) Touch Stability Drift (TSD)
Measure how often best quotes mutate without meaningful trade conversion.
[ TSD_t = \frac{\text{touch updates without conversion}}{\epsilon + \text{total touch updates}} ]
This catches "visual churn" where quotes refresh but executable quality degrades.
Composite Mirage Score
[ MS_t = w_1 Z^{CTD}_t + w_2 Z^{QHL}t + w_3 (1-RQR_t) + w_4 TSD_t + w_5 \Delta s_t + w_6 \hat{\sigma}{short,t} ]
where:
- (\Delta s_t): spread widening speed,
- (\hat{\sigma}_{short,t}): short-horizon realized volatility proxy.
Do not hard-threshold (MS_t) directly. Feed it to probabilistic state modeling.
Modeling architecture
A) Fast state model (classification)
Train calibrated classifier for (M_t):
- gradient boosted trees (low latency, strong tabular performance),
- class weighting or focal loss for rare Mirage windows,
- calibration (isotonic / temperature scaling).
Output:
[ P_t = (P(Normal), P(Watch), P(Mirage)) ]
B) Tail-risk model (quantile)
Separately estimate conditional slippage quantiles for short horizons (e.g., 30s/60s/180s):
- q50, q90, q95,
- optional EVT fit for upper tail in stress buckets.
This model handles cost severity if Mirage is true.
C) Sticky transition filter
Use hysteresis / HMM smoothing to avoid mode flapping:
- enter Mirage when (P(Mirage)>0.60) for 2 consecutive windows,
- exit only when (P(Mirage)<0.38) for 3 windows.
Labeling design
Target future implementation shortfall over horizon (h):
[ Y_{t,h} = IS_{t\to t+h} ]
Regime labels can be built from forward outcomes + microstructure context:
- Normal: low forward slippage and normal fill conversion,
- Watch: deterioration signs, but no severe tail event,
- Mirage: top-tail forward slippage and conversion collapse despite displayed depth.
Use purged time splits to avoid leakage from overlapping windows.
Execution controller mapping
Let (B_t) be remaining slippage budget (bps).
Mode 1: Normal
- passive-first allowed,
- standard queue patience,
- normal participation ramp.
Mode 2: Watch
- shorter passive dwell time,
- stricter cancel/replace limits,
- reduced passive clip size,
- slower participation acceleration.
Mode 3: Mirage
- deprioritize rebate capture,
- enforce max quote lifetime,
- cap passive exposure at fragile levels,
- shift to controlled crossing when budget-breach probability rises,
- optional venue quarantine if mirage signature is venue-local.
Budget breach trigger example:
[ \Pr(\text{budget breach} \mid P_t, q95_t, remain_qty) > \theta_B \Rightarrow \text{defensive mode} ]
Production feature minimum
- Flow quality:
- CTD level + slope,
- cancel burst duration,
- cancel/add asymmetry.
- Queue durability:
- QHL (bid/ask),
- survival-curve slope,
- RQR.
- Conversion quality:
- touch-to-trade conversion,
- TSD,
- passive fill hazard.
- Coupling controls:
- spread drift,
- short volatility,
- imbalance acceleration,
- session/auction/VI guard variables.
Evaluation protocol
Offline
Primary objective:
- reduce q95 slippage vs baseline schedule/router.
Secondary:
- underfill rate,
- opportunity cost,
- mode switch stability,
- probability calibration error.
Use day-block bootstrap by liquidity cohorts.
Shadow to staged rollout
- Shadow decisions only (no capital impact).
- Small-capital rollout in liquid names.
- Expand universe with hard stop guardrails.
Hard stop examples:
- Mirage false-negative spike,
- mode flapping explosion,
- unexplained underfill drift above threshold.
Reliability & drift guards
- Feature drift monitoring (PSI/KS) for CTD, QHL, RQR.
- Calibration drift by session bucket.
- Latency SLO on feature freshness.
- Deterministic fallback when key features stale/missing.
Never run Mirage controller on stale queue-survival inputs.
Practical KR deployment notes
- Bucket by KRX session micro-regimes (open, midday lull, close approach).
- Exclude auction-cross artifacts from continuous-book windows unless explicitly modeled.
- Gate actions by VI/session state to avoid false mirage triggers near structural pauses.
- Keep KRX/NXT venue-local mirage diagnostics separate before cross-venue aggregation.
Pseudocode
for t in decision_ticks:
x = build_features(ctd, qhl, rqr, tsd, spread, vol, own_exec)
p = state_model.predict_proba(x) # Normal/Watch/Mirage
q95 = tail_model.predict(x, q=0.95)
state = sticky_filter.update(p)
breach = breach_prob(slippage_budget, q95, remain_qty, state)
if breach > THETA_B:
mode = "MIRAGE_DEFENSIVE"
else:
mode = policy_map(state)
action = execution_policy(mode, market_state, remain_qty)
send(action)
What this improves
If implemented well:
- fewer false comforts from displayed depth,
- earlier adaptation before spread/markout visibly deteriorate,
- lower tail slippage in cancellation-heavy windows,
- clearer post-trade diagnostics on why passive tactics failed.
Next experiments
- Cross-venue mirage transfer: does one venue’s mirage predict another’s shortly after?
- Conformal mirage probability bands for stronger online risk coverage.
- Metaorder interaction term: mirage sensitivity as function of own participation and slicing cadence.
- Joint optimization of slippage tail + underfill with explicit constraints.
One-line takeaway
Displayed depth is not liquidity; it is a hypothesis. Mirage detection tests that hypothesis before your slippage budget pays the tuition.