Files
sanguo_vnpy_v2/docs/data-platform
claude_dev 075052da54
CI/CD / test (push) Successful in 38s
CI/CD / nas-deploy (push) Successful in 3s
CI/CD / nas-verify (push) Successful in 12s
fix(data): 10-01 二轮审计吸收——白名单补四类+三注册表钉死测试; data-monitor 两班入自监; 旧名注册脚本根治; manifest 补齐; spec 三勘正 [vps] [nas]
- P1-5 读写注册表脱节: EVENT_PANEL_TYPES 补 margin/sw_industry/dragon_tiger_seats/
  nb_daily(15→19, 09-12 四域注册采集时漏同步); 新增 test_whitelist_sync 钉死
  「采集 PER_DATE_TYPES 全族+gdhs == 白名单 == manifest domains ⊇」三同步义务;
  nb_hold 季频 asof 语义不进 exact-date 底座(钉死边界, 零消费方)
- P1-6 manifest 脱节: data_manifest.yaml 8 域→27 域(补事件面板族 19 类),
  消 data_gap_check 对真实供给误开缺口 issue 的潜伏面
- P1-10 监控自监: SCHTASKS +sanguo-data-monitor-morn/eve(17→19); 两 wrapper 本就
  恒 exit 0(设计预留), 非零=真崩, 零假红; 双班全死盲区待 strategy 域 health
  mtime 反盯(已转呈)
- docs_audit 旧名根治: register_schtasks.ps1 重写为现役 bs-daily/xt-daily
  (旧版重跑会复活死任务双开, 09-01 事故同源); bs_eod_wrapper/xt_eod_wrapper
  头注勘正
- docs_audit spec 三勘正: §16.1 白名单 14→19 类; §20.1「零改动自动可读」落空
  改「白名单一行即读+钉死测试」; §18.8 自称权威降级+ak-daily 07:35→19:00
  (VPS 实查)+xt 行名归一+ak-events 指针化; §20.10.2 硬计数指针化;
  §20.15.1/runbook 在岗 17→19
- docs_audit README §4 调度表整表换现役 10 任务; data-monitoring 计划加三行
  状态头注(初值退出权威位)

tests: data_platform+portfolio 1397 passed

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-01 09:19:29 +08:00
..

数据层总览(Data Layer)

A 股量化平台 方案 A 数据层单一权威记录。采集源 → 权威存储 → Provider → 策略全链路闭环。 维护:数据 session。策略层接口对接见本文 §6;策略逻辑本身由策略 session 负责。 深读设计依据:docs/superpowers/specs/2026-07-21-data-source-fusion-design.md(§14 权威层定稿)。 历史中间设计/plan 已归档至 docs/archive/data/。


1. 架构总览

采集源(VPS定时任务)          权威存储层(VPS本地)            使用层(Provider)          策略层
─────────────────         ──────────────────         ──────────────────       ─────────
baostock  ─┐                                         get_closes_panel        选股/轮动
xtdata    ─┼─► staging ─► 验证 ─► 合并 ─►  dbbardata ─►┐                     (BulletTrade
akshare   ─┤            (validator)     (merge)       ├─ LocalUnifiedProvider  三策略)
sina/东财/腾讯─┘                          constituent_unified─►┤              filters
                                          valuation_baostock ─►┼─► get_fundamentals_df
                                          三表 parquet ─►────┘   get_limit_status_batch
                                          bs_adjust_factor        ...

核心原则:Provider 只读 VPS 本地数据,零 online;下载经 staging 隔离 → 验证 → 合并主库,绝不直接写主库。


2. 数据布局(VPS 本地,C:\sanguo_vnpy_v2\data\)

存储 形态 内容 关键说明
dbbardata(quant_trading.db) SQLite 表 唯一行情表:日线(raw) + 15min 含退市股 + ETF + 北交所920;schema (id,symbol,exchange,datetime,interval,volume,turnover,open_interest,open/high/low/close_price);UNIQUE (symbol,exchange,interval,datetime);WAL 模式
bs_adjust_factor SQLite 表 前复权因子 get_closes_panel(fq='qfq') asof merge
constituent_unified SQLite 表 20 指数成份股 9 宽基 + 000985 中证全指(全市场) + 000928000937 中证800十行业;was_removed 治幸存者偏差
valuation_baostock parquet/年 pe / pb / isST 2003-2026,按年
三表(akshare) parquet balance(221列)/income(170列)/cashflow(316列) 财报季更新
A股日线/分钟 parquet 兜底 回测 DB 为主,parquet 兜底

⚠️ 6 位码同名碰撞:000852/000905/000016/000985/000928~000937 在 SZSE 是股票、在中证是指数点位。dbbardata 用 exchange 消歧:SSE = 中证指数点位(约定),SZSE = 个股。指数点位由 sina_index_eod.py 拉取入 exchange=SSE。


3. 采集源职责

源 职责 限制
baostock 个股日线(含退市)+ 15min + pe/pb 单进程单登录,不并发(多连接→封 IP 6-24h);日 ≤ 48000 次
xtdata(miniQMT) ETF + 基金 + 北交所 920xxx 沪深京全覆盖;volume 单位需 ×100 对齐
akshare 三表 + events + top10 股东 东财瞬时限流(断路器 + 夜间重试兜底)
sina→东财→腾讯 14 指数点位 级联,腾讯兜底 5 个 sina 停更

4. 增量管线(定时任务 schtask,VPS)

schtask 时间 职责 wrapper LOOKBACK
sanguo-bs-daily 18:05 日 baostock 个股日线+15m+估值 → 串行季频财务 fund(08-20 重组单入口) bs_daily_wrapper.ps1 7 天
sanguo-idx-daily 18:30 日 14 指数点位(sina 级联) sina_index_eod_wrapper.ps1 —
sanguo-ak-daily 19:00 日 akshare valuation/financial_abstract 逐股日更 ak_eod_wrapper.ps1 —
sanguo-ak-events 19:30 日 per-date 全族事件面板(清单权威=采集注册表 PER_DATE_TYPES) ak_events_wrapper.ps1 —
sanguo-ak-events-retry 周一至五 20:30 起每小时×4 ak-events 兜底重跑(marker 幂等) ak_events_wrapper.ps1 —
sanguo-xt-daily 21:00 日 ETF/基金/北交所920(xt 桥) xt_eod_wrapper.ps1 30 天
sanguo-ak-vintage 09:00 日 vintage 一致性自检(防线,不下载) ak_vintage_wrapper.ps1 —
sanguo-ak-weekly 周六 03:00 gdhs/share_capital/top_holders/financial_abstract+§20.13 三域 ak_stock_wrapper.ps1 —
sanguo-ak-monthly 财报季首周六 02:00 三表+forecast/express 全量洗库(XML 注册方式) ak_quarter_wrapper.ps1 —
sanguo-index 月度 16 号 19:50 成份股月度增量 index_monthly_wrapper.ps1 —

(2026-10-01 二轮审计勘正:本表原为 07 月旧名 bs-eod/xt-eod/ak-eod/ak-stock/ak-quarter——08-20 重组+09-01 旧名复活双开事故后已全部更名;调度权威=register_*.ps1 与 monitor_registry.py SCHTASKS,时刻冲突以 VPS 实查为准。) sanguo-index STEP0:parse_csindex_announce 回溯公告治偏差(000852/932000)+ --indices 刷 11 新指数;STEP1-3 migrate→merge。 写锁错峰已落地(xt-daily 21:00);bs CLOSE_WAIT 卡死修复与调度史详见 runbook。


5. 工作流与铁律

下载链路(用户铁律):

下载 → staging 隔离 → validator 验证(成功率95%,扣北交所) → 合并主库 → 推 NAS

绝不直接写主库(下载质量不可控,曾出现覆盖截断整年)。

约束:

  • baostock 单进程单登录不并发;日 ≤ 48000 次
  • 直连不走代理:unset http_proxy https_proxy all_proxy
  • provider 读 VPS 本地,不调 online
  • 数据层瑕疵报数据 session 根治,不在 provider 适配兜底
  • commit ≠ 部署 VPS:改完 scp 到 VPS + findstr 验证
  • VPS Windows:python -X utf8、反斜杠路径、GBK 控制台用 ASCII 脚本
  • Mac Mini 长任务前 caffeinate -i -s 防睡眠

6. Provider API(LocalUnifiedProvider)

读本地零 online,治偏差(成份股并集 + 前视偏差修复)。14 个公开方法:

方法 用途 备注
get_price(security, start, end, frequency, fields, count, fq) 单只行情 聚宽兼容
get_closes_panel(symbols, start, end, interval='d', fq='raw') 批量收盘价宽表 fq='qfq' 批量前复权;UNION ALL 替 OR 链(340×);chunk=400;5128 只 33s
get_index_stocks(index, date) 指数成份股 读 constituent_unified
get_constituent(...) 成份股详情 治偏差
get_fundamentals_df(stocks, date, fields=None) 基本面 fields= 短路(只算所需源表)+ ThreadPool;300 只 68s→7.4s(9.3×)
get_value_metrics(security, date) 价值指标(单只) —
get_value_metrics_batch(stocks, date) 价值指标批量 ThreadPool 包装
get_trade_days(start, end) 交易日历 —
get_security_info(security) 证券信息(单只) —
get_security_info_batch(stocks) 证券信息批量 2 SQL 替 N×2(ST/次新过滤提速)
get_limit_status_batch(codes, date) 涨跌停/停牌批量 精确算 high_limit=round(prev_close×(1+幅度),2);板块感知(主板10/创业科创20/北交30/ST5,历史ST from valuation_baostock.isST);停牌=volume==0
get_current_tick(security) tick ⚠️ 无 last_price/high_limit 字段,filter 已改用 get_limit_status_batch
get_split_dividend(security) 拆分分红/复权因子 —
get_all_securities(...) 全证券列表 —

四轮批量接口交付(commit f416a17/d2cd8fa/1cc9126):行情 get_closes_panel / 财务 get_fundamentals_df fields= / filters+价值 get_security_info_batch+get_value_metrics_batch / 涨跌停停牌 get_limit_status_batch。

filters(sanguo_portfolio/filters.py):filter_paused/limitup/limitdown 已接入 get_limit_status_batch(向后兼容:无参=保留全部)。


7. 已知缺口与定论

项 状态 定论
行业治偏差(成份股历史调整) 部分覆盖 content HTML 解析已做(was_removed 8→99,主要覆盖 2009 + 零星 2016-2022);2010-2025 定期 csindex 无存档,免费源穷尽,用户接受残留偏差(不上 wind/choice)
北交所 920xxx ✅ 补全 xtdata 独占(baostock/akshare 不覆盖),39 只,volume×100 对齐
实盘标的范围 ✅ 定论 只做主板 + 创业板(filter_kcbj_stock 排除科创北交,用户未开户 50 万门槛);数据层仍全量补成份股治偏差,两层解耦
行业指数点位 ✅ 修复 14 指数入 exchange=SSE,策略 03 不再永远判熊
akshare 三表 ✅ 鲁棒 原子写 + --repair + is_parquet_healthy

8. 待办(Phase 2,低优先)

  • 归档 15min 一次性灌库链(backfill_15min_baostock 等被 tests/data/test_backfill_15min_hardening.py import,需同步处理测试)
  • 归档旧回填 import 链 + Mac .sh 链(build_daily_from_xtdata/import_vnpy_*/raw_redownload 等被 wrapper 引用,需 VPS schtasks /query 确认非活跃后归档)
  • 行业治偏差 2010-2025(若有 wind/choice 授权再补)