Files
sanguo_vnpy_v2/docs/superpowers/specs/2026-07-21-data-source-fusion-design.md
T

47 KiB
Raw Blame History

A 股多数据源融合层设计

日期:2026-07-21 创建 | 基于 brainstorming + 4 源全能力调查(akshare / baostock / miniQMT / csindex) 状态:活文档(唯一数据设计文档) —— 2026-09-02 起用户钦定:本文件是数据架构唯一权威设计, 每次数据架构变更必须同批更新到最新状态;演进采用「日期节追加,新节覆盖旧节相关决策」模式。 最后更新:2026-09-02(A 档截面数据域全量上生产,§15;使用层 provider 接口,§16;首夜巡查修正,§17)


1. 背景与痛点

多数据源(akshare / baostock / xtdata / miniQMT)各不全,整合时格式有偏差:

  • symbol 格式:600519 vs sh.600000 vs 600519.SH
  • exchange 命名:SSE vs SH
  • 复权口径:raw vs qfq
  • volume 单位:xtdata÷100 vs 原值
  • 价格源间漂移:同股同日不同源 close 微差

用户约束(明确)

  • 不要查询时网络源切换(源变化/限流不可控)
  • VPS 本地一份稳定数据,日常只读本地
  • 网络源只用于「采集时拼凑完整本地」
  • 使用层无感(本地缺才网络兜底,罕见)
  • 优先 miniQMT + baostock

2. 设计原则(三层)

职责 原则
采集层 多网络源 → 拼凑完整本地 各源 adapter + 定时 schtask;源不可控隔离在采集(失败重试,不影响使用层)
数据层 整理(重叠定权威,特定保留) 不强合物理表(vnpy 回归风险);每类定权威源(优先 baostock+miniqmt)
使用层 LocalUnifiedProvider 逻辑融合 读权威表 + 归一化 + 本地缺网络兜底;策略无感

核心:网络源不稳的风险只影响采集层(定时跑、可重试),使用层永远读本地 —— 风险隔离。


3. 数据源全能力盘点(综合调查)

3.1 已下(稳定源)

表/源 内容 范围 增量
dbbardata 日线+5m/15m(xtdata/akshare/baostock) 日线2010+/分钟2020+ 16:30
daily_baostock_full 日线 18 字段(pe/pb/turn/pctChg) 19902026 待 #7
bs_index_constituent 成份股 300/500/50(含退市) 2006+ 待增量
bs_adjust_factor 复权因子 全史 待增量
akshare 静态表 三表/估值/北向/龙虎榜/融资融券/股本/解禁/业绩预告 - 部分增量
miniQMT xtdata 日线+5m/15m 全周期(实时 T+0,零漂移) 16年 按需
miniQMT PershareIndex ROE/毛利率/EPS 季频 按需
parquet data/raw、daily_baostock、minute_5/15、static/index_const、qfq+raw ETF(5只) - 部分

3.2 重叠(5 处)

  1. 日线 OHLCV:dbbardata ∩ daily_baostock_full ∩ parquet raw(三处)
  2. 估值 PE/PB:akshare valuation ∩ daily_baostock_full(peTTM/pbMRQ)
  3. 15min:dbbardata ∩ parquet minute_15
  4. 基本面:akshare 三表 ∩ miniQMT PershareIndex ∩ baostock 季频
  5. 成份股:bs_index_constituent ∩ parquet index_const

3.3 新发现缺口(本次调查)

  • ETF 全市场日线(现仅 5 只,策略资产类别缺口)
  • 深证/中证历史成份股(治幸存者偏差,当前仅最新快照 = latent bug)
  • 退市股 K 线(baostock 有,从未提取;反幸存者偏差核心)
  • 申万行业 SW1/2/3 + 历史变动
  • 龙虎榜 / 合约信息(涨跌停/ST)/ 可转债 / 研报一致预期 / 股东户数 / 除权明细

4. 权威源地图(数据层整理)

数据类 权威源 物理存储 重叠处理 / 备注
日线 OHLCV(个股,历史) baostock daily_baostock_full dbbardata 日线保留(vnpy 回测硬依赖);parquet raw 冗余
日线(盘中实时) miniQMT xtdata xtdata API 独有(T+0 实时)
日线 ETF(全市场) miniQMT xtdata parquet/dbbardata universe 加 沪深ETF∪沪深基金,dividend_type='front' 自动复权
估值 PE/PB/turn baostock daily_baostock_full akshare valuation 兜底/校验
基本面指标 ROE/毛利率 miniQMT PershareIndex miniQMT API akshare 三表补原始报表
基本面三表(原始) akshare akshare 表 miniQMT Balance/Income/CashFlow + baostock 季频交叉
15min baostock dbbardata parquet minute_15 冗余可清
成份股 300/500/50(含退市) baostock bs_index_constituent query_*_stocks(date) 任意时点
成份股 深证/国证(399xxx) akshare(国证源) parquet index_detail_hist_cni + index_detail_hist_adjust_cni
成份股 中证1000/2000(000852/932000) 新浪 parquet vII_HistoryComponent(gb2312,含退市)
退市股 K 线 baostock daily_baostock_full query_all_stock status=0 + query_stock_basic 退市日期 + 逐只 K
复权因子 baostock bs_adjust_factor 独有
申万行业 SW1/2/3 miniQMT xtdata parquet get_sector_list + get_stock_list_in_sector;akshare 补历史变动
龙虎榜 miniQMT xtdata parquet get_longhubang;akshare 兜底
合约信息(涨跌停/ST/上市日) miniQMT xtdata parquet get_instrument_detail 全 A 一入库
可转债 akshare parquet bond_zh_hs_cov_min + bond_cb_adj_logs_jsl(转股价)
研报/一致预期 EPS akshare parquet stock_research_info_em
股东户数 miniQMT/akshare parquet Holdernum 表 / stock_zh_a_gdhs_detail
除权明细 miniQMT xtdata parquet get_divid_factors
龙虎榜/北向/融资融券/解禁 akshare akshare 表 独有(保留)

5. 归一化规则

维度 统一标准 源映射
symbol 600519.SH(数字+交易所后缀) baostock sh.600000600000.SH;dbbardata 纯数字+exchange 字段
exchange SH/SZ dbbardata SSE/SZSESH/SZ
日期 ISO 2026-07-21 各源统一
复权 raw 存储 + factor 字段(QLib:factor=adj/raw) 查询时按需 qfq($close/$factor);治 raw/qfq 冲突
volume 原值(股) xtdata ÷100 还原
停牌 OHLCV 全 NaN QLib 约定
溯源 source 字段 每行标来源 + 主源/补丁标记

6. 使用层:LocalUnifiedProvider(逻辑融合)

接口:

get_daily(symbol, start, end, adjust='raw')          # 个股日线
get_etf_daily(symbol, ...)                            # ETF 日线
get_fundamentals(symbol, fields, date)                # 财务指标/三表
get_constituent(index, date)                          # 成份股(含历史,治幸存者偏差)
get_industry(symbol, date)                            # 申万行业(含历史变动)
get_longhubang(symbol, start, end)                    # 龙虎榜
get_instrument_detail(symbol)                         # 涨跌停/ST
get_delisted_kline(...)                               # 退市股 K 线

职责:

  • 按数据类路由到权威表(§4 地图)
  • 归一化(§5 规则):源格式 → 统一 vt_symbol/exchange/复权/单位
  • 本地缺 → network_fetcher 透明兜底(罕见,如新股未及采集)→ 写本地 → 返回
  • source 字段溯源;可选多源交叉校验
  • 使用层 API 不变,不知数据来自哪个源

实现:扩展现有 sanguo_portfolio/providers/DataProvider 接口(BaostockProvider/LocalParquetProvider 已有)。


7. 增量 schtask 清单

schtask 数据 时间
sanguo-daily-update(已有) 日线+分钟→dbbardata xtdata 16:30
sanguo-bs-daily-increment(#7 待建) 日线→daily_baostock_full baostock 17:00
sanguo-etf-daily-increment(新) ETF 全市场日线 xtdata(universe 沪深ETF) 17:30
sanguo-akshare-static-increment(新) 估值/龙虎榜/三表/北向 akshare 18:00
sanguo-index-hist(新,半年度) 历史成份股调样 akshare 国证 + 新浪 调样后(6/12 月)
sanguo-delisted(新,月度) 退市股列表+K 线 baostock 月初

query 预算守 48000/天/IP(baostock 硬限):各 baostock schtask 错开 + 日计数器。


8. 分阶段实现

P0 — 治幸存者偏差 + 策略核心缺口

  1. 历史成份股:深证/国证(index_detail_hist_cni)+ 中证1000/2000(新浪 vII_HistoryComponent)+ 300/500/50(baostock 已有)
  2. ETF 全市场日线:xtdata universe 改 沪深A股∪沪深ETF∪沪深基金 + dividend_type='front'(改 build_daily_from_xtdata.py:40 + daily_update_xtdata.py:114)
  3. 退市股 K 线:baostock query_all_stock 筛 status=0 + query_stock_basic 退市日期 + 逐只 K → daily_baostock_full

P1 — 策略增强

  1. 申万行业 SW1/2/3(xtdata get_sector_list)+ 历史变动
  2. 龙虎榜(xtdata get_longhubang)
  3. 合约信息涨跌停/ST(xtdata get_instrument_detail)全 A 入库
  4. 可转债(akshare bond_zh_hs_cov_min + 转股价调整)
  5. 研报/一致预期 EPS(akshare stock_research_info_em)

P2 — 按需

  1. 股东户数 / 除权明细 / 业绩快报 / 大宗交易 / 宏观 / 期货

融合层(贯穿)

  1. 归一化库(vt_symbol/exchange/factor/volume 映射)
  2. LocalUnifiedProvider(读权威表 + 归一化 + 网络兜底)
  3. 完整度监控报表(每类覆盖率/缺口,源退化早发现)

9. 陷阱清单(实证)

  • ak.index_stock_hist 已下线(akshare 1.10.37,2024 初)—— 别抄 2022-23 旧博客
  • ak.index_stock_cons 的"纳入日期"字段有迷惑性 —— 只是当前 300 只各自最初纳入日,不含被剔除,治不了幸存者偏差
  • csindex.com.cn 是 Vue SPA —— requests.get 拿空壳,官网只当前 Excel 无历史
  • 新浪 fund_etf_hist_sina 不复权 —— 不适合回测;ETF 复权走 xtdata dividend_type='front'
  • 东财 fund_etf_hist_em 封 IP —— 单线程限速或避用
  • baostock query_all_stock 不列退市日期 —— 配合 query_stock_basic
  • 申万历史板块有变更 —— 回测用当时分类
  • ak.index_detail_cni(非 hist 版)2025-11-25 起只近期 —— 必须用 hist 版

10. YAGNI(不做)

  • 不强合物理表(冲突解决/历史一致性/vnpy 回归风险,代价大)
  • 不引 QLib/OpenBB 框架(几百 MB,只摘模式:factor/source/归一)
  • CS 截面归一(中期按需,先解决不全+格式)
  • 实时 tick/盘口(非日终策略才需)

11. 风险与对策

风险 对策
vnpy 回测硬读 dbbardata 不动 dbbardata,provider 层 SSE↔SH 映射
baostock query 预算 48000/天 增量 schtask 错开 + 日计数器(#7+day2b 同天 44296<48000)
东财封 IP 避用东财,优先 baostock/xtdata/新浪/国证
接口下线(如 index_stock_hist) 调查实证,不抄旧文
数据源漂移/幽灵尖峰 source 溯源 + 涨跌停/量异常校验
历史成份股缺口致回测幸存者偏差 P0 优先补(深证+中证1000/2000+退市)

12. 实现路径(writing-plans 拆)

  • Phase 1(P0 数据补全):历史成份股 + ETF 全市场 + 退市 K 线(3 个采集脚本 + 灌库)
  • Phase 2(融合层):归一化库 + LocalUnifiedProvider(读现有+新表)
  • Phase 3(P1 增强):板块/龙虎榜/合约/可转债/研报
  • Phase 4(运维):增量 schtask 全套 + 完整度监控

13. 开放问题与默认决策(自行决策,你可推翻)

# 问题 默认(我定) 备选 理由
1 exchange 统一格式 SH/SZ(provider 映射 dbbardata SSE→SH) 保留 SSE/SZSE baostock/xtdata 都用 SH/SZ,主流;vnpy SSE 在 provider 层映射
2 P0 三项优先级 全做(历史成份股 + ETF + 退市 K 线) 先 ETF(策略即用) 三项都治幸存者偏差/核心缺口,并行不冲突
3 ETF 复权方式 xtdata dividend_type='front'(前复权) raw + factor(精确还原) 前复权够策略用;raw+factor 中期按需
4 退市股 K 线范围 近 5 年退市(守 baostock 48000/天预算) 全退市(几千只,慢) 近 5 年覆盖绝大多数回测;全量可后补
5 LocalUnifiedProvider 接口 §6 签名(get_daily/get_etf/get_fundamentals/get_constituent/get_industry/...) 精简 覆盖全天候 + CTA 需求
6 增量 schtask 时间 17:00(baostock 日线)/ 17:30(ETF)/ 18:00(akshare 静态) 调整 错开 sanguo-daily-update 16:30 + day2b 02:00
7 物理表 不新建统一表,provider 读现有(dbbardata/daily_baostock_full/各 parquet) 建 daily_unified 避免 vnpy 回归 + 数据迁移(§10 YAGNI)

默认推进路径:按以上默认 → spec 定稿 → 转 writing-plans(P0 拆 3 个采集脚本实现计划)。你审 spec 时可推翻任一项,我改。


14. 方案 A 定稿(2026-07-22 讨论收敛 — 本节为最新,覆盖前文相关决策)

14.1 背景

P0 补全 + schtask 部署完成后,审计(audit_data_layout.py + dbbardata_probe.py 实证)发现「同类多源、多份落地、DB 多表」混乱。讨论收敛为方案 A:每类数据唯一权威源(允许互补 fallback,禁止并行)、DB 表唯一、估值/三表/事件不进 DB、DB 只放高频随机读取的 K 线+成份股+复权

14.2 权威源最终分工

数据类 权威源 备注
个股日线 OHLCV(含退市) baostock raw 真实价 → dbbardata('d')
ETF/基金日线 xtata baostock 盲区(只取 type=1)
个股当天实时(盘后 baostock 未更窗口/盘中) xtata 拼 baostock 历史,同为 raw
15min baostock 历史+增量同源
5min/1min baostock(暂停) 战略占位,size 扩容续
估值 pe/pb/ps/pcf/turn/pctChg/isST baostock 日线18字段拆出
基本面三表 akshare
成份股 300/500/50 baostock(历史)
成份股 深证 399xxx akshare cni(历史 union)
成份股 中证1000/2000 akshare csindex(当前快照) 历史不可补=永久 gap
复权因子 baostock 全链路复权基准
事件类(龙虎榜/大宗/北向/两融/解禁/预告) akshare

三大源:xtata(ETF+实时) / baostock(个股日线+估值+15min+复权+300.500.50) / akshare(三表+事件+深证中证成份股)。同类不并行,按标的/字段互补。

14.3 DB 边界(只放)

  • dbbardata:日线('d')+15min('15m')+5min('5m'占位)— 唯一行情表
  • constituent_unified:成份股合并唯一表(date,index_code,code,code_name,source)
  • bs_adjust_factor:复权
  • backtest_stats:回测(已有)
  • 不进 DB:基本面三表、估值 pe/pb、事件类、回测明细(独立 db)
  • 废弃 daily_baostock_full(OHLCV→dbbardata,pe/pb→parquet)、bs_index_constituent(合入 constituent_unified)

14.4 pe/pb 落地:parquet 按年宽表

data/valuation_baostock/<year>.parquet,列 date,symbol,pe_ttm,pb_mrq,ps_ttm,pcf_ncf_ttm,turn,pct_chg,is_st。选股排序(全市场某日)列存宽表秒级。baostock 日线增量同源拆出。

14.5 增量 schtask(4 个)

schtask 时间 内容 落点 预算
sanguo-bs-eod 18:05 baostock 个股日线+15min 增量+拆 pe/pb dbbardata('d'/'15m')+valuation_baostock/ ~11000/48000
sanguo-xt-eod 18:40 xtata ETF/基金日线+个股当天实时补 dbbardata('d') 无限流
sanguo-bs-akshare 19:00 akshare 三表+事件类 parquet 限频单线程
sanguo-index 月度 19:50 baostock+akshare 成份股合并 constituent_unified

baostock 单进程单登录,DAILY_LIMIT=48000,sleep 限速,login 探针 graceful skip,直连不走代理。5min/1min 不设 schtask。

14.6 dbbardata 补退市(本次审计发现,顺带治回测幸存者偏差)

实证(dbbardata_probe):退市股(000005/000023/600811)在 dbbardata 只有 15m,无日线 → 回测读 dbbardata 日线天然幸存者偏差。迁移:daily_baostock_full OHLCV 全量(含退市)→ dbbardata('d') INSERT OR REPLACE(本地 DB 迁移,无网络)。ETF 已在 dbbardata(不碰)。

14.7 复权统一

全链路 raw 真实价存储(dbbardata 存 raw),前复权由消费端按 bs_adjust_factor(baostock)统一算。xtata 当天实时同为 raw,可拼接。禁止混 xtata dividend_type=front。

14.8 数据迁移(5 单元,风险升序,备份+staging+可回滚+审计日志)

  1. 存量垃圾清理(_staging_xtdata 14万文件 / _xtdata.tar 1.4G / 归拢 cta_* dbg_* → backtest_files/)
  2. config 统一 VPS 路径(NAS 仅备份)
  3. 成份股合并(bs_index_constituent + index_const_hist union → constituent_unified,按指数代码去重,新浪300/50丢弃)
  4. daily_baostock_full 拆分(OHLCV→dbbardata('d') 含退市;pe/pb→valuation_baostock/.parquet;旧表 rename _old)
  5. dbbardata 个股日线切 baostock 源(单元4已覆盖:daily_baostock_full 含全量,在市股 REPLACE 覆盖 xtata,数值一致)

每单元:全库 sqlite3 .backup + rsync NAS → 脚本写 staging(新表/新目录)→ 验证探针(行数/distinct symbol/抽样价格/成功率)→ 用户确认合并 → 旧数据 rename _old 保留 7 天。全程 nohup + 审计日志 data/migration_logs/

14.9 config 清理

VPS config 的 daily_dir/raw_dir/qfq_dir/minute_15_dir 改 C:\sanguo_vnpy_v2\data\...(当前 yaml 指 NAS /volume1,容器版遗留)。NAS config 保留作备份。read_parquet_daily 的 daily_dir 统一指向 qfq(消除 daily/ vs qfq/ 分叉)。

15. 增补 2026-09-02:A 档截面数据域全量上生产(本节为最新,覆盖前文相关决策)

本节数据的使用层读取接口见 §16(get_event_panel / get_limit_pool,同日落地)。

背景:调研 daily_stock_analysis(Gitea 镜像 sanguo/daily_stock_analysis) 的数据采集面,双机实验(Mac + VPS 生产 IP 49.232.102.198)后落地。四 commit db789d6→020d7cd→00cfd45→46a0569,CI#303 NAS 验证绿 + vps-deploy#304 绿,tag=46a0569。

15.1 架构红线:单脚本注册表,零新采集脚本(用户钦定)

脚本按**数据源(栈)*分类恒定:akshare 栈唯一采集入口=scripts/data_platform/akshare_static_download.py, baostock 栈=bs_ 系列,xtdata 栈=daily_update_xtdata,新浪指数=sina_index_eod。新数据类型=注册表添行 +一个 fetcher 函数+wrapper 加名字,禁止每类型开新脚本。akshare 本身是聚合库(东财/新浪/同花顺都在内), 新浪/同花顺数据进 akshare 脚本=按栈分类,不算混源。

15.2 新数据域清单(全部落 data/static//,parquet+marker)

数据域 类型 源/端点(集群) 调度 行数 回补能力
zt_pool 涨停池 per-date 东财 stock_zt_pool_em(push2ex) ak-events 19:30 ~83/日 30 交易日内可回补
zt_pool_zbgc 炸板池 per-date 东财 zbgc_em(push2ex) 同上 ~6/日 同上
zt_pool_dtgc 跌停池 per-date 东财 dtgc_em(push2ex) 同上 0-2/日(空=当日真无跌停,写空+done) 同上
fund_flow_industry 行业资金流 per-date 快照 新浪 stock_fund_flow_industry('即时') 同上 90/日(净额/流入/流出/领涨股) 无历史回补,洞即永久
fund_flow_concept 概念资金流 per-date 快照 新浪 fund_flow_concept 同上 ~387/日
ths_industry 行业榜 per-date 快照 同花顺 board_industry_summary_ths 同上 90×12列/日
ths_concept 概念名单 per-date 快照 同花顺 board_concept_name_ths 同上 ~375/日
xueqiu_hot 雪球热度 per-date 快照 雪球 stock_hot_follow_xq('最热门') 同上 ~5634/日
sina_sector 新浪行业 per-date 快照 新浪 stock_sector_spot 同上 49/日(ths_industry 对账源)
hot_rank 东财人气榜 per-date 快照 东财 stock_hot_rank_em(emappdata) fetcher 就位未挂载,待墙测量拍板 ~100/日
gdhs 股东户数 per-period 东财 stock_zh_a_gdhs(datacenter) ak-weekly 周六 ~5342/期 marker 去重,无新期零网络
  • ak-events 事件窗现状 13 类 = 上表前 9 + 原有 dragon_tiger/block_trade/margin_sse/restricted
  • gdhs 形状特殊:build_gdhs_units 只枚举距今>90 天的季度末(披露守卫)——防未披露期拉空走「真空+done」 被 marker 锁死永不重拉;cyq 筹码判死后的筹码结构免费替代(策略侧共识)
  • 快照族节假日拉到上一交易日态(端点无 date 参数无自日期列),接受重复,消费方按交易日历过滤

15.3 东财墙模型(实测,勿再踩)

  • 每 IP 每窗口(~30-60min)放 1 发:push2 clist(行业/概念榜/资金流榜)、push2his(kline/cyq/个股资金流)、 emappdata(人气榜)三集群同款;第二发必死、镜像(1./17./79.push2)共享、请求形状无关 (dsa 的 efinance 四差异 http+IE11UA+无ut+fid=f12 全复刻也死)、失败重试不重置窗口
  • datacenter 集群(三报表/gdhs/top_holders)独立健康,不受 push2 惩罚波及;push2ex(涨停池)独立稳定连打全绿
  • cyq 筹码全市场=数学死(5552×40min≈154 天);dsa 的答案是 tushare cyq_chips token 且免费档 15 次/天
  • 行业/概念榜+资金流的免费答案=换域:同花顺(行业+概念榜)+新浪(资金流+行业)实测秒级零限流

15.4 语义与防线(全族统一)

  • 失败→返 None 不写不标保旧数据(次日重试);真空 df→写空+done;列名零清洗 akshare 原样落盘
  • 缺日防线(static_vintage_check.py 09:00):panel_gap_check 每工作日应有 1 个 parquet(节假日空文件也算有); 可回补族(zt_pool×3)洞≤42 日历日→告警+回补指引;快照族洞即永久→近窗洞告警查日志、旧洞只入 json 不刷告警
  • vintage_status.json 的 panel 块=策略守卫层消费契约:panel.<type>={n_files,first_date,holes_backfillable,holes_permanent}

15.5 消费契约(与策略 session 09-02 对齐)

  • 炸板率 = 炸板池行数/(涨停池+炸板池行数):涨停池=收盘仍封(「炸板次数」>0 行=炸过又回封),炸板池=触板未封, 并集≈当日触板全集,分母无遗漏
  • 涨停池 16 列:封板资金/首次封板时间/最后封板时间/炸板次数/涨停统计/连板数/所属行业( =免费当日热点行业分布信号,涨停行业集中度原料)/换手率/市值等
  • 温度计三支柱=涨跌停(hot_rank 待批)+雪球;情绪周期/打板/行业轮动因子原料自 2026-08 起逐日积累

16. 增补 2026-09-02:使用层 provider 接口(A 档数据的读取出口)

§15 采集落盘的数据在本节获得 provider 出口。设计经业界对照定稿(2026-09-02 用户拍板): dsa get_limit_up_pool / tushare limit_list_d(U/D/Z 参数化)/ 聚宽 per-domain 方法 / OpenBB TET ——共识三条:接口轴=数据域列名在数据层边界标准化(无一家透传原始中文列)、 泛型传输+语义入口分层(tushare 底层也是 pro.query(api_name, params) 泛型通道)。 miniQMT/QMT/PTrade 均无涨停池/龙虎榜类接口(业界惯例=外部源补),实盘 provider 同样读本地文件。

16.1 两层出口(「泛型底座 + 域语义门面」)

接口 定位 返回列
get_event_panel(event_type, date / start+end, trading_days_only=True) 保真底座:白名单 14 类统一通道(§15.2 全部+gdhs),研究/因子探索用 akshare 原样中文列 + trade_date(YYYY-MM-DD,文件名合成);别把底座列名当生产契约
get_limit_pool(kind="zt"|"zbgc"|"dtgc", date / start+end, ...) 涨停池门面:kind 三合一(← tushare limit_list_d),唯一有消费契约的域先建(温度计/炸板率/行业集中度) 英文标准列:code/consecutive_boards/seal_amount/break_count/first_seal_time/industry/limit_stat…(键名对齐 dsa)
  • 实现=TET Fetcher(fetchers/event_panel.py,FETCHERS 注册表新增 event_panel/limit_pool), LocalUnifiedProvider(回测)与 SanguoMiniQmtProvider(实盘,委托 self._unified)双侧同款 ——方法面钉死测试(issue #35)强制无缺口;双侧同 schema 支持副本对照验证
  • 列名漂移吸收:akshare 改中文列名时,门面映射表(_LIMIT_POOL_COLUMNS,基于 VPS 真实 parquet 实测 2026-09-02,dtgc 实测含 动态市盈率/封单资金/板上成交额/连续跌停/开板次数)吸收, 下游英文键不炸;有行但缺源列→DataSchemaError fail-fast
  • trading_days_only=True(默认):用 get_trade_days 滤非交易日——治快照族「周中法定假日文件 =上一交易日态复制品」的区间双计数;=False 按周一~五枚举(=采集侧口径)
  • 缺文件(洞/未来日/从未采集)=合法缺失→空 DataFrame;真空日(dtgc 0 跌停)→门面仍返标准列空表
  • hot_rank 未挂载不在白名单(拍板后与采集注册表、PANEL_TYPES 三处同步加)
  • 新数据类型接入=底座白名单加一行(零新方法);某域有消费契约后再升格门面(YAGNI,不加投机门面)

16.2 MCP 出口预留

FETCHERS 注册表新增两键即自动可被未来 provider MCP server 暴露 (Fetcher.fetch(ctx=provider, **kwargs) 直接调用,fetchers 包设计初衷)。

17. 增补 2026-09-02 深夜:首夜巡查修正(覆盖 §15 相关决策)

  • 首夜实绩(09-02 19:30,13 类): 12/13 绿——快照族 6/6 行数与双机实验一致 (资金流 90/387、同花顺 90/375、雪球 5634、新浪行业 49);唯一红=margin_sse(下条)。
  • margin_sse 结构性缺陷根治(用户批准): SSE 融资融券 T+1 供应(当晚拉当天→空响应 →akshare Length mismatch 崩),自 07-22 起慢性失血 43 天全空(旧码 empty+done 锁死, 缺日检查未覆盖老四类故无人发现)。修=①--force 回补 07220901(30/30 ok 59865 行, VPS+NAS 双端);②wrapper 拆 margin_sse 单独 **T-1T 两天窗**(564160d):每晚稳定写昨日, 当天失败不写不标、次晚同窗自愈。
  • NAS 同步链扩容(ab8f4e3): sync_parquet_daily.sh TYPES 原写死老 4 类——扩到 13 类; gdhs=per-period 季度日期永不落 7 天滚动窗,单独全量拉(≤10 文件幂等)。⚠️NAS 坑:03:00 链 以 root 跑留 root 属主文件,admin scp 覆盖之=Permission denied,先 rm 再拉。
  • 回灌纪律(zt_pool 0902 事故): 回灌窗口绝不含当日——盘前拉当日=拿到上一交易日态 复制品(0902 文件≡0901 逐值同)+marker 占位致当晚 19:30 跳过;已删+盘后重拉 52/15/8 真数据。
  • VPS 部署终态: 使用层 3 commit(4966d30/7f01c5f/564160d)推 VPS(run#1043,tag=564160d, gap=0),VPS 端 8/8 功能验证过(双层接口/区间滤日/回补数据可读/白名单拒绝/实盘方法面)。

18. 增补 2026-09-06:基本面语料库(新闻+公告)采集设计——NAS 域(本节为最新,覆盖前文相关决策)

用户拍板(2026-09-06,经 factor session 转达):范围=六项全做(新闻标题+摘要级增量/新闻全文级/ 新闻历史回补/公告元数据全量回补 2000 起/公告每日增量/定期+业绩类 PDF),唯一不做=公告 PDF 全量 (520GB/年)。前置调研=docs/fundamental_corpus_probes_20260906.md(三摸底实测)。 本节为 spec,验收通过后才实施;spec 阶段零建表零采集。

18.1 硬约束(用户原话级)

  1. 存储全部落 NAS、一律不上 VPS——「vps承载有压力,之前基本面都放在了nas上,没有放vps,本次 也一样」。VPS 零参与:零 schtask、零存储、零采集进程;repo 里进脚本随 nas-deploy 到 /volume1/homes/admin/.sanguo_projects/sanguo_vnpy_v2/(= 采集容器的 -v 只读挂载 /app, 与 5m 同款分发通道),VPS 侧永远不会被调度。
  2. 采集进程=一次性容器,与 sanguo-5m 统一(用户终拍板 2026-09-06「统一到5min吧」)。方案 演进:初版按用户「不要和docker绑定,避免docker重启就失败」设计为宿主机 venv 零 docker; 验收中用户权衡「不想搞出多种下载方法」,比较两方向后拍板 corpus 向 5m 的 docker run --rm 模式统一(反向统一有硬阻塞:5m 写入的 data_backup 库为 03:00 链 root 属主产物,admin venv 写不进;且需重验 baostock@py3.8、动在跑系统)。被治的痛点不变——主容器重启不再杀任务 (08-22 5m 被 CI 杀三案后的同款根治);保留的弱依赖=docker daemon 在跑+镜像 tag 不改名 (与 5m 同款,已跑一个月实证;daemon 停一天,数据次日自愈)。两项 corpus 专属改进:①DSM 任务以 admin 跑(09-06 实测 admin 可执行 docker 命令);②容器加 --user <admin-uid> → 输出文件 admin 属主(root 文件坑不复发),杀进程=docker stop sanguo-corpus(admin 一条 命令)。镜像环境完整+版本自动跟随 CI 部署,零 venv 自举/锁版本/漂移问题。家宽出口 IP ≠ VPS 公网 IP(49.232.102.198),与 VPS 侧 ak-daily/ak-events 的东财限流零冲突。09-06 实测 佐证:np-listapi/巨潮/东财文章页 ~35 发连续探测自家宽 IP 全成功、零限流。统一后全图 (机器内一种,物理下限):VPS=Windows schtask 家族(数值类)NAS=DSM→bash wrapper→ docker run --rm(5m+corpus 同款,对外爬取)+sync 链(内部搬运)。
  3. 时间带:全部采集限于 00:3017:30,避开 18:0523:45 傍晚带(VPS 夜任务密集+家宽使用)。 唯一日窗=每日 06:00 起(见 18.3)。
  4. 慢爬纪律:单进程单线程、per-domain 限速+抖动、直连不走代理(Session.trust_env=False,防 Mac 系统代理同款坑)。新浪线已判不可依赖(09-06 实测空返),本设计不使用。

18.2 数据模型(NAS 落位:/volume1/stock/corpus/,与 A股数据/ 平级)

/volume1/stock/corpus/
  news_meta/dt=YYYY-MM-DD/part-0.parquet    # 东财个股新闻·标题+摘要级(仅新条目,append-only)
  news_fulltext/dt=YYYY-MM-DD/part-0.parquet# 东财新闻正文(按 art_code 全局去重,4.1KB/条)
  ann_meta/dt=YYYY-MM-DD/part-0.parquet     # 巨潮公告元数据(仅新条目;回补的也落发现日分区)
  ann_pdf/YYYY/<announcementId>.pdf         # 定期+业绩类 PDF(文件名=唯一id,天然幂等)
  state/                                    # 断点水位+unit marker(JSON/parquet)
  logs/corpus_YYYYMMDD_HHMMSS.log

Schema(列名冻结,消费方=factor session 因子加工层,后续 provider fetcher 可包):

  • news_meta: art_code(pk), stock_code(6位), show_time, title, summary(可 null: np-listapi 回补段无摘要——search-api 只有最近100条,历史摘要物理不存在), media_name(同上可 null), url, first_seen_date
  • news_fulltext: art_code(pk,跨股票全局一条——同一篇稿提及多股只在 meta 层多行), url, show_time, content_text(去标签正文), fetch_date
  • ann_meta: announcement_id(pk), sec_code, sec_name, org_id, title, short_title, content(摘要原文), ann_time(epoch ms→ts), ann_type, ann_type_name, column_id, important, adjunct_url, adjunct_size, batch_num, first_seen_date
  • ann_pdf 索引(state/ann_pdf_index.parquet): announcement_id, sec_code, ann_type_name, report_year(从报告类别+公告年推), local_path, bytes, fetch_date

设计要点:id 键控、无「$today 文件名」语义——条目自带时间戳(show_time/ann_time),分区键是 发现日而非业务日,盘前跑/隔夜跑都无 0902/0904 式错标风险(与 A 档快照族的root差异)append-only 不重写(仅新条目入区,短窗 id 去重=读近 N 日分区),无 merge 改写类事故面。

18.3 采集设计:1 个脚本 + 1 个调度入口(脚本整合原则,用户追加指令②)

  • 脚本: scripts/data_platform/corpus_download.py(repo 内唯一新文件;单脚本红线同款—— corpus 栈一个入口,类型靠内部注册表,禁再开新脚本)。参数 --lane daily|backfill--until HH:MM(墙钟自停)、--limit N(手动冒烟)。
  • 调度: DSM 任务计划 sanguo-corpus-daily,每日 06:00 一条,以 admin 身份跑,机制=与 sanguo-5m 完全同款的「bash wrapper → 一次性容器」(wrapper=/volume1/stock/corpus/ run_corpus.sh,宿主文件 CI 不覆盖,改后手动同步——同 5m 的 run_5m.sh 部署纪律)。 为何 admin 而非统一 root(用户问):①03:00 链 root 属主文件坑已在案——admin scp 覆盖 root 文件 Permission denied 只能先 rm 再拉;语料库生命周期内 admin 侧操作密集(venv 装包/ 回补盯跑/删错分区/debug),admin 属主=全程零摩擦 ②最小权限:出网慢爬+写文件的进程没必要 root,出错爆炸半径小一截 ③成本为零:DSM 建任务本就选用户,不比 root 贵——统一到 root 统一 的是坏模式。存量脚本一个都不迁移(用户问「有必要全改admin吗」:没有——03:00 链等既有 root 任务照旧跑,没坏不动;admin 仅是新建 corpus 任务从第一天的选型;两套并行零冲突:目录 隔离/时间窗错开/部署管道不同,互不碰对方文件)。admin 权限逐项实测(2026-09-06): /volume1/stock 建目录/写/删全通(rwxrwxrwx+ACL,admin 属主);admin 可执行 docker 命令 (docker ps 实测通过)→ wrapper/容器/docker stop 全程 admin 可运维;读 admin 家 CI 部署 路径无障碍(初版 venv 方案及其 /tmp 坑实测,已随「统一到 5m」拍板作废,记录在 git 历史)。 设计内无任何一步需要 root;万一未来例外,人工 sudo/改任务属主是逃生门非设计依赖。 root vs admin 终局论证(用户问「root 数据不可修改的设计更好吗」):root 属主的「写保护」 是半吊子幻觉——admin 不能覆写 root 文件但能删(删看目录权限,/volume1/stock rwxrwxrwx, 03:00 链「先 rm 再拉」workaround 实证),防住原地改防不住删了重建;而 root 跑采集的代价是 全天候的——root 进程 admin 杀不动(Synology sudo 要交互密码,自动化做不了;本设计验收 含 kill -9 续跑项,root 方案连测试都无法执行)+venv 装包/盯跑全要 root 陪跑+外网爬虫拿最大 权限。不可改性交给正确工具:append-only 协议(dt=分区只追加/tmp+rename/id 键控)+ 可再生性(公告新闻都在源站,断点机制可重拉,语料=全体系唯一可完全再生的数据类);如仍需 防篡改层,验收后加 DSM 快照/每周 tar+校验和归档——对任何属主都生效,属主只是假不可变。 「root=和之前数据一致」前提实测不成立(用户追问后核查):/volume1/stock 现状=三种属主 混合——cfdaily(A股数据/minute_kline/knowledge_base 等,用户记忆中的「之前基本面数据」 恰是 cfdaily 属主而非 root)/root(03:00 链产物+sanguo_5m)/admin(_dbuild/gitea/frp 等); 且文件全 rwxrwxrwx+ACL,无任何消费方依赖属主。真正的一致在方法论层(schtask 语义/marker/ 慢爬/单脚本红线),root 与 admin 两案完全同款;唯一实质差异=运维通道(admin ssh 可杀进程/ 装 vps 包,root 全要 DSM 一次性任务或交互 sudo,自动化不可达)。终判 admin,若用户仍拍 root 亦可行,代价=venv 引导与 kill 全走 DSM 一次性 root 任务/人工 sudo。 为何独立任务而非并进 03:00 链(用户问):①失败不连坐——03:00 链=从 VPS 拉 行情的对内同步,corpus=对外 HTTP 慢爬+数小时回补马拉松,合成一条则 corpus 卡死会拖死每日 行情同步(断路器饿死同款教训,绝不复刻)②属主/部署管道不同——sync 脚本在 /volume1/stock root 地盘 CI 不覆盖须手动 scp,corpus 脚本走 CI deploy 的 repo 路径,搅进一条任务两头别扭 ③06:00 起跑避开 03:00 链跑道(26G 库同步 IO+家宽带宽),且 00 时档公告(54%)凌晨已入库, 06:00 全吃到;DSM 加一条任务代价≈零,改 root 生产链脚本才是真风险: wrapper 内部(同 5m 结构+corpus 两改进): /var/packages/Docker/target/usr/bin/docker run --rm --name sanguo-corpus --user <admin-uid> --entrypoint python -v /volume1/stock:/volume1/stock -v /volume1/homes/admin/.sanguo_projects/sanguo_vnpy_v2:/app:ro sanguo_vnpy_v2:lock-aligned /app/scripts/data_platform/corpus_download.py --lane daily 成功后同款第二发 --lane backfill --until 17:30(两 lane 串行=天然互斥;rc 聚合,任一 lane 失败 log 留痕)。--name sanguo-corpus=运维锚点:杀进程=docker stop sanguo-corpus(admin 一条命令);--user <admin-uid>=输出文件 admin 属主。镜像 tag 与主容器同源,CI 部署自动 跟随;tag 若将来基建重建改名,wrapper 跟着改(与 5m 同款注意事项)。

断点续传(用户钦点加固,所有 lane 的第一设计原则)

  • 粒度=unit(公告=(stock,year)/新闻=(stock,page)/全文/PDF=单 id),每 unit 一枚 marker(state/ 下原子写 tmp+rename);进程被杀/断电/重启后,重启即从「未标 done 的最老 unit」续跑,无任何 全局重启语义17:30 墙钟=完成当前 unit 即 checkpoint 退出,次日 06:00 自动接续。
  • daily lane 幂等可重跑(短窗 id 去重,重复执行零副作用);漏日自愈=公告 T-1~T 两天窗,新闻 recent-100 页面天然覆盖数日缺口(冷门股 100 条跨数月)——某天整个任务没跑,次日一次执行即可 补齐,不依赖专门回补。
  • 从 sanguo-5m 借鉴三件(用户问「断点续传是否一样/可否互借」后盘点 bs_5m_eod.py):① 单实例锁(bs_5m.lock pid 活性检测同款——防 DSM 定时与手动补跑撞车双进程竞写 state, corpus 原设计缺口,采纳为 state/corpus.lock)②退出码细分(对齐 5m 语义并适配: 0=完成,1=致命,2=限流让路,3=墙钟自停让路——rc 即运维信号)③state 损坏降级路径 (5m「state 坏→幂等重头无伤」思想;corpus=marker 坏→该 unit 重拉,append-only+id 去重 保证幂等无伤)。5m 反向无需借鉴改造:其整片推进粒度粗(半年片 3-4h,中断=整片重拉), 但回灌已完结、OR REPLACE 幂等无害、每日增量 LOOKBACK=7 独立自愈,改造无未来收益—— 5m 不做结构性改造,仅两个顺手项下次动 run_5m.sh 时一并(docker run 加 --name 便于 定向 stop;头注释 DSM 时点 19:05→00:05 过时修正),不专门跑。

股票池口径(用户 09-06 拍板「都按你说的来」):全 A 含退市(~5547 只),清单源=NAS 副本库 data_backup/quant_trading.db 的 distinct symbol(本地零网络、天然含退市,同 dbbardata 治幸存者 偏差原则);退市股新闻层自然为空不浪费,公告层=事件因子回测原料。PDF 类别=六类(同日拍板): 年报/半年报/一季报/三季报/业绩预告/业绩快报(≈45GB/年;权益分派/增发等不进,元数据层仍全量有)。

daily lane(每日,总 ~4.5h,06:0010:30 前后)(06:00 晨窗依据 09-06 实测:深市 600 条公告 发布时刻分布=盘中(09-15时)0%(3条)、盘后 15-20 时 46%、00 时档 54%(巨潮深夜批处理 披露)——公告主体在盘后+零点档,06:00 拉取 T+1 晨=前日公告 100% 入账,优于任何傍晚方案 (17:30 前收工的方案会漏 19-20 时 18%+00 时 54%);新闻当日条目盘中占 27%、盘后晚间 73%, 日频消费 T+1 晨拉零损失):

  1. 公告增量(巨潮,5400 req @1/s≈1.5h):每股 seDate=T-1T 两天窗+announcement_id 短窗去重 (同 margin_sse 两天窗自愈模式,漏一天次日自动补上);
  2. 新闻增量(东财 search-api=akshare stock_news_em 同款端点,~5400 req @1/s≈1.5h):带摘要, 每股最近100条,新 art_code 入 news_meta;
  3. 新闻全文(东财文章页,@2/s,~1万 req≈1.5h):仅下载昨日新发现的 art_code 正文;
  4. 当日 PDF(定期+业绩类 category 过滤,数量级 ~100-400 份/日,峰值在 4 月年报季)。

backfill lane(每日 10:3017:30 剩余时间,断点续跑,顺序=因子价值优先): ① ann_meta 全量回补(2000→今,unit=(stock,year),~19 万 req,预计 36 天跑完); ② news_meta 回补(np-listapi 标题级,unit=(stock,page),翻到空页或 page≥200 止,~11 万 req, 24 天)——历史段 summary=null 是物理上限(search-api 只有最近100条),spec 如实约定; ③ news_fulltext 回补(①②清单里的 url,@2/s,~1000万 req≈12 个月慢车道); ④ 定期+业绩类 PDF 回补(年份新→旧,2026→2000,~34 万份/~300GB,慢车道数周–数月)。 容量闸门: /volume1 实测空闲 645G(2026-09-06);PDF 回补每落 50GB 自查 df,空闲<200G 即 暂停 PDF 段并 log 告警升级用户重拍(其余段不受影响——非 PDF 段总盘子 <60G)。

失败语义(吸收 09-01/09-05 教训): fetch 失败→unit 不标 done 不写半截(parquet tmp+rename); 真空(该股该年 0 公告)→标 done 合法;确定性解析错→记日志跳过该 unit 绝不烧重试、绝不连坐后续 unit(northbound 断路器饿死教训);域名级连续传输错(403/429/超时×10)→该域本日冷却、它域继续、 rc=1 留痕,次日自然重试。

探测优先(用户追加指令①): 深度不预设上限——巨潮按年翻到空、东财按页翻到空/PAGE 硬顶为止, PDF 按可得性实下(404 标 missing 不重试);每源每股记录 first_date 入 state/depth_summary.json, 实施期边探边记,实际深度以落盘数据为准(三摸底测得:巨潮≈2000 起渐密/1993 有零星,东财≈最热股 3 年)。

18.4 预算汇总(实测口径)

增量/年 回补累计 请求量级
news_meta(标题+摘要) ~1.3GB +3 年标题级 ~1.5GB 日 ~5400;回补 ~11 万
news_fulltext ~10.6GB 3 年 ~32GB 日 ~1 万;回补 ~1000 万(慢)
ann_meta ~1.3GB 2000 起 ~15GB 日 ~5400;回补 ~19 万
ann_pdf(定期+业绩) ~45GB ~300GB(带容量闸门) 日 ~100-400;回补 ~34 万
非 PDF 合计 ~13GB/年 <60GB

18.5 验收标准(实施完成的定义)

  1. daily lane: T+1 晨抽查 5 股(超热/热/中/冷/ST)——show_time/ann_time∈[T-1,T] 的条目 全在且 id 无重复;日志限速合规(平均间隔≥设定值,零 429/403 连击)。
  2. ann_meta 回补: 600519 年报 2001 起逐年可查;announcement_id 全局无重;year×count 曲线 单调合理(早年稀疏→近年 ~130 万/年)。
  3. news 回补: 600519 最早条目落 2023-09±1 月(实测硬顶对齐);depth_summary.json 全量产出。
  4. PDF: 抽 20 份跨年份可打开(%PDF 魔数+size>0+meta 可反查路径);索引行数=文件数。
  5. 边界: /volume1/stock/corpus 之外零写入;VPS 零改动(git diff 触及面仅 scripts+tests+docs); 容量闸门演练一次(临时阈值)证明会停;主容器 restart(nas-deploy)不影响在跑的 corpus 容器 (一次性容器与主容器互不相干,5m 已实证同款);手动 docker stop sanguo-corpus 即停, 再触发从断点续跑。 5b. 断点续传: 回补中途 docker stop sanguo-corpus→重启后从未完成 unit 续跑,已完成 unit 零重拉(marker 核对);某日整个任务停跑一天→次日单次执行把漏日补齐(T-1~T 窗+recent-100 覆盖);单实例锁实证:DSM 定时在跑时手动触发→让路退出(退出码=2/3 类),双进程零竞写。
  6. 测试: tests/data_platform/ 新增 CI 测试(fetch 全 mock 零网络)——失败语义/短窗去重/ 两天窗自愈/墙钟自停/unit marker,全套本地绿+CI 绿。

18.6 非目标(明确不做)

公告 PDF 全量(用户排除);因子加工层(factor session 职责,消费接口=18.2 的 parquet 契约); 新浪任何接口;VPS 侧任何东西;正文 NLP 解析/向量化;provider 出口(消费层稳定后再议,先直读 parquet);月度 compaction(数据量小,YAGNI)。

18.7 实施步骤概要(验收通过后,TDD)

T1 wrapper+连通金丝雀(run_corpus.sh 按 5m 同款结构编写;docker run --rm --user <uid> 跑通 镜像 python+每域 1 发出网验证+目录骨架)→ T2 corpus_download.py daily lane 四段+断点续传 state 机制+单实例锁+测试 → T3 DSM 任务注册(admin 身份)+首周人工盯跑 → T4 backfill lane ①② → T5 ③④+容量闸门 → T6 验收清单执行+活文档本节补「实施终态」小节。每步一个 commit,标签 [nas](VPS 零触及)。时长预期(用户知悉):T1T3≈12 个 session 工作日;ann_meta 回补 ~1 周后即可供 factor 做事件因子回测;全文/PDF 为月级慢车道自然推进。用户已批开工 (2026-09-06「都按你说的来吧」)。

18.8 全局下载方案与存放位置总表(回应「不想搞好几套」——本节=现势唯一完整说明)

一条规则,不是几套方案:每类数据唯一权威源+唯一权威位置(§14.2 既定原则),采集发起位置 跟随权威位置——数值类(行情/估值/报表/事件面板)权威=VPS,既有任务家族不变;文本语料类(新闻/ 公告)权威=NAS(本节新增,用户三约束唯一决定:不上VPS+东财IP限流冲突+不绑docker)。两域方法论 同款:单脚本注册表红线/慢爬防封/断点 marker/schtask 语义/容量闸门。「数值类权威=VPS」有 一个在跑的例外=5min,其权威在 NAS 副本库(见下表 sanguo-5m 行)。§14.5 为 07-22 历史快照, 采集任务现势以本表为准(08-20 起 bs-eod+bs-fund 已并 sanguo-bs-daily、akshare 已拆 daily/weekly/monthly/events 三频率+ak-vintage 自检):

任务 机器 时刻 内容 权威落点
sanguo-bs-daily VPS 18:05 baostock 日线/15m/估值/财务 fund dbbardata + valuation_baostock/
sanguo-xt-eod VPS 18:40 xtdata ETF+个股当日实时 dbbardata
sanguo-idx-eod VPS 每日 指数点位 SSE 表
sanguo-ak-daily VPS 07:35 akshare 低频日更 static/
sanguo-ak-events VPS 19:30 A 档 15 类事件面板(时间守卫) static/
sanguo-ak-weekly VPS 周六 03:00 gdhs/share_capital/top_holders/northbound static/
sanguo-ak-monthly VPS 首周六 三表全量马拉松(55h 跑道) static/
ak-vintage 自检 VPS 09:00 缺日/错标防线 vintage_status.json
NAS sync 链(DSM id=2,root) NAS 03:00 VPS→NAS 副本拉取(7 域) /volume1/stock/…
sanguo-5m(DSM id=7,root) NAS 00:05 baostock 5min 增量+全量回补(独立一次性容器 docker run --rm 跑 lock-aligned 镜像,08-22 治「CI 重启主容器杀在跑任务」;窗口 2020 起,含退市 5547 只,runner=/volume1/stock/sanguo_5m) NAS 副本库 dbbardata('5m')=5m 唯一权威
sanguo-corpus-daily(DSM,admin) NAS 06:00 巨潮公告+东财新闻(本设计,一次性容器同 5m 模式) /volume1/stock/corpus/

存放位置全景:数值权威=VPS data/(dbbardata 26G+static/+valuation_baostock/), 两个例外在 NAS:①5min——权威=NAS 副本库/volume1/stock/sanguo_vnpy_v2/data_backup/ quant_trading.db 的 dbbardata('5m')(VPS 侧 '5m' 是空占位;§14.2「5min 占位/不设 schtask」 为 07-22 历史快照,08-20 起由 DSM 00:05 任务实际落地,当时未回写本文档=文档债,本表现补 ——用户 09-06 验收总表时点名找回);②语料=NAS /volume1/stock/corpus/(本设计)。 NAS 其余=数值副本(sync 链产物)+大体积历史(minute_kline/ 2.1G=cfdaily 时代外部 1min/5min/ 15min,无任务在跑,其中 1min 为全体系唯一 1 分钟粒度;A股数据/;LLM-Models 等非本项目)。 Mac=开发 fixture 无生产数据。corpus 不是第三种根——就是既有 /volume1/stock 数据根下的 新子目录,与 CLAUDE.md「NAS 部署目录」表一致。

参考(调查来源)