Repository navigation
Deflated Sharpe and PBO (CSCV) over the 6,605 retained research candidates - #199
Merged
seathatflowsinourveins merged 3 commits intoSep 24, 2026
Merged
Conversation
…valuation ledger Audit gap #11. A standard-library module written from Bailey and Lopez de Prado (2012, 2014) and Bailey, Borwein, Lopez de Prado and Zhu (2017) computes PSR, the deflated Sharpe ratio and the CSCV probability of backtest overfitting. Nothing was vendored. Parameters were frozen in params.json before the first computation. Over the retained 6605-record candidate ledger (sha256 08ea5309..., 301 aligned development episodes), the four selection candidates give DSR 0.552 (momentum120) and PBO 0.776 at S=16. All sensitivity cells give PBO between 0.76 and 0.96. The walk-forward selected series has PSR(0) 0.405. These results show no skill evidence. The work is offline, refetches no data and leaves the reserved segment unscored. Evidence: a local integration check, byte-identical on Python 3.12 and 3.13, with an independent numpy recomputation that matches exactly. The tests cover the DSR paper's numerical example (SR0 0.1132, DSR 0.9004, constants transcribed from the paper), synthetic PBO fixtures and a receipt replay. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With the mean metric and equal complementary halves, each trial's in-sample mean plus its out-of-sample mean equals twice its mean over the used rows. Every split that selects the same trial therefore lies on a line of slope exactly -1, and momentum120 is selected in 5,490 of 12,870 splits, so the pooled -0.727 slope is mostly a construction identity and says little about ranking persistence. The identity is now stated in the cscv_pbo docstring, the README and the receipt limitations. The slope row is removed from the README result table, and the receipt conclusion no longer cites it. The anti-persistence wording now rests on PBO 0.776 against a no-skill level of about 0.5 for four exchangeable trials, and is marked descriptive because the splits overlap and PBO has no p-value. A new unit test checks the identity: slope exactly -1 for an always-selected trial, and selected in- plus out-of-sample means equal to twice the selection-weighted full means. The numbers did not change. evaluate.py was re-run twice on CPython 3.13.15 and once on the pinned 3.12.3 runtime, giving byte-identical stdout that differs from the original only in the overfitting.py source hash. The receipt keeps runs 1-3 and records the fix-round runs separately. Focused tests: 14 passed, 0 skipped; with research-evaluation, 26 passed, 0 skipped on 3.12.3. Full suite: 4032 OK, 490 skipped on system python3. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins
deleted the
claude/overfitting-controls-20260924
branch
September 24, 2026 19:25
seathatflowsinourveins
pushed a commit
that referenced
this pull request
Sep 24, 2026
…guard branch Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Sep 24, 2026
… fill-precision branch Conflicts were registries and counts only: took main's copies, regenerated the rate-limit evidence (1693 trading, 16 data headers), re-pinned this branch's five sources in source-hashes.json and re-registered its files in the evidence manifest. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Sep 25, 2026
…-09-24/25 merges (#225) Updates four checkpoint entries: the paper lane, the simulation lane, alpaca-paper-operational and corporate-action-data. They now reflect #198, #199, #212, #218, #219 and #222. tests.test_grand_dashboard passes, and all state strings satisfy progress.py's public-token rule. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Closes audit gap from the 2026-09-24 trading wiring audit (native-agent-stack-71).
I added a deflated Sharpe ratio (DSR) and a probability-of-backtest-overfitting (PBO) check to the multi-candidate research lane. I ran both over the 6,605 retained candidate records. Neither shows evidence of skill.
Where the records are. The ledger itself is not in
blueprints/us-equities/research-evaluation; that folder only holds its hash (inreceipt.json). The file with that exact hash (08ea5309…) is already in the repo atevidence/artifacts/gap-wave2-20260923/us-equities__portfolio-risk/raw/3/regenerated/run-1/candidate-ledger.json. It is a byte-identical regeneration of the original run. No data was refetched.Implementation. I wrote the module from the papers rather than vendoring one. None of the candidate libraries was on this machine. eslazarev/purged-cross-validation is catalogued only as a discovery with no pin. pypbo and the R
pbopackage would each need a network fetch and a new dependency lock for about 150 lines of arithmetic. The module uses only the standard library, and its docstring cites Bailey and Lopez de Prado (2012, 2014) and Bailey, Borwein, Lopez de Prado and Zhu (2017). The receipt records a condition for switching to a maintained, licence-reviewed library later.Parameters.
params.jsonwas frozen (sha256 0e371da4…) at 15:53:14Z, one minute before the first run. It fixes three candidate sets:It also fixes 16 partitions for PBO (8, 10 and 12 as checks), mean label as the main metric (Sharpe as a check), and development data only (2015-01-02 to 2020-12-16, 301 aligned episodes). The reserved 2021 Q1 segment is excluded.
Results (primary set)
Every check setting gives PBO between 0.76 and 0.96, and DSR stays between 0.55 and 0.58.
Conclusion. The retained candidates look like selection noise, or in-sample rankings that slightly reverse, not skill. This only covers the three-ETF control lane. Nothing was tuned, promoted or rejected.
Limits on what this shows
Files added: in
blueprints/us-equities/overfitting-controls/:overfitting.py,evaluate.py,params.json,crosscheck.py,receipt.json(input hashes, method, parameters, commands, all results) andREADME.md. The test file istests/test_overfitting_controls.py. I also added a short section linking to the new lane inblueprints/us-equities/research-evaluation/README.mdand updated only that file's entry inmanifests/evidence.json. The new files are not registered in the manifest, following the rule to update only changed registered files.Tests. - New test file (13 tests, 0 skipped), passing on Python 3.13.15:
python3 -m unitteston system Python 3.13.15, which lacks numpy, jsonschema and PyYAML): 4031 tests OK, 490 skipped. None of the skips are in the new test file.Validation. - Required checks on the final tree, all exit 0:
scripts/validate.py,validate_catalogs.py,landscape.py --root .,evidence_manifest.py --check,verdict_review_gate.py --base origin/main --root .(no verdict rows changed) andtrading_gates.py --check.crosscheck.pyredoes the calculation with numpy 2.5.3, using direct slicing of all 12,870 splits and its own ranking. It matches the module exactly (DSR 0.5520685371554236, PBO 0.7756021756021756). It shares only the standard library's inverse normal function with the module.Independent review. Severities: medium, low, low, low, info, info, info. Fix round
30103cd6: fixed 1, rejected 1 (Partially rejected, the wording that the pooled slope 'can only be negative'. It is pulled towards -1 by construction, but the between-trial part (selected tria).🤖 Generated with Claude Code