fix(data): normalize baostock volume to board lots + cross-source consistency guard - #1067
Draft
shadowinlife wants to merge 2 commits into
Draft
fix(data): normalize baostock volume to board lots + cross-source consistency guard#1067shadowinlife wants to merge 2 commits into
shadowinlife wants to merge 2 commits into
Conversation
A-share loaders return volume in each source's native unit with no metadata: tencent/mootdx/eastmoney/akshare/tushare report board lots (1 lot = 100 shares) while baostock reports single shares — a silent 100x discrepancy whose value depends on which fallback source served the request (see HKUDS#1062). Phase 1 (non-breaking; no data values change): - Loaders may declare volume_units keyed by market; tencent/eastmoney are market-dependent (A-share lots vs HK shares, empirically verified 2026-08-11); baostock pinned to shares, the single outlier - fetch_market_data surfaces _provenance.volume_unit per symbol from the serving loader ("lots" / "shares"; null when undeclared) - get_market_data tool descriptions (agent + MCP) state the contract so LLM consumers read the unit instead of assuming one Undeclared markets (crypto, futures, US via unverified sources) stay null rather than guessed. Pin tests lock the audit matrix from HKUDS#1062. Signed-off-by: shadowinlife <shadowinlife@gmail.com>
Phase 2 of HKUDS#1062. BaoStock was the single A-share source reporting volume in single shares while tencent/eastmoney/akshare/mootdx/tushare report board lots (1 lot = 100 shares) — a silent 100x discrepancy whose value depended on which fallback source served the request. - baostock_loader: divide native share volume by 100 at the loader boundary; fractional lots preserved (odd-lot trades are real); volume_units declaration now "lots" like every other A-share source - Loader cache version 3 -> 4 so entries cached under the pre-normalization unit are never served again - New empirical cross-source consistency test: the same settled trading day fetched from every reachable A-share loader must agree within 1% (network-guarded — skips when fewer than two sources are reachable); this is the runtime lock against future unit drift - Pin tests updated to the post-normalization matrix Verified end-to-end: 600519.SH 2026-07-31 — tencent 55,128 lots vs baostock 55,127.52 lots (ratio 0.999991; the 0.48-lot gap is baostock's exact share count including odd lots, within the 1% tolerance). Signed-off-by: shadowinlife <shadowinlife@gmail.com>
shadowinlife
added a commit
to shadowinlife/Vibe-Trading
that referenced
this pull request
Aug 11, 2026
- Merge 14 upstream commits (swarm/backtest/agent/RSI fixes) with zero conflicts; all gates unchanged (memory 321/2, CH 13/8, counts 54, env 0) - Update HKUDS#1062 tracking with Phase 1/2 draft PRs (HKUDS#1065/HKUDS#1067) and the canonical-unit decision (board lots) - Add section 4.6 pending research: R1 ClickHouse semantic-layer deep-dive (DB-side comments/DDL, semantic views, explicit valuation tool for the SELECT * leak path, metric dictionary, MCP preconditions) Signed-off-by: shadowinlife <shadowinlife@gmail.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.
Summary
Why
#1062 identified baostock as the single A-share source reporting volume in shares while tencent/eastmoney/akshare/mootdx/tushare report board lots (1 lot = 100 shares) — empirically 600519.SH 2026-07-31: baostock 5,512,752 shares vs tencent/eastmoney 55,128 lots, ratio exactly 100.0. Phase 1 (#1065) made the discrepancy visible via
_provenance.volume_unit; Phase 2 removes it. Canonical unit = board lots: the native unit of 4 of the 5 A-share sources and the mainstream A-share quote convention.Changes
baostock_loader.py: divide native share volume by 100 at the loader boundary; fractional lots preserved (odd-lot trades are real, so no rounding);volume_unitsdeclaration flips to"lots", matching every other A-share sourcebase.py: loader cache version 3 → 4 — entries cached under the pre-normalization unit become unreachable and are never served againtests/test_volume_unit_consistency.py(new): fetches the same settled trading day from every reachable A-share loader (tencent/eastmoney/baostock/mootdx) and asserts pairwise agreement within 1%; network-guarded — unreachable sources skip individually, and the test skips entirely when fewer than two sources are reachabletests/test_baostock_loader.py: normalization unit tests (clean lots + odd-lot fractional case)tests/test_loader_volume_units.py: pins updated to the post-normalization matrix (baostock now declares lots)Test Plan
Checklist
src/agent/,src/session/,src/providers/) without prior discussionNote for reviewers: this branch stacks on #1065 — it contains the Phase 1 commit until that PR merges, after which this PR's diff narrows to the Phase 2 commit. Behavioral change is bounded: only runs that previously fell back to baostock see different volume values (now consistent with the chain head instead of 100x off).