采集层(多源各下): - baostock: 日线全字段全量(baostock_daily_fullmarket) + 15min全市场 + 静态(基础/复权/分红/季频/三表) + 成份股 - akshare: 静态(估值/龙虎榜/大宗/融资融券/北向/指数成分/行业/股本/解禁/业绩预告) - xtdata(miniQMT): build_daily_from_xtdata + daily_update_xtdata 数据补全 P0: - ETF全市场: universe 扩展 沪深A股∪ETF∪基金(7414), dividend_type='front' 前复权 - 历史成份股(治幸存者偏差): index_const_hist_download 深证/国证 adjust_cni 4指数 + 中证1000/2000快照 + 新浪交叉校验 - 退市K线: baostock_delisted_download + import_delisted_to_db(实证 Day1 fetch_all_stocks 已含退市) 灌库: - import_baostock_to_db: daily_baostock_full(5537股/1826万行,18字段)+ bs_index_constituent + bs_adjust_factor - INSERT OR REPLACE 幂等, WAL+busy_timeout, dbbardata 不碰 每日增量 #7(用户决策A: VPS直跑): - daily_update_static: login探针防黑名单graceful skip + LOOKBACK7 + query_stock_basic含退市 + INSERT OR REPLACE + QUERY_COUNT守48000/天 设计文档: spec(13节三层融合) + P0 plan + 数据gap设计
4.2 KiB
LocalParquetProvider V1 数据缺口记录
V1 已通过 VPS 真实数据验证(2026-07-21): fundamentals 字段值合理(茅台市值 18433亿/PE 23.6/ROE 0.19/净利率 0.51)、 get_price/get_index_stocks/trade_days/all_securities 全通、B_mean 趋势信号正常、 回测出完整 JSON(117 交易日, 0.4s/月, 无 baostock 卡死)。
0 交易根因(非 provider bug):
_pick_big_universe选股 target=[] =bigfilter 8 条件 AND 过严 +roic_big用 roic(V1 NaN) + bm market_cap 100-900亿 不匹配 hs300 大盘 + B_mean<0 时兜底海外 ETF(无 K 线)。补 roic + 调 filter 阈值即出交易。以下缺口不阻塞 MVP 链路验证,但全市场正式回测前需补齐。
缺口 1: 历史成分股(治幸存者偏差,重要 ⚠️)
现状: VPS static/index_const/index_const.parquet 仅 2026-07-17 最新一期快照。
get_index_stocks(index, date) 的 date 参数当前被忽略(无历史数据可读)。
影响: 回测 2020 年选股池 = "现在还在 hs300/zz500 里的股票" → 幸存者偏差(结果虚高)。
max_pool 小范围验证影响相对小(只取前 N 只),全市场轮动回测前必须补。
补齐方案(任选,不用 baostock online):
- akshare
index_stock_cons_csindex(symbol="000300")按调仓日拉历史成分(csindex 源) - 中证指数官网 csindex.com.cn 历史成分下载
- 用户侧(数据补全 session)补到
static/index_const_history/多期 parquet, provider 加日期过滤
缺口 2: gross_profit_margin(V1 NaN)
现状: akshare income 表无明确"营业成本(COGS)"列(有 OPERATE_INCOME 营收、OPERATE_EXPENSE 营业总成本,但非纯 COGS)。
V1 gross_profit_margin 置 NaN,策略 filter 该阈值失效(不过滤毛利率)。
补齐方案: 从 static/financial_abstract/{code}_*.parquet 读现成"销售毛利率"
(宽表 指标×季度,含 1990-2026)。解析:找指标行"销售毛利率",取最新季度列。
缺口 3: roic(V1 NaN)
现状: ROIC = NOPAT / (权益 + 有息负债 - 现金),需有息负债拆分。 V1 置 NaN。balance 表有 BORROW_FUND/BOND_PAYABLE 等字段可算。
补齐方案: balance 读 BORROW_FUND(短期借款) + BOND_PAYABLE(应付债券) + SUBBOND_PAYABLE
- 现金(CASH_DEPOSIT_PBC 附近字段),算 roic。NOPAT = 营业利润 ×(1 - 税率)。
V1 单位口径备忘(VPS 实测验证合理 ✅)
| 字段 | VPS 源单位 | 转换 | 验证值(2024-06) |
|---|---|---|---|
| market_cap | 总市值(元) | /1e8 转亿 | 茅台 18433 亿 ✅ |
| circulating_market_cap | 流通市值(元) | /1e8 | ✅ |
| pe_ratio | PE(TTM) 数值 | 直接 | 茅台 23.6 ✅ |
| pb_ratio | 市净率 数值 | 直接 | 茅台 7.69 ✅ |
| ps_ratio/pcf_ratio | 市销率/市现率 | 直接 | ✅ |
| eps | BASIC_EPS 元 | 直接 | 茅台 33.19 ✅ |
| roe | 归母净利润/归母权益 | 小数(单期非TTM) | 茅台 0.19 ✅ |
| roa | 净利润/总资产 | 小数 | ✅ |
| net_profit_margin | 归母净利润/营收 | 小数 | 茅台 0.51 ✅ |
| inc_revenue_yoy | OPERATE_INCOME_YOY 百分数 | /100 | 茅台 +0.18 ✅ |
| total_liability | TOTAL_LIABILITIES 元 | /1e8 | 浦发 85000 亿 ✅ |
| total_sheet_owner_equities | TOTAL_PARENT_EQUITY 元 | /1e8 | ✅ |
| retained_profit | SURPLUS_RESERVE+UNASSIGN_RPOFIT | /1e8 | ✅ |
VPS 两种代码格式(已适配,备忘)
VPS data/ 下代码格式不统一:
- K 线
qfq/{年}/raw/{年}/: baostock 风格sh600000_daily.parquet(sh/sz 前缀无点) →jq_to_kline_code("600000.XSHG") = "sh600000" - 三表/估值
static/{table}/: jq 后缀000001.SZ_balance.parquet→jq_to_file_code("000001.XSHE") = "000001.SZ"
get_price 用 jq_to_kline_code,get_fundamentals_df 用 jq_to_file_code。
V1 已验证可用的接口
| 方法 | 状态 | 备注 |
|---|---|---|
| get_price | ✅ | qfq 日线, 单股 index=date / 多股 panel |
| get_fundamentals_df | ✅ | 19 列对齐 _FUNDAMENTAL_COLUMNS, 字段值合理 |
| get_security_info | ✅ | valuation 最新行 |
| get_trade_days | ✅ | sh600000 K 线 date 列 |
| get_all_securities | ✅ | 5528 股 |
| get_index_stocks | ⚠️ | 仅当前快照(缺口 1) |
| get_current_tick | ✅ | valuation 推算 close + 涨跌停(主板±10%) |
| get_split_dividend | ✅ | 占位返空(qfq 已复权) |