Summary
An offline feasibility study (no live-path changes) that decides whether a book-driven early-exit rule raises net EV/bet vs hold-to-resolution while barely touching winners. Built subagent-driven on branch
feat/exit-study@c8eddb3(repowowjeeez/pmv2-crypto-algo,crates/analysis). 5 TDD tasks + per-task review + whole-branch review; 29 analysis tests green, build 0-warnings. Kept as-is, unmerged. RAN 2026-07-02 on live data → definitiveNO-GO, confirmed by TWO independent runs (well-powered — Phase-0 passed, not underpowered): exiting is significantly −EV vs holding (OOS z=−2.68 / z=−2.33). See Result below. Repo report:docs/superpowers/exit-study-report.md. Related: Crypto 5m Up-Down — Oracle-Lag Strategy (Canonical Spec) and crypto-shortterm-backtesting.
What it is
The strategy holds a 5-min Polymarket binary ~60–150 s and wins ~87%. Open question: can we sell/hedge a held position early when it’s turning into a loss, to cut the ~13% tail? Never studied before (unlike entry filters, where everything except the ask/EV cap was refuted — see crypto-shortterm-loss-filter-analysis-2026-06-26). It’s a feasibility question ⇒ a study, not a model: if the Polymarket book can’t foresee the turn early enough to exit into real value, no exit model is worth building.
The dominant constraint is winner preservation: exiting sells the held token into the bid; for a loser you recover only ~bid (small), for a winner you forfeit 1−bid (large) on the 87% that win. So a false-exit on a winner costs multiples of a correct exit on a loser ⇒ the rule must have high precision on losers. Winner-exit rate is a first-class headline and the GO is gated on it out-of-sample.
Architecture (crates/analysis)
exitlib.rs— pure, unit-tested library:Hold/Tickmodel +side_view(maps up/down book → the held side).fee/SLIP/hold_pnl/exit_pnl— SELL and BUY-complement P&L,t+Δfill, no-fill, depth. Fee0.07·p·(1−p), slip0.01(replicated verbatim fromwalkforward.rs, which is bin-private/not importable — plan-mandated duplication).book_prob/loser_lead_pr— H1: loser-conditioned precision/recall of a book-drop signal within exitable τ∈[60,150)s (NEVER a pooled AUC — the book also converges as τ→0).day_folds/clustered_bootstrap_delta/deflated_threshold— H2/H3: OOS day-folds + day-clustered bootstrap + trial-deflation.
exit_study.rsbin — DB (crypto_shorttermobservations⋈outcomes) → reconstructp_calfrom the FROZENcrates/observe/calibration.json→ build Holds (entry = first in-regime instant, reusingobserve::is_regime+analysis::backtest::select_side) → Phase-0 power gate → Phase-1(A) loser-lead PR → Phase-1(B) OOS clustered exit-EV over a 16-rule grid × 3 winner-exit ceilings → GO/NO-GO. Honors H1–H5 end-to-end.
Key decision — base branch (stacked on the harness)
Branched off the harness tip feat/backtest-harness (7d0f2f9), NOT main, because the plan reuses analysis::backtest::select_side + the analysis observe/types deps that live only on the (unmerged) harness. Main’s only select_side is a private twin in emit.rs the spec forbids re-implementing (silent-divergence risk). Consequence: exit-study can’t clean-merge to main until the harness merges. Related: crypto-shortterm-backtesting.
Reusable lesson — a lib-unit ≠ production-unit seam bug (the whole-branch review's whole reason for existing)
day_folds(days, k, embargo_days)subtracts the embargo directly fromdayvalues, so the embargo’s unit is coupled to whatever unitdaysare in. The bin builtdayin epoch-seconds (div_euclid(86400)*86400, days 86400 apart) but calledday_folds(&days, 6, 1)— subtracting 1 second from a midnight boundary excluded nothing, so the intended ≥1-day OOS embargo (binding H2↔H3) was silently ZERO → train/test contamination on exactly the loser subpopulation that drives the result. It passed the unit test only because that test fed day-indices[1..6](there, embargo 1 = 1 index). Every per-task review missed it; the whole-branch review (production call-site vs lib contract) caught it. Fix: makedayan epoch-DAY ordinal (div_euclid(86400), no ×86400) so production uses the same unit as the exact-contents fold test — which then genuinely locks the seam. Takeaway: a unit test that exercises a different unit/scale than production can green-light a broken invariant. Always confirm the test’s inputs are in production units, and keep a whole-branch pass whose job is call-site-vs-contract.
H5 linchpin — asymmetric NULL mapping
exit_pnlgates depth viaside_bid_sz < size(NOTis_nan). So to make “NULL depth = no-fill” (H5) actually fire, the bin maps NULL depth →0.0(triggers< size) while NULL bid/ask →NaN(triggersis_nan). A collapsing book (bid present, ask NULL ⇒ depth NULL) is then correctly a no-fill even though the spread guard can’t see a NaN ask. Non-obvious, load-bearing.
Other review-caught fixes
- Survivorship-biased fold-skip: a fold where no rule cleared the train ceiling was skipped entirely (excluded from
per_dayAND the majority denominator), biasing both GO gates optimistically at the tight ceiling. Fixed to score it as held (0-delta bets, counted in the majority denominator). - OOS winner-exit gate: GO now requires OOS
winner_exit_rate ≤ c(was report-only), per the spec’s dominant winner-preservation constraint validated out-of-sample (H2). - Deflation N:
deflated_threshold(grid_size() × CEILINGS.len(), 1.64)= 48, not 16 — count every swept variant (H2), z-bar ≈ 4.42.
Result (2026-07-02 operator run) — NO-GO
Ran ASSET=btc EXIT_START=2026-06-08 EXIT_END=2026-07-03 on live crypto_shortterm (Supabase mkofmdtdldxgmmolxxhc), 1,509,625 rows, exit 0.
Phase-0 PASSED — well-powered (NOT underpowered)
held_windows=2837,losers=350,distinct_adverse_days=21,book_density=0.9998. Comfortably above the ≥200-loser / ≥8-day gate — so the NO-GO is real signal, not small-sample. (Prior expectation of UNDERPOWERED was wrong: the broad in-regime held set is large.)
Phase-1(A) — book’s early lead on losers is WEAK. PR frontier (τ∈[60,150)): θ=0.10 → precision 0.85 / recall 0.13; θ=0.30 → 0.58 / 0.34; θ=0.50 → 0.40 / 0.57. Some lead (precision > ~13% base rate), but you can’t get recall without flagging winners.
Phase-1(B) — exiting is significantly −EV OOS. Best rule at ALL ceilings {0.02,0.05,0.10} = θ=0.30, BuyComp, δ=1:
| metric | value |
|---|---|
| OOS EV Δ /bet | −0.00785 (−0.79¢) |
| z (vs +4.42 deflated bar) | −2.68 → pass=false |
| OOS winner-exit rate | 1.85% (winners preserved — ceiling never bound) |
| couldn’t-fill rate | 52.3% |
| loser-exit rate | 15.6% |
Verdict: NO-GO — documented dead-end
Exiting loses ~0.79¢/bet vs holding, reliably (z=−2.68). It’s not winner-forfeiture (only 1.85% of winners exited). Two killers, both anticipated by the spec:
- The book doesn’t foresee the loser-turn early enough (weak PR).
- ~52% of the exits you’d want can’t fill — the moment a loser turns, its bid is collapsing/empty (the same thin-book reality as the FAK no-bids problem). ⇒ Do NOT build an exit/loss-cut rule into
@positionmanager. Hold-to-resolution is correct. Effort belongs on entry (the EV cap) and latency, not exits. The “wire into executor” follow-up was gated on GO, so it is moot.
Independent replication (second run, 2026-07-02) — same NO-GO
A separate session ran the study independently on a different window (BTC-only era 2026-06-08 → 2026-07-01, ~1.42M rows) and reached the same verdict:
| metric | this run | first run (above) |
|---|---|---|
| Phase-0 | PASSED — held=2530, losers=316, adverse_days=19, density 0.9998 | PASSED — 2837 / 350 / 21 / 0.9998 |
| best-rule OOS EV Δ /bet | −0.77¢ | −0.79¢ |
| z (vs deflated bar) | −2.33 | −2.68 |
| couldn’t-fill rate | 63% | 52.3% |
| ceilings | NO-GO at ALL ceilings | NO-GO at ALL ceilings |
Definitive — two independent runs, same killers
Both runs agree on the mechanism: (1) exit fills fail ~half the time exactly when needed — the loser’s bid is collapsing (the same thin-book reality as the FAK repricing problem, crypto-shortterm-fak-nomatch-root-cause-2026-07-02); (2) weak loser-lead (θ=0.10: precision ~.86 / recall ~.13); explicitly NOT winner-forfeit. Policy: hold-to-settlement stands; do NOT build exit machinery.
On-disk record: .superpowers/sdd/progress.md (exit-study section) + docs/superpowers/{specs,plans}/2026-07-01-exit-loss-cut-study* + docs/superpowers/exit-study-report.md (the run report). Related: crypto-shortterm-crypto-5m-algo-both-sides-2026-06-27, crypto-shortterm-down-side-money-path-fixes-2026-06-28, crypto-shortterm-algo-accuracy-audit-2026-07-02.