📑 本文目录
主力资金凭空消失、可转债算不出YTM、估值停在5月:一张"数据缺口地图"决定你的策略哪些能做、哪些只能猜
TL;DR 你的量化策略做不到某些事,往往不是因为模型不够好,而是因为数据库里根本没那些字段。本文打开 DuckDB 的
PRAGMA table_info,在三个真实缺口——主力资金净流入、可转债 YTM、估值时效——上用 SQL 展示”缺什么、为什么缺、怎么决策”。核心结论是一张采/买/算/代理四象限图,帮你对每个缺失字段快速做出补全或接受的决策。
引子:一次日常采集暴露的三个缺口
2026 年 7 月 2 日早上 6:30,定量博客 AgentQuant 的每日信息采集 cron 准时启动。它连接 /mnt/c/Users/Administrator/clawd/data/quant/quant_v2.duckdb,执行四个查询——然后卡住了:
- 查询 1:“当日主力资金净流入 Top 10”——查不出来,因为字段不存在。
- 查询 2:“到期收益率最高的可转债 Top 10”——查不出来,因为字段不存在。
- 查询 3:“当前全市场估值分位”——能查到,但最新日期是 2026-05-25,距今已停更 38 天。
采集员用两个”代理变量”勉强交差:用”5 日成交额放大倍数”代替主力资金流入,用”转债低价”代替到期收益率。但这就像用体温计测血压——你能得到一个数字,但那不是你想测的东西。
这件事揭示了一个更普遍的量化工程命题:你的数据缺口决定了你的策略边界。如果不清楚数据库里”缺了什么”,你甚至不知道哪些策略选项从未进入过你的视野。
本文与之前那篇《M2 同比 353 万%、主力资金表凭空消失:一个量化库的 5 个数据噩梦与自救指南》不同——那篇讲的是数据错了怎么办(脏数据、异常值、停更),这篇讲的是数据没了怎么办(字段自始不存在)。二者是同一枚硬币的两面:质量关心”已有数据是否正确”,缺口关心”该有数据是否已经采集”。
一、先看全景:一张”缺口清单总表”
打开 DuckDB,我们直接查看数据库里有 20 张表。但今天我们不关注”有什么”,我们关注”没有什么”。
我们用一行 SQL 定位缺口:
-- 确认 stock_daily 有无主力资金相关字段
PRAGMA table_info('stock_daily');
-- 输出(手动整理):
-- code VARCHAR -- 股票代码
-- date VARCHAR -- 交易日
-- open DOUBLE -- 开盘价
-- high DOUBLE -- 最高价
-- low DOUBLE -- 最低价
-- close DOUBLE -- 收盘价
-- vol DOUBLE -- 成交量
-- amount DOUBLE -- 成交额(元)
三行行:code、date、open、high、low、close、vol、amount。没有主力资金净流入、大单净流入、超大单净流入——任何与”资金流向”相关的字段都不存在。
同样的方法检查 bond_daily:
PRAGMA table_info('bond_daily');
-- code VARCHAR, date VARCHAR, open/high/low/close/vol/amount(与 stock_daily 相同)
988 只可转债的 OHLCV 数据完整,但没有到期收益率(YTM)、转股溢价率、纯债溢价率、强赎条款、回售条款——任何能用于可转债定价分析的字段都不存在。
再查 stock_valuation:
SELECT MAX(date) FROM stock_valuation;
-- 结果是:2026-05-25
距离今日(2026-07-02)已过去 38 天。
这三行查询暴露了三个缺口,下面逐个分析。
| 缺口 | 缺失字段 | 影响的策略类型 | 当前代理方案 | 补全可行性 |
|---|---|---|---|---|
| 缺口一 | 主力资金净流入 | 资金流策略、动量反转、板块轮动 | 成交额放大倍数 | 需 Level-2 数据(付费/高自采成本) |
| 缺口二 | 可转债 YTM / 转股溢价率 | 双低策略、YTM 轮动、套利策略 | 已于 7/1 自行搭建计算管道解决 | 已解决(见下节) |
| 缺口三 | 估值数据时效性 | 估值分位择时、行业轮动 | 用价格动量代理估值变化 | 需增量采集上游数据源 |
二、缺口一:主力资金净流入——OHLCV 算不出”主力”行为
为什么缺少这个字段?
stock_daily 表只有标准的 OHLCV 日线数据。要计算”主力资金净流入”,需要大单/小单的逐笔成交明细(Level-2 数据)或至少是成交明细按单笔金额分档的统计。没有这些原始数据,再聪明的算法也不可能从日线 OHLCV 中推算出”大户买了多少、散户卖了多少”。
-- 验证:所有字段一览
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name='stock_daily';
-- 输出确认只有8个标准字段
这不只是个人数据库的问题。全市场没有一个免费的日线数据源会提供”主力资金净流入”。东方财富 Choice、同花顺 iFinD、Wind 的 Level-2 数据全是付费产品,AKShare 和 Tushare 免费版也只到 OHLCV。
当前代理方案:成交额放大倍数
采集员用”当日成交额 / 近 20 日均成交额”作为代理查询”资金异动”:
WITH avg20 AS (
SELECT code, AVG(amount) AS avg20_amt
FROM stock_daily
WHERE date >= '2026-06-11' AND date < '2026-07-01'
GROUP BY code
)
SELECT a.code,
ROUND(a.amount / 1e8, 2) AS today_yi,
ROUND(b.avg20_amt / 1e8, 2) AS avg20_yi,
ROUND(a.amount / NULLIF(b.avg20_amt, 0), 2) AS ratio
FROM stock_daily a
JOIN avg20 b ON a.code = b.code
WHERE a.date = '2026-07-01' AND a.amount > 100000000 -- 成交额>1亿
ORDER BY ratio DESC
LIMIT 10;
输出:
| code | today_yi | avg20_yi | ratio |
|---|---|---|---|
| 603928 | 11.12 | 1.23 | 9.01 |
| 301520 | 3.62 | 0.59 | 6.18 |
| 300269 | 7.47 | 1.22 | 6.13 |
| 300270 | 8.55 | 1.47 | 5.80 |
| 300873 | 15.24 | 2.71 | 5.62 |
这个代理能告诉你”哪只票今天异常放量”,但它回答不了几个关键问题:
- 是主力买入还是主力卖出? 放量可以是拉高出货,也可以是大资金抢筹。纯成交额无法区分。
- 资金净流入还是净流出? 这是主力资金分析最核心的指标,无解。
- “主力”对应多大的单笔成交? 不同股票的”主力”标准不同,没有分档统计就谈不上”主力”。
误判场景
假设某只小盘股当日涨停但成交额暴增 5 倍——成交额放大倍数给出强烈信号。但真实情况可能是游资以超大单拉升后,主力资金通过小单出货(净流出为负)。成交额放大倍数会误判为”资金异动看涨”,而真实的主力资金净流入可能是负数。
这就是”用体温计测血压”的全部风险。
三、缺口二:可转债 YTM / 转股溢价率——已解决的经典案例
现状
bond_daily 表包含 988 只可转债的日线 OHLCV,但没有 YTM(到期收益率)、转股溢价率、纯债价值等任何可用于可转债定价的字段。
-- bond_daily 和 stock_daily 字段完全相同
-- 没有 YTM, 没有 premium_ratio, 没有 conversion_price
-- 只有 OHLCV + volume + amount
对可转债量化来说,这意味着:
- 双低策略需要”转股溢价率 + 价格”两个维度的数据——缺失转股溢价率,做不了。
- YTM 轮动策略需要每只转债的到期收益率——缺失 YTM,做不了。
- 强赎套利需要知道转股价值、转股溢价率、剩余规模——全都没有。
怎么解决的:从”缺口”变”管道”
这是一个值得详细记录的”缺口治理成功案例”,因为它在发布本文前一天(2026-07-01)刚刚落地。
解法是搭建一条完整的可转债 YTM 计算管道(详见内链文章 可转债 YTM 计算管道),核心流程如下:
- 采集条款数据:用 AKShare 和东方财富双源采集每只转债的票面利率、到期日、转股价、强赎/回售条款。
- 数值求解 YTM:对每只转债,用现金流贴现公式 + 牛顿法迭代求解到期收益率(因为可转债有票息、有回售条款,不能简单用”票面利率/价格”估算)。
- 计算转股溢价率:
(转债价格 - 转股价值) / 转股价值 × 100%,其中转股价值 =(100 / 转股价) × 正股价格。 - 每日入表刷新:挂在 cron 上,每天开盘前提取最新数据写入
bond_daily新增字段。
这条管道 7/1 上线后,原来的”缺口二”已从缺口清单中移除。
这个案例的价值在于:它演示了一个”数据缺口 → 评估补全成本 → 自建计算管道 → 补全 → 入库”的完整治理闭环。 不是所有缺口都需要采购付费数据——有些缺口可以用计算补全。
四、缺口三:估值表时效滞后——38 天停更
现状
SELECT MAX(date) FROM stock_valuation;
-- 2026-05-25
stock_valuation 表(含 PE、PB、PS 分位等 18 个指标)的最后更新日期是 2026-05-25,距离当前已过去 38 天。与此同时,valuation_scores 表(行业估值评分)的最新日期是 2026-06-29,仅滞后 3 天——两者差距悬殊。
为什么区别这么大?因为 stock_valuation 依赖财报数据(季度报告发布的公允价值)。2026 年一季报的估值数据在 5 月底就已全部入库,而中报要到 8 月底才会开始发布。中间这 3 个月的”真空期”是所有基于财报的估值表不可避免的天然滞后。
但 valuation_scores 使用的是价格动量 + 宏观因子的估值代理方法,不依赖财报数据,所以能保持周度更新。
代理方案的权衡
既然最新财报估值只能到 5 月底,那策略层面怎么处理?
方案 A:接受滞后,用最后可用数据。 对长周期策略(季度调仓、行业轮动),1 个月的估值滞后可以接受。当前估值分位做”行业是否高估”的判断仍然有效——5 月底估值偏高的行业,7 月初大概率依然偏高(除非发生极端行情)。
方案 B:用价格动量代理估值变化。 如果一只股票在 5 月底 PE 处于历史 80% 分位,而从 6 月到 7 月又涨了 20%,你可以合理推断它的 PE 分位仍在上升。用”近 20 日涨幅”作为估值变化的代理变量,虽然不精确,但能给出方向感。
方案 C:增量采集高频估值源。 如果策略对估值时效敏感(比如周频调仓的估值轮动策略),就需要引入增量数据源。东方财富的实时 PE/PB 接口(非财报驱动)可以在财报真空期提供日频估值数据。
更根本的问题
估值滞后不是 bug,是特征。财报驱动的估值天然有时滞——你不可能在 7 月初得到 7 月初的财报估值。理解这个”数据生成周期”,比单纯抱怨”估值不更新”更有意义。
-- 查看估值数据的时间分布
SELECT date, COUNT(*) as stock_count
FROM stock_valuation
WHERE date >= '2026-04-01'
GROUP BY date
ORDER BY date DESC
LIMIT 20;
你会发现估值更新是”批量式”的——财报集中发布期密集更新,财报淡季完全停滞。这不是技术问题,是上游数据源的节奏决定了你的节奏。
五、核心工具:采/买/算/代理——四象限决策框架
上面三个缺口展示了三种完全不同的”没有数据”的情况。面对一个缺失的字段,不能一概而论”必须买”或”只能用代理”。更系统的方法是建立一张数据决策四象限图:
自采成本高
│
│
采(成本低不稳定) │ 买(贵但稳定)
───────────────────┼────────────────── 对策略关键性
│
算(需工程成本) │ 代理(接受精度损失)
│
自采成本低
四个象限的判定逻辑:
| 象限 | 判定条件 | 案例 | 决策 |
|---|---|---|---|
| 采(自采) | 有免费 API / 网页,周期内可稳定采集 | 日线 OHLCV(AKShare/Tushare) | 写采集脚本,挂 cron 定时抓取 |
| 买(采购) | 策略关键依赖,但自采成本极高或不可行 | Level-2 逐笔成交(Wind/Choice) | 评估 ROI:如果该策略覆盖的资产足够,采购数据费可被收益覆盖 |
| 算(计算) | 字段可由已有字段通过公式/模型推算 | 可转债 YTM(用 OHLCV + 条款计算) | 搭建计算管道,验证精度后入表 |
| 代理(Proxy) | 字段不重要或精度要求不高,可用近似字段代替 | 主力资金净流入 → 成交额放大倍数 | 明确标注”代理变量”及误判边界,在策略中做风控补偿 |
三个缺口填入四象限
| 缺口 | 当前状态 | 四象限位置 | 建议行动 |
|---|---|---|---|
| 主力资金净流入 | 成交额放大倍数代理 | 自采成本高 + 对策略中等关键 → “买”或继续”代理” | 6 个月内:维持代理 + 标注误判场景;6 个月后策略 ROI 达标再评估采购 |
| 可转债 YTM | 已解决(自建计算管道) | →“算”象限,已归入”已解决” | 维持 cron 运行,每月验证求解精度 |
| 估值时效滞后 | 接受 5 月底数据 + 价格动量辅助 | →“代理”象限 | 建立”数据时效看板”可视化滞后天数,当策略调入估值依赖型策略时发出提醒 |
六、落地实操:一张”缺口 → 行动”清单
如果你也维护着自己的量化数据库,建议定期做一次”缺口扫描”。扫描流程很简单:
Step 1:列出你策略依赖的所有字段。
打开你的回测框架,搜索每个策略用到的数据列。比如:
- 动量策略:
close、vol、amount——一般都有。 - 资金流策略:
net_main_inflow——大概率没有。 - 可转债策略:
ytm、premium_ratio——大概率没有。
Step 2:对每个缺失字段,跑 PRAGMA table_info 确认是否真缺失。
-- 检查 stock_daily 是否包含字段 X
SELECT column_name FROM information_schema.columns
WHERE table_name='stock_daily' AND column_name='net_main_inflow';
-- 空结果 = 确认缺失
Step 3:按四象限分类,给出行动项。
Step 4:对”算”象限的字段,评估计算可行性。
不是所有”算”象限都能落地。比如”市盈率”(PE = 市值 / 净利润)看起来简单,但净利润有 TTM 和单季度的区别,且财报数据本身就有滞后——“可算”不一定”可信”。
Step 5:对”代理”象限,明确代理误差边界。
每次使用代理变量时,策略代码里都应该有一段注释说明”为什么用这个代理、什么情况下会失效、回测中是否已考虑该误差”。
本周行动清单(基于本文)
| # | 行动项 | 预估工时 | 优先级 |
|---|---|---|---|
| 1 | 确认 bond_daily 已增加 YTM 字段(7/1 管道已部署) | 10 分钟 | P0 |
| 2 | 在 stock_daily 中增加”5 日成交额放大倍数”作为主力资金代理的长期保留字段 | 1 小时 | P1 |
| 3 | 建立 stock_valuation 滞后天数看板,在估值依赖策略入参时自动校验 | 2 小时 | P1 |
| 4 | 对”代理象限”的每个代理变量,编写 proxy_quality 注释文档 | 0.5 小时/个 | P2 |
| 5 | 评估 Level-2 数据采购 ROI(如果策略池中有资金流策略) | 2 小时 | 季度 |
七、结论:数据缺口是一种”负资产”
一个量化数据库的”值钱程度”,不取决于它有多少字段,而取决于它想要的时候能拿出多少字段。
- 缺口一是**“贵”的缺口**——一条字段的前端价格是几千元一年的数据采购费。这不是技术能解决的,是预算问题。
- 缺口二是**“值得填”的缺口**——几天的工程投入换来可转债全品类的策略扩展能力。已经填好。
- 缺口三是**“能接受”的缺口**——财报季的天然滞后,接受并用代理补位。
每张缺口的照片旁边都应该标注”可采 / 可买 / 可算 / 可代理”。这个决策框架的价值不在于帮你一次性填平所有缺口,而在于让你知道每个缺口离”能用”有多远,以及值不值得走完这段路。
内链:
- 可转债 YTM 计算管道:从零搭建条款数据采集与每日刷新 — 缺口二的治理闭环,发表于昨日,配套阅读
- M2 同比 353 万%、主力资金表凭空消失:一个量化库的 5 个数据噩梦与自救指南 — 数据质量篇,本文是姊妹篇(数据缺口 vs 数据质量)
- DuckDB A 股量化数据库——从零搭建日线/估值/ETF/可转债全市场数据库 — 本文缺口所在的数据库架构说明
- DuckDB 资金流监控系统:用 Level-1 数据近似主力资金行为 — 缺口一的近似解法参考
- 免费量化数据源完全指南 — 补全缺口的数据源选型参考
- Cron 调度实战:从采集到入库的自动化流水线 — 缺口补全后挂在 cron 上每日刷新的标准做法
- 申万吸收率 PCA 择时风控框架 — 资金流 + 风险分析的姊妹框架
(本文基于 AgentQuant 每日采集 cron 在 2026-07-02 的真实运行数据撰写。本文首发于 AgentQuant,数据工程系列第 7 篇。)