Files
signal-platform/docs/research/prod-book-universe-horizon.md
dennisthiessen 1c38a94dd0 research: interpret prod book universe x horizon matrix; ignore candidate cache
Four-arm results: 505 stays positive (softer on deep history); liquid breadth
destroys book under current knobs. Stop tracking 1.3GB pkl cache under reports/.cache.
2026-07-19 14:25:06 +02:00

128 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Production book × universe × horizon matrix
**Status:** PRE-REGISTERED — prepare / MacBook run; no production changes.
**Branch:** `research/earnings-gap-and-sue`
**Runner:** `scripts/run_prod_book_universe_matrix.py`
---
## Question
How does the **live production book** (unchanged knobs) behave when we only vary:
1. **History length** used for entries (≈4y vs since 2016-07)
2. **Tradable universe** (prod ~505 vs 505 + PIT liquid Nasdaq/breadth)
No strategy modifications: same residual gate, 80/20 high-vol rank, GTL entry
machinery, 3× ATR trail, 30d max hold, gate-reset re-entry, `fill_mode=close`,
cost 10 bps/side, max 10, 1% risk.
---
## Pre-registered arms (locked)
| id | label | Entry start | Tradable universe |
|---|---|---|---|
| **A** | prod_4y_505 | **2022-07-01** | Prod ~505 only |
| **B** | prod_4y_505_liquid | **2022-07-01** | Prod liquid top-1500 |
| **C** | prod_2016_505 | **2016-07-01** | Prod ~505 only |
| **D** | prod_2016_505_liquid | **2016-07-01** | Prod liquid top-1500 |
- **End:** last available bar in snapshot (no artificial end).
- **4y start** chosen to align with recent PhaseA / book baselines (~mid2022 → mid2026).
- **2016-07-01** = first full month after typical Alpaca floor (~2016-01); residual 121 needs ~1y bars so first residual ranks appear mid2017 where feed allows.
### Universe definitions
| set | definition |
|---|---|
| **Prod ~505** | Symbols **not** in `research_rank_only` on the research snapshot (the original prod-universe copy). |
| **Liquid top-1500** | Point-in-time: among names with as-of close ≥ **$5** and valid 63d median $vol, keep top **1500** by that $vol. Same definition as breadth IC research. |
| **Prod liquid** | A name may enter the book on date *t* if it is prod **or** in the liquid top-1500 at *t*. |
Cross-sectional residual / vol / 80/20 ranks are **recomputed inside each arms
eligible candidate set** that period (so breadth arms are not ranked against
non-eligible thin names).
### Explicit non-goals
- No sector residual, SUE, FIP filter, gap-cap, take-profit, vol-target, corr-cap
- No retune of trail / cutoff / min_rr
- Survivorship: report levels with the standard caveat; **compare arms relatively**
### Reporting (required table)
Per arm: Sharpe, Sharpe SE (Mertens), CAGR %, max DD %, total return %, trades,
win rate if available, start/end, n qualified longs. One markdown table + JSON.
**No promotion rule** — descriptive matrix only. Human decides whether breadth
or depth changes the risk story.
---
## Snapshot requirements
- Prefer MacBook **deep** `research.sqlite` after sector-resid deepen (prod names
from ~2016, breadth deep, completion manifest `complete=true`).
- Race-guard before run.
- Sector map / sector ETFs optional (not used for ranking).
---
## Results
Generated: `2026-07-19T14:07:37` · artifact
`reports/prod-book-universe-horizon-20260719-140737.json`
Snapshot: MacBook deep `research.sqlite` (506 prod + breadth prices; 2.39M raw
GTL candidates). Strategy knobs = live production (residual 80, 80/20 high-vol
rank, ATR trail 3×, hold 30, gate-reset, `fill_mode=close`).
> Survivorship: today's constituents backfilled. **Compare arms relatively.**
> Absolute deep CAGR/Sharpe are not deployable forecasts.
| arm | universe | entries from | Sharpe | SE | CAGR % | max DD % | total ret % | trades | win % | vs SPY |
|---|---|---|---:|---:|---:|---:|---:|---:|---:|---:|
| **A** | 505 only | 2022-07-01 | **1.32** | 0.49 | **31.8** | **18.9** | +205 | 374 | 35.6 | +96.5 |
| **B** | 505 + liquid 1500 | 2022-07-01 | 0.14 | 0.50 | 1.8 | 55.3 | 7 | 706 | 29.3 | +95.0 |
| **C** | 505 only | 2016-07-01 | **0.88** | 0.31 | **16.7** | **24.4** | +369 | 763 | 36.7 | +257 |
| **D** | 505 + liquid 1500 | 2016-07-01 | 0.06 | 0.32 | 7.0 | 73.9 | 52 | 1567 | 28.0 | +254 |
Qualified longs: A 1448 · B 6587 · C 2450 · D 11551.
### Read (relative only)
1. **Same strategy, broader liquid universe kills the book** (A→B and C→D).
Sharpe collapses; DD roughly triples; win rate drops ~68pp; trade count
~doubles. This matches earlier breadth IC work: the production residual +
high-vol package is a **large-cap / prod-universe** edge, not a
“more names = better” edge.
2. **Longer history on 505 stays positive but softer** (A→C). Sharpe 1.32 → 0.88,
CAGR 32% → 17%, DD 19% → 24%. Still well above the liquid-breadth arms.
Levels are optimistic (survivorship); the useful message is “edge does not
vanish when 2018/2020 are included,” not “expect 17% CAGR forever.”
3. **Arm A vs older PhaseA / short-window controls** (~Sharpe 1.72.1): this
matrix re-ranked on deep research.sqlite with a fixed entry start; numbers
need not match prior reports row-for-row. Use **this table for AD
comparisons**, not for rewriting the production baseline number.
4. **No production change implied.** Keep the live ~505 universe. Do not broaden
the tradable set to liquid Nasdaq under current knobs without a new
pre-registered design (and almost certainly a different rank/tilt package).
## Verdict
**Descriptive matrix complete.**
| question | answer from this matrix |
|---|---|
| Prod book @ ~4y / 505 | Positive (arm A) |
| Same + liquid Nasdaq | **No** — large degradation (arm B) |
| Prod book since 2016 / 505 | Still positive, milder (arm C) |
| Same + liquid Nasdaq deep | **No** — worst arm (arm D) |
**PENDING_HUMAN** only for whether to log “universe broaden under current knobs”
as rejected in the main research index. Strategy knobs unchanged either way.