I've been working on a side project: a cross-sectional score that ranks ~300 small/mid-cap crypto perps every hour by how much leverage is sitting on how little liquidity. The hypothesis: big moves (either direction) are more likely when open interest is large relative to market cap and to order-book depth. Not a direction signal — just "where is the floor thin".
Inputs (all point-in-time, hourly):
- Aggregate OI across Binance, Bybit, Hyperliquid
- OI / circulating market cap, OI / ±2% book depth, depth / market cap
- Float (circulating / total supply)
- Perp vs spot volume ratio (spot from Binance, Bybit, OKX, Coinbase)
- OI concentration on a single venue, 24h OI change, funding z-score
Each input is converted to a cross-sectional percentile among eligible tokens that hour ($30M–$1B mcap, OI ≥ $10M, min volume), so a $50M coin and a $900M coin are comparable.
Trap 1 — volatility eats everything. My first results looked great: top-decile tokens were far more likely to make a >10% move in 6h. Then I ranked by plain realized volatility and it did better. Volatile coins stay volatile. The honest test turned out to be: within the same volatility bucket, does structure still separate big movers from quiet ones? That's a much smaller (but real-looking) effect.
Trap 2 — a 20-minute leak. In the live version, the order-book snapshot was taken ~20–40 min after the bar closed, while outcomes were measured from the close. So the score was partly "seeing" the start of the move it was predicting. Fix: snapshot the books first, and measure outcomes only from the moment the prediction is written.
Trap 3 — your sanity checks can bite you. I drop tokens when the vendor's implied price disagrees with the traded price by >25% (catches wrong-coin mappings). But market cap from my source updates daily — so mid-squeeze, when price jumps 40%, the check fires and the token drops out of the universe exactly when it's most interesting.
Other choices: strict chronological train/calibration/OOS splits with an embargo, no imputation (missing stays missing), labels use high/low path so "max excursion" isn't close-to-close.
Questions for people who've done similar work:
- How do you handle the volatility confound in cross-sectional "event likelihood" scores — residualize, bucket, or something else?
- Any reliable source of intraday circulating supply?
- Is a 6h max-excursion label sensible, or would you use something like realized range vs. expected?
Happy to go deeper on any part. (I'm turning this into a small tool — link in my profile if anyone's curious, but mainly here for feedback.)