Repository navigation
Screening fixes and speedup, research harness fixes, and five pre-registered formula rounds - #2
Merged
Conversation
…500 symbols/month Batch download is the right interface and per-ticker API is the wrong one, so the fetcher now speaks both EODHD and Tiingo behind one interface. Choosing a vendor should not change the pipeline. Both silent failure modes from the Tiingo work are handled explicitly rather than left to chance: a quota response is never recorded as "no data for this symbol" (that manufactures false negatives indistinguishable from a real coverage gap), and every series is checked against the master's death date before being accepted, because a ticker master keyed by ticker cannot represent reuse and the prices endpoint resolves to whoever owns the ticker now. Measured, not guessed, from Tiingo's own pricing bundle: 50 req/hour, 1000 req/day, 500 unique symbols per MONTH, 1 GB/month. The unique-symbol cap binds, so 7,231 dead names is ~14 months on the free tier. EODHD at $19.99 for a single month is 100,000 req/day over 30+ years with delisted data listed as a feature, which is the same set in under an hour. Checked whether the full 7,231 is even the right target: a dead name that died trading $200k/day could never have been held by a strategy with a liquidity floor, so its absence cannot bias a 20-stock portfolio. Dollar volume at death is bimodal (p50 $0.19M, p75 $26.7M), and 48-65% of dead names clear the cross-sectional ADV20 floor depending on where it is set. The bias-relevant set is the liquid tail, not the full list.
…ormula rounds Production screening (tradingagents/screening): - Exclusion formula exclusion-20261004-1: trend gate tolerance (TREND_EPSILON) so a close equal to its MA20 no longer passes on float rounding. - Vectorised bar validation and evidence rows; one calendar window per scan. Synthetic 3,000-symbol scan 15.3s -> 4.1s, differential-tested on 20,000 random/malformed bar sets (reasons, windows, dtypes, hashes identical). - Includes the previously uncommitted data-quality gate, shared 20-stock analysis budget and exclusion-screen integration work. Research harness fixes (each with a regression test that fails on old code): - build_portfolio per-name attribution, turnover with short books, flat periods - study_as_of grid (was shifted and sampled the leading buffer) - analyse/parameter_sweep restricted to their span; discovery clipped to 2020 - plateau classification counted only rightward of the best cell - percentiles_fast ranked NaN at the top percentile - conditions 5/12/13 (production baseline, equal-weight excess, holdout sign) - point-in-time SEC 10-K fundamentals module; build_panel needs no keys offline Rounds (all pre-registered, single-shot): - F-09 screen diagnosis: research universe is ~half ETFs; shortfall days 68+22 not 9+5; fill rule rejected; risk evidence holds on stocks only - F-10 literature candidates x3, F-11 SEC quality factors x2: all REJECTED - F-12/F-13 short formulas (5y/5y and pandemic-isolated splits): none qualified in selection; short conclusions dominated by survivorship bias Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 208 files, which is 108 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configuration
⛔ Files ignored due to path filters (90)
📒 Files selected for processing (208)
You can disable this status message by setting the
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Summary
Production screening fixes and optimisation, a set of research-harness measurement bug fixes, and five pre-registered research rounds searching for a 20-stock formula (long and short). No formula passed the R10 acceptance criteria. The production long-only exclusion screen stays in place, with corrected documentation of how it behaves.
This branch also contains work that was sitting uncommitted on
mainbefore this session (data-quality gate, shared 20-stock analysis budget, exclusion-screen integration, 2026-09-28/29 research outputs), plus the one localmaincommit that had not been pushed (4462b8c).Production changes (
tradingagents/screening)trend > 0was decided by rounding noise when a close equals its 20-day mean (computes as ±1e-16). AddedTREND_EPSILON = 1e-12; formula version bumped toexclusion-20261004-1, so old caches are invalidated by fingerprint and rescanned once.validate_and_clean_barsis now vectorised with numpy, and the expected calendar window is computed once per scan instead of once per symbol.bar_evidencebuilds its rows with numpy. A synthetic 3,000-symbol scan went from 15.3s to 4.1s. A differential test over 20,000 random and malformed bar sets found the old and new code identical on exclusion reasons, output windows and dtypes, evidence hashes, and factor values.docs/EXCLUSION_SCREENING.mdcorrects the "fewer than 20 names" frequency. On a stock-only universe it is 68 + 22 days over 2016–2025, not 9 + 5. The doc also notes that ETFs are excluded only indirectly, through the Nasdaq stock-screener market-cap source.Research harness fixes (each has a regression test that fails on the old code)
build_portfoliofiltered returns, then zipped them against unfiltered pickstop_knames; skipped periods kept stale holdingsnp.flatnonzero(valid_as_of(...))[::h]idiom (8 tools), replaced bypanel.study_as_ofanalyse/parameter_sweepbuilt portfolios on the whole panel;--period bothused 2016–2025 as "discovery"classify_curvecounted only cells to the right of the best cellpercentiles_fastranked NaN at percentile 1.0Also added: a point-in-time SEC 10-K fundamentals module (
research/src/fundamentals.py), andbuild_panelno longer needs Alpaca keys when the calendar cache already covers the window.Research rounds (all pre-registered and single-shot; details in
research/history.md)Notes for reviewers
SEC_USER_AGENT; no contact address is committed. Raw SEC and price data live under the gitignoredresearch/data/.tests/test_execution_long_run_refactor.pyupdates thelong_run_freshsnapshot hash. The same test first proves that, with the old schema and formula fingerprint restored, the previous full hash still matches.Testing
pytest tests/: 2001 passed, 335 subtests passedpython -m research.src.test_harness: all passed (11 new tests)python -m research.src.smoke_test: passedgit diff --check: clean🤖 Generated with Claude Code