# Cross-Sectional Crypto Funding-Dispersion Strategy — Design

**Status:** design approved 2026-06-18 (brainstorm). Data-feasibility spike PASSED (verdict A).

## Why
Our two real crypto edges (XS momentum, funding carry) live in the less-efficient crypto market. The *existing* `funding` track is a **time-series** carry book (hold every liquid coin whose trailing-30d funding clears a 5 bp/day hurdle). This strategy targets the **cross-sectional dispersion** instead: rank coins by funding *relative to peers*, long the richest-carry / short the poorest. It hedges out the "all funding moves together" common factor (more market-neutral) and lives in the **illiquid tail** that large funds are structurally locked out of — a genuine small-capital edge. Institutions crowd the BTC/ETH basis (now ETF-ified, decayed); the tail dispersion is comparatively open. Target: a modest (0.5–1.0), uncorrelated, capacity-limited edge that *adds to the book-of-books* — not a standalone money-printer.

## Data (feasibility-confirmed, on disk, survivorship-free)
- **Source:** `foxhunt/data/surfer/crypto_pit/*.npz` — 180 Binance USDT-perp symbols, each with `day` (epoch-day), `close`, `qvol` (daily USD quote-volume), `funding` (daily-summed 8h funding rate). Span 2019-09 → 2026-06. **Survivorship-free**: includes 25 delisted coins (LUNA/FTT/SRM/…), funding present right up to each delisting.
- fxhnt reads it through a **configurable path** (`FXHNT_CRYPTO_PIT_DIR`, default the foxhunt path for local runs). A thin `CryptoPitPanelSource` adapter loads the npz set into an in-memory panel (`{symbol: {epoch_day: (close, qvol, funding)}}`); `.npz` loaded WITHOUT `allow_pickle` (numeric arrays only).
- **Cadence is DAILY** (the panel's funding is daily-summed; 8h is not in this panel — out of scope).
- **Documented caveats:** (1) the delisted-ticker roster is the 35 hard-coded famous blow-ups in `fetch_crypto_pit.py` — survivorship-free for those, but not an exhaustive dead-coin census (future hardening via `data.binance.vision` monthly archives; noted, not in scope). (2) No separate mark-vs-spot basis column — `close` provides returns; the funding rate itself is the carry signal, so this suffices.

## Architecture (mirrors the proven B3b pattern: pure domain + PIT runner + gauntlet)
### Domain (pure, no I/O) — `domain/strategies/cross_sectional_funding.py`
- `funding_scores(panel_asof) -> {symbol: score}`: cross-sectional signal at date D from data ≤ D — a blend of **funding z-score across the eligible peers** (robust z, median/MAD) + **funding momentum** (recent trailing funding vs longer trailing). Blending avoids stale-level bias (a coin that paid in the past but not now ranks lower).
- `construction_weights(scores, mode, quantile=0.2) -> {symbol: weight}` for **three modes (all tested)**:
  - `long_tilt` — long-carry only: top-quantile by score, positive weights summing to 1 (short perp + long spot — executable at any size, no borrow).
  - `market_neutral` — top-quantile long + bottom-quantile short, weights sum to 0 (the short leg = long perp + short spot, needs coin-borrow; modelled in backtest, borrow-gated live).
  - `executable` — long side full + short side ONLY where borrow is plausible (majors); the realistically-deployable subset.
- `book_return(prev_weights, funding_today, new_weights, cost)`: delta-neutral carry — realized = Σ wᵢ·fundingᵢ (signed: long collects +funding, short collects −funding) − turnover·cost. Generalizes the existing `funding_carry.book_return` to signed cross-sectional weights.

### PIT universe — `domain/cross_sectional_funding` (pure)
- `eligible_asof(panel, asof, *, min_qvol, min_history)`: coins ALIVE at D (have bars in a trailing window ending D) with trailing dollar-volume ≥ `min_qvol` (the liquidity floor) and enough history to score. Price/volume presence = the tradeability signal (PIT, no membership table needed). No future data.

### Application — `application/funding_backtest_runner.py`
- Walk-forward: for each daily rebalance D → `eligible_asof` (PIT) → `funding_scores` (≤ D) → for each mode, `construction_weights` → hold to D+1 → accrue `book_return` (funding carry − cost) → per-(mode × floor) daily return series.
- **The output is a verdict matrix:** `{long_tilt, market_neutral, executable} × {$1M, $5M, $20M floor}` (deep-tail target = $1M; the sweep shows where the edge lives vs where it's uninvestable).
- `evaluate_funding_constructions(...)` → `compute_stats` + IS/OOS split + gauntlet `evaluate` per cell. **`n_trials` = number of matrix cells tested** (multiple-testing correction — we ARE testing several variants, so DSR must deflate for it).

### Cost model (the crux — deep tail = thin coins)
- Per-rebalance turnover × round-trip cost, where cost = taker fee (both perp + spot legs) **+ liquidity-scaled slippage** (slippage rises as a coin's `qvol` falls — the tail pays more). Parameterised; the backtest sweeps a conservative cost so we see the edge net of realistic tail friction. The primary way this edge dies is costs eating it on tiny coins — the model must be brutal and the result reported net.

### Pre-registered kill criteria (decide before looking)
A matrix cell is KILLED if any: net **DSR < 0.5**; OR the edge concentrates only in sub-$1M-ADV names (uninvestable even for us); OR **correlation > 0.6** to the existing `funding` track and/or crypto momentum (not a real diversifier). Surviving cell(s) → paper-forward.

### Paper-forward + cockpit
- The winning **executable** construction becomes a `ForwardStrategy` cockpit track (new registry entry `xsfunding`), gate=WAIT until forward data confirms, with its backtest verdict surfaced via the `backtest_summary` table we already wired.

## Reuse
`crypto_pit` npz (existing data), the gauntlet (`compute_stats`/`evaluate`), the B3b PIT-runner + `evaluate_constructions` pattern, `robust_z` (from `equity_factor`), `ForwardTracker` + cockpit `backtest_summary` surface. New: the npz panel adapter, the cross-sectional-funding domain, the funding backtest runner, a CLI `backtest-funding`.

## Testing (same discipline as B3b — no live network)
- Synthetic in-memory panel (a few coins incl. one that "delists" mid-history, one always-illiquid, one high-dispersion) for all unit/integration tests.
- **The decisive PIT test:** a coin whose funding is low early / high late is NOT long-ranked early (no look-ahead).
- Cost-sensitivity test (edge must survive a realistic tail-slippage cost). Gauntlet on a known return series. Determinism.

## Out of scope
- Live execution / order routing (paper-forward only).
- 8h-cadence backtest (panel is daily-summed).
- Exhaustive delisted-coin census (documented caveat; future `data.binance.vision` hardening).
- Mark-vs-spot basis modelling (funding signal + close suffice).
- Colocation (not needed for daily carry; available later if ever warranted).

## Honest expectation
A modest, capacity-limited, uncorrelated carry edge in the tail — or a clean falsification if costs eat it. Either outcome is a win: a new diversifier for the book, or days (not months) spent proving it isn't one. The answer is weeks (backtest now → paper-forward), not years.
