From aa6cd5cac440c73a235faca61949b6781ef5aa51 Mon Sep 17 00:00:00 2001 From: Dennis Thiessen Date: Wed, 5 Aug 2026 22:23:11 +0200 Subject: [PATCH] docs: record portfolio capacity findings --- docs/research/README.md | 21 +-- .../portfolio-capacity-bracket-findings.md | 124 ++++++++++++++++++ 2 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 docs/research/portfolio-capacity-bracket-findings.md diff --git a/docs/research/README.md b/docs/research/README.md index 393e116..68d038a 100644 --- a/docs/research/README.md +++ b/docs/research/README.md @@ -25,7 +25,7 @@ score, Structural S/R, the Gate Target Ladder, sentiment, fundamentals) is | 1.5× ATR initial stop | Real exit | Cuts losers fast | | 3× ATR trailing stop, 30-day max hold | Real exit | Best Sharpe of every exit tested | | Post-stop normal gate reset | Re-entry policy | Stop always closes; a later gate failure and subsequent fresh qualification define the next signal episode. The selected study arm reached Sharpe 1.77 / CAGR 48.3% at capacity 10; live scan-before-outcome timing is stricter (Sharpe 1.68 / CAGR 44.8% analogue). [Full study](post-stop-reentry.md) | -| Max 10 concurrent positions, 1% risk per trade | Sizing | Cap never binds in practice | +| Max 10 concurrent positions, 1% risk per trade | Sizing | The cap binds by signal count, but the focused bracket found negligible opportunity cost: cap 15 admitted every blocked setup and added only 0.0018 R/trade in affected paths. [Findings](portfolio-capacity-bracket-findings.md) | | Structural S/R | Human-facing product context | Clean, capped zones for charts and alerts; not read by the scanner | | Gate Target Ladder | Screening machinery | Volume-free transient proposals preserve the production candidate set exactly; never an exit | @@ -61,7 +61,7 @@ invites overfitting. |---|---| | ATR trail multiple {1.5–4.0} | **Keep 3.0** — ≤2.0 whipsaws out the right tail; ≥2.5 is a plateau | | Momentum lookback (6-1, 3-1, 12-7 Novy-Marx, composites) | **Keep residual 12-1** — the others have IC ≈ 0 or weaker t-stats | -| Selection cutoff {70…90} × book size {10, 15, 20} | **Keep 80 × 10** — monotonically worse in both directions | +| Selection cutoff {70…90} × book size {10, 15, 20} | **Keep 80 × 10** — the focused daily bracket found no meaningful gain from cap 15, while weekly rank replacement hurt. [Findings](portfolio-capacity-bracket-findings.md) | | Position sizing (equal-weight, inverse-vol, risk-% sweep) | **Keep 1% fixed-fractional** | | Primary-target probability floor | **Keep 20%** — pruned lottery targets, 1,428 → 1,089 qualified, lifted Sharpe | | Primary-target R:R selector | **Keep 1.5** — target choice is intentionally independent of the later 2.0 activation floor | @@ -146,6 +146,7 @@ knobs. | **Broader universe** | Composition changes factor signs (fip tug-of-war); vol-tilt on breadth is only a **directional hypothesis** (auth. −0.048 / t −1.36) | Any prod broaden must re-validate 80/20 tilt; offline research only; research.sqlite requires completion manifest | | **Forward paper-trade record** | The only true out-of-sample evidence the snapshot cannot give | Time; mark entries at actual near-close fill once ops ships | | **Better target model for clear-air names** | The return is demonstrably there (#2 wins on raw CAGR in *both* train and test); it's the *flat* 3× ATR target that makes it too expensive in risk | Needs a per-name model, not a constant k×ATR | +| **Minimum effective-risk floor** | In cap-never-bound paths, the confounded 0.5% floor arm removed about 8% of fills while EV rose from 0.328 to 0.399 R and PF from 1.60 to 1.75, with exposure nearly unchanged | Run a single-variable A/B: cap 10 control versus cap 10 plus `min_initial_risk_fraction=0.005`. [Capacity findings](portfolio-capacity-bracket-findings.md) | --- @@ -197,11 +198,15 @@ qualification. The [daily re-entry matrix](post-stop-reentry.md) supports this for the current 10-position book, but not as a universal rule for other portfolio capacities. -Capacity itself is no longer considered settled. The current daily Phase A -control rejects 519 qualified entries because the ten-slot book is full versus -472 admitted trades. The older weekly “cap never binds” result is stale. The -[frozen focused capacity bracket](portfolio-capacity-bracket.md) compares cap -10, cap 15, cash-only unbounded, and weekly current-rank top 10 without tuning -replacement variants or using a formal promotion gate. +Capacity is now closed as a negative result. The current daily Phase A control +does reject 519 qualified entries because the ten-slot book is full versus 472 +admitted trades, so the older weekly “cap never binds” claim was stale. But the +clean cap-15 arm admitted every opportunity the strategy requested and added +only 0.0018 R/trade in paths where cap 10 bound. Weekly current-rank replacement +reduced mean EV and created substantial churn. Keep cap 10 and do not build the +replacement policy. See the [frozen specification](portfolio-capacity-bracket.md) +and the separate [capacity findings](portfolio-capacity-bracket-findings.md). +The only open follow-up from that run is the confound-free 0.5% minimum +effective-risk-floor A/B. The next real evidence is **forward**, not backward: the live paper-trade record. diff --git a/docs/research/portfolio-capacity-bracket-findings.md b/docs/research/portfolio-capacity-bracket-findings.md new file mode 100644 index 0000000..5d38d9f --- /dev/null +++ b/docs/research/portfolio-capacity-bracket-findings.md @@ -0,0 +1,124 @@ +# Portfolio-capacity bracket — findings + +Date interpreted: 2026-08-05 + +Status: **capacity and weekly replacement closed as negative results; the +minimum effective-risk floor remains an open single-variable follow-up.** + +This document interprets the frozen v2 run without modifying its generated +outputs: + +- result commit: `24482c6`; +- simulation source commit: `6fc82ae8574de9104c83273e018391e75a5f8ac6`; +- frozen specification SHA-256: + `f1e37783cf6d157ecc827d48211fa45da16f0a0ac19cd23686b3902d347a1898`; +- JSON SHA-256: + `2435875667097db7416a0d96f412db81d2f2d09ba053748c9f2cfb8a0cba4417`; +- Markdown SHA-256: + `dc3f5de25eb0a156ce51d0025c90e04ac0977e9502dec47bcf1b25bdcf609c81`. + +The run completed 78 empty-book paths, 97 warm-seed paths, seven annual +clusters under both protocols, two cost levels, four arms, and 1,400 cells with +no validation errors. The construction universe was 505 priced tradable +symbols plus 4,149 priced rank-only symbols. + +## Capacity is economically free + +The clean capacity treatment is `cap15_incumbent`: it changes no sizing or +admission rule. Its cap never bound in any cell (maximum observed position count +12; zero full-book skips), so it absorbed every opportunity blocked by cap 10. + +At 0.10% per fill, split the 175 paths by whether the paired control recorded +any `skipped_book_full`. Values below are mean paired changes in net EV per +trade, in R: + +| Arm | Cap never bound (n=70) | Cap did bind (n=105) | +|---|---:|---:| +| `cap15_incumbent` | +0.0000 | +0.0018 | +| `cash_unbounded` | +0.0714 | +0.0077 | +| `cap10_weekly_top10` | -0.0246 | -0.0426 | + +The exact zero for cap15 in the never-bound stratum is also a harness validity +check: when the treatment cannot act, results are identical. Where it does act, +giving the strategy every slot it requested adds only 0.0018 R/trade. The old +519-blocked-versus-472-admitted count was true, but it did not imply that the +blocked opportunities were economically valuable. + +Decision: **keep the production cap at 10.** Do not remove it or raise it in the +expectation of additional edge. + +## The positive arm measured the risk floor + +`cash_unbounded` combined two treatments: no count cap and a 0.5% minimum +effective initial-risk fraction. Its EV effect is roughly nine times larger in +the 70 paths where the control cap never bound, so capacity cannot explain the +improvement. + +Within that never-bound stratum: + +| Measure | Control | `cash_unbounded` | +|---|---:|---:| +| Mean trades | 75.7 | 69.9 | +| Mean cash | 27.8% | 28.2% | +| Mean gross exposure | 72.2% | 71.8% | +| Mean hold | 15.4 sessions | 15.6 sessions | +| Mean EV | +0.328 R | +0.399 R | +| Mean profit factor | 1.60 | 1.75 | + +The floor removes about 8% of fills while leaving exposure and holding time +nearly unchanged. This is selection, not general de-risking: candidates that +available sizing compresses below half the intended risk are worse on average. +The report records repeated reject attempts, not the rejected candidates' +ranks, so whether the effect is rank-mediated remains unknown. + +Next research: one single-variable A/B, `cap10_incumbent` versus cap 10 with +`min_initial_risk_fraction=0.005`, with every other rule unchanged. Do not call +the current `cash_unbounded` result causal evidence for that floor until this +confound-free comparison is run. + +## Weekly replacement hurts + +Median paired deltas read zero because enough cohorts are inert. The distribution +is not neutral: + +| Protocol | Mean ΔEV | P25 ΔEV | Identical paths | +|---|---:|---:|---:| +| Empty book | -0.0360 R | -0.0817 R | 27/78 (34.6%) | +| Warm book | -0.0348 R | -0.1582 R | 14/97 (14.4%) | + +The arm made 2,170 replacements and 529 same-symbol re-entries within ten +sessions, so 24% of replacements were associated with short-horizon churn. + +Decision: **reject weekly top-10 replacement.** Future reports should show mean +paired effects and identical-path fractions beside medians whenever treatments +are inert in a material share of cohorts. + +## Warm dispersion was mostly structurally degenerate + +For six of seven anchors, control EV IQR is numerical zero (approximately +`1e-16`) and Calmar IQR is exactly zero. The displayed ratio `1.000` is therefore +mostly the implementation's zero-over-zero convention, not evidence of equal +nonzero dispersion. + +Two mechanics cause convergence: sizing and notional limits are fractions of +equity, making R and ratio metrics scale-invariant; and the 30-session maximum +hold is shorter than the 63-session minimum seed offset, allowing initial books +to wash out before the anchor. + +The exception is 2023. Control measurement-start positions vary from 6 to 9, +EV IQR is 0.0274 R, and Calmar IQR is 0.2675. The protocol therefore carries +state correctly, but its chosen offsets usually erase the initialization effect +it was intended to measure. + +Future initialization studies should use seed offsets shorter than maximum hold, +approximately 5–25 sessions. The current empty-book cohorts remain the primary +start-date evidence, but they necessarily mix initialization with market regime. + +## Final decisions + +1. Keep cap 10; its measured opportunity cost is negligible. +2. Reject weekly rank replacement. +3. Do not interpret the `cash_unbounded` improvement as a capacity effect. +4. Run only the focused cap-10 effective-risk-floor A/B next. +5. Report means, inert fractions, and absolute dispersion beside medians and + ratios in future sparse-treatment studies.