research: fip breadth diagnostics + compositional read

Add lagged/tier/prod-subset/mom-conditional checks on research.sqlite.
Log: unconditional sign is a winner/bleeder tug-of-war; mom-conditional
fip stays negative and reliable; warn on high-vol tilt if universe broadens.
This commit is contained in:
2026-07-18 21:40:05 +02:00
parent d34c7a21b7
commit ceaaadc49f
5 changed files with 995 additions and 25 deletions
+128 -23
View File
@@ -1,46 +1,151 @@
# Broad-universe fip_id IC research (Phase B)
Generated: 2026-07-18T21:14:40.170961
**Status:** research complete enough for a platform decision on *unconditional* fip.
**Production impact:** none. Display card remains context-only.
Generated: 2026-07-18 (breadth run + diagnostics same day).
## Scope
- **Research only** — production universe, gate, scanner, schedule unchanged.
- Price-only signal harness; no sentiment/fundamentals on the broad tier.
- Point-in-time liquidity mask: top **1500** by 63d median $vol, price ≥ **$5.0** at as-of.
- Snapshot: `research.sqlite` — ~4,650 tickers (prod + nasdaq_all extend).
- IC mask: top **1,500** by point-in-time 63d median $vol, price ≥ **$5**, per week.
## Caveats
- **Survivorship bias**: today's constituents backfilled historically (worse in small caps).
- **IEX volume undercount**: relative $vol rank only, not absolute floors.
- **Pool skew**: nasdaq_all sp500 tilts tech/biotech; missing pure NYSE mid-caps.
- **Survivorship bias** today's constituents, history backfilled (worse in small caps).
- **IEX volume undercount** relative $vol rank only, not absolute floors.
- **Pool skew** nasdaq_all partial SPX seed tilts tech/biotech; missing pure NYSE mid-caps.
- **Do not** compare full multi-signal tables across universe baselines; only compare `fip_id` to its 505-name fingerprint.
---
## Fingerprint (505-name prod snapshot)
- Expected: IC ≈ -0.045, t ≈ -2.9
- Observed: IC = -0.045, t = -2.91, weeks = 35, reliable = True
- Pass: **True**
| | Expected | Observed |
|---|---:|---:|
| mean IC | 0.045 | **0.045** |
| t-stat | 2.9 | **2.91** |
| weeks | ≥12 | 35 |
| avg N | ~500 | 497.7 |
| reliable | true | **true** |
## Liquid-breadth signal_eval (fip_id)
**Pass.** Pipeline and formula are trustworthy.
Artifacts: `reports/fip-breadth-20260718-211440-fingerprint.json`
---
## First breadth harness run (pre-registered iron rule)
Unconditional `fip_id` on liquid top-1500 (runner `run_fip_breadth_research.py`):
| metric | value |
|---|---|
| mean_ic | 0.0575 |
| ic_t_stat | 5.12 |
| ic_positive_pct | 88.6 |
|---|---:|
| mean_ic | **+0.0575** |
| ic_t_stat | **+5.12** |
| ic_positive_pct | 88.6% |
| weeks | 35 |
| avg_cross_section | 1471.2 |
| reliable | True |
| mean_quintile_spread | 0.0199 |
| reliable | true |
## Verdict (iron rule)
**Iron rule as written (need negative sign):** **not green.**
Honest call: no production change from that screen alone.
- **Green: False**
- iron rule not met on liquid-breadth cross-section
- Checks: `{"mean_ic": 0.0575, "abs_mean_ic_ge_0_03": true, "sign_negative": false, "ic_t_stat": 5.12, "reliable": true, "weeks": 35, "avg_cross_section": 1471.2}`
Artifact: `reports/fip-breadth-20260718-211440-breadth.json`
A green verdict authorizes a **follow-up proposal** only (two-tier universe / gate revalidation) — **not** production wire-in.
---
## Artifacts
## Why “+IC on Nasdaq” is not a jumpiness-premium story
- Fingerprint report: `reports/fip-breadth-20260718-211440-fingerprint.json`
- Breadth report: `reports/fip-breadth-20260718-211440-breadth.json`
`fip_id = sign(PRET) × (%neg %pos)` **pools two opposite continuous populations:**
| Leg | Formation | Continuation intuition | IC contribution |
|---|---|---|---|
| **Continuous winners** | PRET>0, mostly up days (smooth climbers) | Paper: keep going up | **negative** |
| **Continuous losers / bleeders** | PRET<0, mostly down days (grind-down biotechs, SPACs, etc.) | Momentum: keep going down | **positive** |
Unconditional IC is a **tug-of-war weighted by universe composition**:
- **S&P-like book** ≈ few steady bleeders → winner leg dominates → IC **0.045**.
- **Liquid Nasdaq pool** ≈ many bleeders / junk-lottery names → loser leg can flip the **aggregate** sign **without contradicting Da/Gurun/Warachka**, whose claim was always **momentum-conditional** (ID modulates continuation *among winners*), not an unconditional sort.
First-run context rows (same breadth harness) fit that reading: strong **vol_6m** underperformance and **high_52w** effects flag a large junk segment — exactly the population that can flip unconditional fip.
**Do not write “on Nasdaq, jumpy paths outperform” into the log as a collectible premium** until the diagnostics below are read.
---
## Follow-up diagnostics (same snapshot, independent panel)
Script: `scripts/run_fip_breadth_diagnostics.py`
Artifact: `reports/fip-breadth-diagnostics-20260718-213908.json`
| check | mean_ic | t | weeks | avg N | reliable |
|---|---:|---:|---:|---:|---|
| fip same-week liquid 1500 (panel) | 0.017 | 1.85 | 35 | 1471 | true |
| fip **lagged membership** (prior-week $vol) | 0.010 | 0.93 | 35 | 1471 | true |
| fip **tier 1800** (senior liquid) | **0.035** | **2.99** | 35 | 791 | true |
| fip **tier 8011500** (junior liquid) | **+0.014** | +1.25 | 35 | 700 | true |
| fip **prod-universe subset** inside liquid | **0.044** | **2.88** | 35 | 498 | true |
| fip **mom-conditional** (top 20% mom_12_1) | **0.088** | **4.58** | 35 | 294 | true |
| vol_6m liquid 1500 (panel) | 0.047 | 1.3 | 35 | 1471 | true |
| mom_12_1 liquid 1500 | +0.046 | +1.91 | 35 | 1471 | true |
| mom_12_1_resid liquid 1500 | +0.029 | +1.33 | 35 | 1471 | true |
### What the checks settle
1. **Lagged membership** — same sign as same-week panel (mildly negative); does **not** recreate a large positive IC. Not a clean “liquidity explosion leak manufactures +0.06” story for the panel path. (The first harness runs **+0.0575** still does not match the independent panels 0.017 — treat the **+0.0575 as a contested unconditional figure**; do not build a premium narrative on it.)
2. **Tier split** — senior liquid **negative** and reliable; junior liquid **mildly positive** / weak. Bias and bleeder weight are stronger in the junior tier.
3. **Prod-universe subset** — IC **0.044 / t 2.88**, ~498 names/week — matches the fingerprint. **Sign flip is compositional**, not “the whole market regime flipped.”
4. **Momentum-conditional fip (the platform test)** — IC **0.088 / t 4.58**, reliable, ~294 winners/week. **Negative sign, |IC| ≳ 0.03.** This is the papers claim and the only version a gate could consume.
### Platform verdict
| Question | Answer |
|---|---|
| Unconditional fip iron rule (negative on liquid-1500) | **Not green** (first harness +0.06 fails sign; panel mild neg fails magnitude) |
| Production change now? | **No** |
| Is fip “dead forever”? | **No****alive only as a momentum-conditional tilt candidate** on breadth |
| Next real step if pursued | Book-level experiment: among qualified residual-momentum names, tilt/filter by lower fip — **not** an unconditional fip sort |
| Display card | Stays; still the right home until a book test wins |
---
## Buried headline: vol tilt / residual mom on breadth
Even with panel vs harness magnitude differences, the **direction** is clear:
- **High vol underperforms** on this pool relative to a clean S&P-like book.
- Production rank tilts **20% toward high volatility**, validated on S&P-like names where high-vol ≈ high-beta in a bull tape. On broad Nasdaq liquid, high-vol often means **lottery junk**.
- **If the universe ever broadens in production, re-validate the 80/20 high-vol tilt first** — it can flip from mildly helpful to actively harmful.
- **Raw momentum > residual** on breadth (panel and first harness both show this pattern) — SPY residualization is a noisier fit for small caps; a breadth book may want a different benchmark or raw mom.
---
## How to re-run (research branch only)
```powershell
# Windows
.\.venv\Scripts\python.exe scripts\run_fip_breadth_diagnostics.py `
--research-snapshot backtest_snapshots\research.sqlite `
--prod-snapshot backtest_snapshots\prod.sqlite `
--workers 6
```
```bash
# macOS
python scripts/run_fip_breadth_diagnostics.py \
--research-snapshot backtest_snapshots/research.sqlite \
--prod-snapshot backtest_snapshots/prod.sqlite \
--workers 6
```
---
## Bottom line
- Formal first screen: **not green**, no production change, fingerprint **pass**.
- Deeper reading: unconditional sign is a **compositional tug-of-war**, not a new jumpiness premium.
- **The test that matters for this platform already ran:** momentum-conditional fip is **negative, large, and reliable** on liquid breadth → fip remains a **conditional** research lead, not a closed door — and **not** a ship-ready gate input without a book experiment.