docs(experiments): build the §80.16 independence harness; measure cross-asset - #188
Merged
Merged
Conversation
…ss-asset `research/independence.py` has implemented §80.16's five measurements since PR #103, but nothing in the repo drove them over two real rules -- the 2026-07-20 cross-horizon run was ad hoc and left no script behind, so every future between-family question started from zero. This adds the script. Three passes, in increasing order of what they settle: - BETWEEN-FAMILY (turtle vs rsi_meanrev) -- degenerate. On daily bars rsi_meanrev takes zero trades on all five allowlisted assets: `oversold=20` on a daily RSI(14) is near-unreachable (PAXG and XLM never print one), and the handful that fire on BTC/ETH/ADA die at the support-level gate. Not a low correlation -- no relationship to measure. Arm B is settled-refuted anyway (§74.3), so this pass could never have tested its candidacy; it is a shakedown. - CROSS-HORIZON (40/20 vs 80/40) -- the calibration, and the reason to trust the rest. Reproduces `2026-07-20-horizon-independence.md` exactly: BTC 0.802, ETH 0.934, median entry gap 0 days. It also settles which P&L convention PR #103 used, which that write-up never states: `closed` reproduces the published figures, mark-to-market gives 0.813/0.759. Future §80.16 tables should stay on `closed` for comparability. - CROSS-ASSET (shipped turtle vs ITSELF on another asset) -- the finding. Mean P&L correlation 0.011, position 0.175, Jaccard 0.144 across 10 pairs, against 0.508/0.585/0.510 for cross-horizon measured the same way on the same assets. Asset breadth is roughly an order of magnitude better than horizon breadth as a source of independent evidence. §79.1 redirected the frequency plan to breadth without saying which; this says which. PAXG is the standout -- zero Jaccard against ETH, ADA and XLM, negative position correlation against all four cryptos. This also tests an assumption `2026-07-20-minbtl-sizing.md`'s allowlist case rested on: that added assets multiply trades/year roughly linearly, which only holds if the added trades carry independent information. At the measured correlations they largely do. Arm A reproduces the shipped trade counts exactly (13/13/4/6/8), so the harness is wired to the real rule. Correlations rest on 4-13 trades per asset and carry no confidence intervals -- the direction is far more robust than any individual cell; caveats are in the write-up. Ledger: three rows, all `diagnostic_only` / `a_priori`, chain verified intact. M 69 -> 72, N_decisions unchanged at 30, so MinBTL is untouched. The cross-asset rho-bar is deliberately NOT substituted into §78.2's N-hat, which corrects a trials count and is a different quantity. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ures `assets discover` pre-filters on the venue's reported 24h quote volume; `assets screen` admits on the median of `volume * close` over cached history. Same units, different statistics -- and the gap is large enough to change outcomes in both directions. The 2026-08-08 sweep shortlisted BICO on a reported $12.81M/24h. The screen then rejected it at a median daily volume of 108,004 -- 9x under the floor, a 227x gap between the two numbers. The same sweep nearly dropped DOGE for sitting 1.7% below the $5M discovery floor, when on the admission criterion it is ~30x ABOVE it. The pre-filter could not see either, because it was measuring a one-day snapshot of a quantity the gate medians over five years. - `screen.median_daily_quote_volume` is now the ONE definition of the statistic. `cli._market_facts` had it inline; a second copy next to `discover` would drift, and the symptom of that drift is exactly the bug being fixed here. - `assets discover --probe-liquidity` samples 180 days of daily candles per candidate (one extra request, same cost model as `--probe-history`), computes that same statistic, and marks it LOW/ok against `ScreenPolicy.min_median_daily_volume` -- the same floor `screen_asset` applies. Against the live venue it catches BICO (36,137, LOW) plus two the old filter would have passed through: IMU (71,713) and GWEI (440,864). Three of the top fourteen by 24h volume are sub-floor on the real criterion. DOGE probes 14,643,369 -> ok. It is an ESTIMATOR, not a verdict, and the output says so: 180 days recent vs the screen's full cached history. ZEC probes 33.1M against a full-history median of 1.23M -- a 27x spread from a recent surge. `ok` means "worth pulling candles for", never "will be admitted"; the gate still decides. A recent window also makes a false LOW unlikely for a currently-active asset, which is the safe direction for a pre-filter. No behaviour change to the gate itself: same criterion, same floor, same verdicts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
research/independence.pyhas implemented §80.16's five measurements since PR #103, but nothing in the repo drove them over two real rules. The 2026-07-20 cross-horizon run was ad hoc and left no script behind, so every future between-family question started from zero. This adds the script, plus its write-up and threediagnostic_onlyledger rows.Three passes
rsi_meanrev)The between-family pass is degenerate, not low. On daily bars
rsi_meanrevtakes zero trades on all five allowlisted assets —oversold=20on a daily RSI(14) is near-unreachable (PAXG and XLM never print one). Arm B is settled-refuted anyway (§74.3), so it could never have tested candidacy; it is a shakedown.The calibration is why the rest is trustworthy. BTC 0.802, ETH 0.934, median entry gap 0 days — exact reproduction of
2026-07-20-horizon-independence.md. It also settles which P&L convention PR #103 used, which that write-up never states:closedreproduces the published figures; mark-to-market gives 0.813 / 0.759.Cross-asset is the finding. 0.011 / 0.175 / 0.144 against cross-horizon's 0.508 / 0.585 / 0.510, same method, same assets. Asset breadth is roughly an order of magnitude better than horizon breadth as a source of independent evidence. §79.1 redirected the frequency plan to breadth without saying which; this says which. PAXG stands out — zero Jaccard against ETH, ADA and XLM.
This also tests an assumption
2026-07-20-minbtl-sizing.md's allowlist case rested on: that added assets multiply trades/year roughly linearly, true only if those trades carry independent information. At the measured correlations they largely do.Confidence
Arm A reproduces the shipped trade counts exactly (13/13/4/6/8), so the harness is wired to the real rule. Correlations rest on 4–13 trades per asset with no confidence intervals — the direction is far more robust than any individual cell. Caveats are in the write-up, including that this window had crypto broadly trending together (§79.16).
Ledger
Three rows, all
diagnostic_only/a_priori,keel trials verify→ chain intact. M 69 → 72, N_decisions unchanged at 30, so MinBTL is untouched. The cross-asset ρ̄ is deliberately not substituted into §78.2'sN̂, which corrects a trials count and is a different quantity.Scope
docs/experiments/only — no library code, no config, no rule, no gate." That was true when written and false at merge: a second commit was pushed to this branch before it squashed, so a code change shipped inside this PR. Corrected here rather than left to mislead, becausescripts/release_notes.pyinlines this body into the 0.5.6 release notes.The research half is
docs/experiments/only.ruffclean;docs/is outside the project's mypy scope (files = ["packages", "keel", "tests"]), matching the existing2026-08-05-coinbase-asset-class-probe.py.Also shipped in this PR —
fix(assets): the discovery pre-filter now measures what the gate measuresassets discoverpre-filtered on the venue's reported 24h quote volume;assets screenadmits on the median ofvolume × closeover cached history. Same units, different statistics, and the gap changes outcomes in both directions:screen.median_daily_quote_volumeis now the single definition of the statistic —cli._market_factshad it inline, and a second copy next todiscoverwould drift, which is the bug.assets discover --probe-liquiditysamples 180 days of daily candles per candidate (one extra request, same cost model as--probe-history) and marksLOW/okagainst the same floorscreen_assetapplies.Against the live venue it catches BICO (36,137) plus two the old filter passed through: IMU (71,713) and GWEI (440,864) — three of the top fourteen by 24h volume are sub-floor on the real criterion.
An estimator, not a verdict, and the output says so: 180 days recent vs the screen's full cached history. ZEC probes 33.1M against a full-history median of 1.23M — a 27× spread from a recent surge.
okmeans "worth pulling candles for", never "will be admitted". No behaviour change to the gate: same criterion, same floor, same verdicts. Tests:2137 passed, ruff and mypy clean.🤖 Generated with Claude Code