fix(correlation): resolve bare tickers so the matrix stops failing with "Fetched: []"#472
Merged
Merged
Conversation
…th "Fetched: []" The /correlation endpoint passed user input straight to the data loaders, which key US/HK/A-share instruments by exchange-suffixed symbols (AAPL.US / 0700.HK / 600000.SH). Bare tickers — exactly what the UI hint suggests (e.g. "BTC-USDT,ETH-USDT,AAPL,SPY") — matched no loader and the request failed with "Could not fetch price data for at least 2 assets. Fetched: []". Three layered fixes: 1. infer_market: classify by explicit suffix first, then bare numeric codes by digit length (6 digits = A-share, <=5 = HK). The old prefix heuristics misrouted bare HK codes (0700 -> SZ, 9988 -> US), ChiNext codes (300750 -> HK), and even suffixed 830799.BJ (-> US). 2. _normalize_symbol (new): canonicalize bare tickers to the loader symbol form before fetching, keeping the user's input as the label. 3. Fetch loop: walk the market's full FALLBACK_CHAIN until a loader actually returns data instead of stopping at the first *available* one, and log every per-source failure instead of the bare "except: continue" that made this failure mode undiagnosable. Tests: +10 cases (bare/suffixed classification, symbol normalization, chain fall-through); 22 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
|
Merged — thanks for the root-cause work. The digit-length classification is the right disambiguator, and the available-but-empty chain fall-through closes a real silent-drop bug. Verified locally: 22 correlation tests green, |
warren618
added a commit
that referenced
this pull request
Jul 12, 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.
Summary
Fixes the Correlation tab failing with
Could not fetch price data for at least 2 assets. Fetched: []when given bare tickers likeAAPL,SPY— the exact format the UI hint suggests. Root cause: user input was passed straight to loaders that key instruments by exchange-suffixed symbols (AAPL.US/600000.SH), plus two compounding issues in market inference and the fetch loop.What's in it
Three layered fixes in
agent/backtest/correlation.py:infer_marketrewritten — explicit suffix is now authoritative (.HK,.SH/.SZ/.BJ,.US), then bare numeric codes classify by digit length (exactly 6 digits = A-share; ≤5 = HK). The old prefix heuristics misrouted bare0700→SZ,9988→US,300750→HK, and even suffixed830799.BJ→US. Prefix alone can't separate HK from A-share (both use leading 0/3); digit length can._normalize_symbol(new) — canonicalizes bare tickers to the loader symbol form before fetching (AAPL→AAPL.US,600000→600000.SH,0700→0700.HK), while crypto pairs and already-suffixed codes pass through untouched. The user's original input is kept as the matrix label.FALLBACK_CHAINSuntil a loader actually returns data, instead of stopping at the first available one — a loader can be available yet serve nothing (network error), which silently dropped assets a later loader could serve. Every per-source failure is now logged (logger.warning) instead of swallowed by bareexcept: continue, so the next person debugging this sees why.Tests (
agent/tests/test_correlation.py, +10 cases): bare/suffixed classification for all markets incl. BJ, symbol normalization, and a chain fall-through regression test (first loader available-but-empty → second loader serves). 22 pass.Notes
000001-style true ambiguity (Ping An Bank vs SSE Composite index) can't be resolved by inference — bare 6-digit codes default to the stock reading; the index still needs an explicit000001.SH.correlation.py+ its tests; verified end-to-end:AAPL,SPY→ 2×2 matrix (corr 0.4057),0700,9988,AAPL,SPY→ full 4×4 with eastmoney down (falls through to yahoo, failure logged).Closes #471.
🤖 Generated with Claude Code