39 KiB
量化因子导出与合成设计(v2.0,2026-07-26)
一句话:把 astock-kg 知识图谱的产业理解,做成一个自洽的、有经济含义的 景气度选股因子
akg_score,托管在通用因子管理平台quant_factor_service里(本文只用其注册 / 存储 / 调度 / 评价能力,不用其合成能力,理由见 §2); 因子的合法性来自产业逻辑,不来自历史 IC 拟合。本版是对 v1.1 的方向性修订,不是增补。 v1.1 的核心方案(四路子因子对称注册 → 平台 ElasticNet/贝叶斯/GRU 拟合出复合因子)已被推翻,理由见 §2。v1.1 中的 数据契约、视图定义、子因子构造口径、平台接口细节仍然有效,本版继承并更新(§5、§6)。
版本号约定(避免歧义):
v1.1 / v2.0指本设计文档的版本;因子自身的演进阶段 一律用 S1 / S2 / S3 表示(S1 = 首个上线版本)。
0. 版本变更与决策基线
0.1 v1.1 → v2.0 的三处推翻
| 项 | v1.1 | v2.0 | 触发原因 |
|---|---|---|---|
| 复合方式 | 平台拟合合成(ElasticNet/贝叶斯基线,GRU 三头为目标) | 桥内自洽公式(漏斗),平台不参与合成 | 拟合要求全部输入可回填、且历史上与收益共变;传导两者都不满足 |
| 四路地位 | 四路对称,权重由拟合决定 | 两道硬门槛 + 三项加权,权重由投资逻辑指定 | 「c 应该是硬门槛……传导第一、还没热第二、便宜第三」 |
| 回测角色 | 生死闸(神经 IC-IR 超线性基线才判收) | 仪表盘(持续观测,不做 go/no-go) | 「核心是这个值有其合理性和经济含义在,那么大方向肯定不会是错的」 |
0.2 v2.0 决策基线
| 议题 | 决定 | 理由摘要 |
|---|---|---|
| 承载形态 | 独立 akg-factor-bridge 工程(Docker,可单独部署) |
基座只暴露只读视图,桥消费视图+热度、写平台;三方镜像都保持纯净 |
| Universe | astock-kg 覆盖池(industry_pools 全主题成员并集),实测 1675 只 |
池内信号厚;实测规模足够做截面统计 |
| 复合因子 | akg_score = 景气度漏斗,桥内计算,注册为 single(平台视角它就是一个普通因子) |
自洽公式的产物不是"平台合成结果",不占 multiple 语义 |
| 赛道范围 C | 十五五规划前沿赛道产业链(核聚变、商业航空航天、通信、算力、人工智能、低空经济等;材料 → 设备/零部件 → 制造/系统集成 → 应用/服务,全链) | 划定范围,不做计算——范围本身就是确定性来源 |
| 传导 | 只 live 使用,不回填、不进拟合 | 传导是推断不是观察,回填必然引入前视(§2.2) |
| 评价 | 复用平台 ic_calculator + 分层回测,当仪表盘看 |
复用平台的目的就在评价与调度,但不让它当判官 |
| 开发规范 | 全流程 Docker(构建/运行/连库/psql 一律走容器) | 团队铁律 |
1. 投资论题:为什么是"景气度漏斗"
这一节是全文的地基。因子的每一项都能追回到这里的某一句话;若论题变了,因子该重做。
主线判断。 A 股乃至全球股市未来三五年的主线是科技。这条主线会在 AI 渗透率接近 2015 年移动互联网渗透率、AI 变成某种公用服务或基础设施之后终结——那时它才会像新能源 或制造业那样"可研究"(业绩稳定、能做确定性高的预测)。在此之前,它不可研究。
不可研究意味着什么。 具体到方法论,处在这个阶段的赛道有三个特征:
- 大方向向上——产业趋势本身没有分歧,政策与产业资本都在推;
- 无法准确估值——收入曲线还没定型,DCF/PE 给不出可信中枢;
- 没有另类领先数据——不像制造业有订单、排产、开工率可以先行跟踪。
三条同时成立时,自下而上的基本面精算是无效的(算不准),量价动量是滞后的(等确认 就已经在右侧了)。剩下唯一可行的办法是景气度投资:不追求算准,只追求 方向对 + 位置早 + 价格不离谱。
落到选股上,就是找两类特征的交集:
- 确定性高——确定性不来自盈利预测,来自产业逻辑:它在不在国家级主线上、 在产业链上占什么位置、这个位置有没有壁垒。
- 相对较便宜——不是绝对估值便宜,是相对于预测的空间还在。因为系统赌的是 大方向正确,必须给自己留容错度;贵了就没有容错度了。
热度在这里的真实作用。 单一股票的热度本身没有太大意义。它的价值在于 辅助验证产业传导逻辑是否已经启动——用来缩短左侧建仓的时间和风险。所以热度 不是一个独立的 alpha 来源,它是传导逻辑的确认器与位置指示器: 板块层面已启动(传导给出),个股层面还没热(热度给出)= 左侧位置还在。
注:S1 的实现把"还没热"落成了一个独立加性项而非条件项,这是一处有意的简化, 代价与备选方案见 §3.4 与 §9-9。
研报滞后的再解释。 硬科技赛道的特征是壁垒高、投入大、业绩分化、生态站位分工 明确。券商研报覆盖这类标的天然滞后。在一个看预期的市场里,滞后本身反而是确定性的 体现——研报开始密集覆盖时,产业逻辑已经被验证到了能写进报告的程度。所以我们不把 "研报少"当成信息缺失来惩罚,而是把"研报所指的赛道"当成一个已经通过验证的范围来使用。
2. 方法论转向:从"拟合合成"到"自洽公式"
2.1 原方案为何走不通
v1.1 的设想是把四路信号当成对称的特征喂给平台的合成引擎(ElasticNet 滚动 / BayesianRidge / GRU 三头),让模型学权重。三条独立的理由否决了它:
(一)实证否决。 单纯的 heat 与其他因子的合成结果此前并不理想。这不是调参问题, 是"把热度当 alpha 源"这个前提本身站不住——热度既可能是动量也可能是拥挤反转,符号不 稳定,模型学到的权重会随窗口反复翻转。
(二)数据本身有系统性偏差。 上升空间本质上是券商报喜不报忧的预测。它作为 一个"还有多少空间"的相对标尺是可用的(这也是为什么它留在漏斗里当门槛),但作为一个 待拟合的自变量,它携带的偏差是结构性的、不随样本增加而消失的。
(三)传导根本进不了拟合模型。 这是决定性的,展开在 §2.2。
2.2 观察 vs 推断:一个必须区分的类型学
四路信号看起来同构(都是"每股每日一个数"),但它们的认识论地位不同:
| 维度 | 观察(observation) | 推断(inference) |
|---|---|---|
| 定义 | 世界上发生了某件事,被带时间戳地记录下来 | 系统在某一天,用当天的状态推出的一个判断 |
| 本例 | 事件(disclosure_date)、热度(上游历史留存)、预期空间(研报 asof_date) |
板块传导(scan_date) |
| 历史 | 有耐久历史,重放可复现 | 无耐久历史,过期即不可复原 |
| 回填 | 可回填,点时正确 | 回填 = 前视 |
传导为什么是推断。 传导候选 = 当日异动集(movers)× 当时的产业链图谱。两个输入
都没有耐久历史:历史每日的 hotspot 异动集没有留存;产业链图谱是随研报持续生长的
当前态,industry_pools 只存最新快照、没有时点版本。
于是若要重建 2024 年某日的传导,只能用今天的图谱去套 2024 年的行情——而今天的 图谱里,有大量关系是 2025、2026 年的研报才写进去的。这是教科书式的前视偏差: 回填出来的历史传导会"提前知道"后来才被发现的产业链关系,其历史 IC 必然虚高,而这个 虚高恰恰无法在样本外复现。
推论。 任何需要"历史上该特征与收益共变"的方法——线性回归、贝叶斯、GRU,无一例 外——都无法把传导纳入。不是因为传导没用,恰恰相反,是因为传导是我们唯一真正原创 的信号,而它天生不可回测。
神经网络能否豁免? 不能。常被误解的一点是"神经网络不要求因子为正、有信息即可" ——这句话本身对(A 股利好往往是大跌的开始,符号确实无所谓,模型可以学到负向使用)。 但它要求的是该特征在样本内相对结果有过变化。传导没有可信的样本内历史, 模型面对的是一列几乎全空、仅最近三天有值的特征,只会把它的权重压到零。
2.3 转向:自洽公式
既然最有价值的信号无法进拟合,就不要为了迁就方法而丢掉信号——换方法。
因子化仍然是必须的,也必须通过现有因子管理平台托管;但未必要通过平台的合成方案。 如果系统自己能用自洽的方案算出这个值,那么:
- 合法性来源改变:从"历史 IC 显著"改成"这个值有其合理性和经济含义"。
- 回测不再是前置条件:甚至不需要马上回测。核心是这个值经济含义成立, 那么大方向肯定不会是错的——这是我们追求的。
- 回测降为仪表盘:仍然做、仍然看、仍然复用平台的
ic_calculator和分层回测, 但它输出的是"当前市场是否在奖励这套逻辑"的读数,不是"这个因子该不该活"的判决。
这个转向还有一个附带好处:公式的每一项都能被人读懂、被人质疑、被人调整。拟合出来的 权重做不到这一点,而在一个我们明确承认"无法准确估值"的领域里,可解释性比精度更重要。
3. 复合因子 akg_score:景气度漏斗
3.1 结构
KG 覆盖池 U(industry_pools 全主题并集,实测 1675 只)
│
┌─────────────────▼─────────────────┐
│ 硬门槛 ① 赛道 C │ 十五五前沿赛道产业链成员
│ 材料→设备/零部件→制造/系统集成→应用 │ —— 划定范围,不计算
└─────────────────┬─────────────────┘
│
┌─────────────────▼─────────────────┐
│ 硬门槛 ② 估值 V │ upside ≥ θ_v(贵了不买)
│ (留容错度) │ —— 一票否决
└─────────────────┬─────────────────┘
│
候选池 P_t
│
┌─────────────────▼─────────────────┐
│ 池内加权排序(截面标准化后加权) │
│ w_T · z(传导) ← 第一,最重 │
│ w_H · z(−热度) ← 第二,还没热 │
│ w_V · z(便宜) ← 第三,再加权 │
└─────────────────┬─────────────────┘
▼
akg_score(写平台因子表)
为什么是漏斗而不是加权和。 加权和允许"某一项极好补偿另一项极差"——在这套逻辑里 这恰恰是灾难:一个不在赛道上的股票传导分再高也不该买(传导的经济含义依附于产业链 的真实性),一个贵到没有容错度的股票赛道再正也不该买。硬门槛表达的是"不可交易", 权重表达的是"更值得先买",两者不能混为一谈。
3.2 硬门槛 ① 赛道 C(定义域,非计算量)
定义:C(i) = 股票 i 属于十五五规划前沿赛道产业链的任一环节。
赛道清单以十五五规划确定的前沿领域为准,已明确的包括:核聚变、商业航空航天、通信、
算力、人工智能、低空经济等(完整清单待补,见 §9-2)。每个赛道按上下游全链取,
layer 统一四层枚举:材料 → 设备/零部件 → 制造/系统集成 → 应用/服务。
这是本设计最重要的一步:C 是一个被划定的范围,不是一个被计算的分数。
理由(用户裁定):所谓硬科技赛道本身就是壁垒高、投入大、业绩分化、生态站位分工 明确。这些属性一旦成立,赛道内标的的"确定性"就已经由产业结构提供了,不需要再用 数据去打分——打分反而会把结构性的确定性稀释成一个可被其他项补偿的连续量。 这也与 astock-kg 的"不打分"铁律一致:系统负责把范围划清楚,不负责给股票评级。
实现路径(桥内新增模块 tracks.py + 配置 config/frontier_tracks.yml):
# 示意结构,实际清单待 §9-2 确认
tracks:
- name: 商业航空航天 # 正式名唯一,别名进 aliases
aliases: [商业航天, 航天科技]
kg_themes: [...] # 映射到 industry_pools 主题名
kg_segments: [...] # 映射到环节(材料/设备/制造/应用)
kg_concepts: [...] # 映射到概念标签
- name: 低空经济
...
成员表落在哪里(归属):yml 是唯一事实源,随桥仓库版本控制;映射产物物化为
track_members(列:ts_code, track, layer, source_rule, updated_at),落在桥工程
自身的 data/ 目录下的版本化快照文件(CSV/Parquet,可 git diff),不落基座、
不落平台——这样既不破坏 §4 的三层边界,又满足"必须能被人逐条 review、能被 diff、
能追溯某只股票凭什么进来"的审计要求。若日后下游需要 SQL 查询,再另议是否落库。
关键前置风险:C 是一次图谱成员性测试,它成立的前提是 astock-kg 的图谱真的覆盖 了这些赛道。通信 / 算力 / 半导体大概率已覆盖;核聚变、低空经济、商业航空航天的 覆盖情况未知。因此 G1 里程碑的第一件事是赛道覆盖体检(§8),体检结果决定 S1 先 上哪几个赛道——覆盖为空的赛道宁可先不放进来,也不要放一个空集合进公式。
3.3 硬门槛 ② 估值 V(贵了不买)
定义:V(i,t) = akg_upside(i,t) ≥ θ_v。
θ_v 的口径:θ_v = max(0, 池内 upside 的 q 分位),默认 q = 0(即退化为
θ_v = 0:一致预期目标价中枢不低于现价)。绝对下限 0 不可让渡——它是"容错度是否
真的存在"的物理判据;分位数只用于在此之上进一步收紧,绝不用于放行 upside 为负的
标的。q 的取值见 §9-3。
为什么必须是硬门槛而不是扣分项:系统的算法本质是"大方向正确",精度有限, 必须给自己留下容错度。容错度的物理载体就是价格与预期中枢之间的空间。空间为负时, 即便产业逻辑完全正确,也已经没有犯错的余地了——这时不是少买一点的问题,是不该买的问题。
已知偏差:upside 来自券商一致预期,天然报喜不报忧,绝对水平偏乐观。作为截面 相对标尺它仍可用(乐观偏差在覆盖股之间大体同向);若实测发现 θ_v = 0 几乎筛不掉 任何股,就靠上调 q 来收紧,而不是放弃这道门槛。
缺失处理:upside 为 NaN(无券商覆盖)= 不通过门槛。这是保守选择: 没有覆盖就没有容错度的度量,宁可漏不可错。代价是牺牲一部分真正冷门的早期标的 ——这个代价与"研报滞后是确定性体现"的论题有张力,列为 §9-4 待议。
3.4 门槛内的三项加权
在候选池 P_t 之内(标准化只在池内做,池外样本不参与统计量估计):
| 项 | 构造 | 默认权重 | 语义 |
|---|---|---|---|
| 传导 z_T | (log1p(akg_transmission) − mean) / std |
0.50 | 产业逻辑正在向该环节传导——最硬的买入理由 |
| 还没热 z_H | −1 × robust_z(akg_heat)(中位数/MAD) |
0.30 | 个股尚冷 = 左侧位置还在(见下方"退化说明") |
| 便宜 z_V | robust_z(akg_upside)(中位数/MAD) |
0.20 | 过了门槛之后,空间越大越优先 |
\text{akg\_score}_t(i) = w_T \cdot z_T + w_H \cdot z_H + w_V \cdot z_V,\quad
i \in P_t$$
**权重次序由投资逻辑指定**(传导第一、还没热第二、便宜第三),不由拟合决定。
0.5/0.3/0.2 是满足该次序的一组默认值,是**旋钮不是结论**;调整它需要的是逻辑上的
理由,不是回测上的理由。
**"还没热"的退化说明(必须写明的一处妥协)**:§1 里热度的定位是**条件性**的——
只有在传导已确认板块启动的前提下,"个股尚冷"才等于"左侧位置还在"。但 S1 把它实现
成了**无条件加性项**,后果是:传导为 0 的股票只要够冷,仍然能拿到 0.30 权重的正分,
此时该项退化成一个**独立的反拥挤/低关注度因子**,与 §1 的"确认器"定位脱钩。
接受这个妥协的理由是:赛道硬门槛已经保证了标的的产业地位,在**已经确定是好赛道**的
池子里,"冷"更可能意味着"还没被发现"而非"基本面差",所以退化后的语义仍然可辩护。
备选实现(条件项 `z_H · 1[z_T>0]`、或交互项 `z_T · z_H`)列为 §9-9,S2 再评估。
**几个必要的技术处置:**
- **截面标准化是自洽性的前提,不是可选项**。三项量纲完全不同(传导是"路径数 × 空间
比例"的乘积量、热度是 0~1 分、upside 是收益率),不标准化则权重毫无意义。
**热度项与便宜项**采用池内**稳健标准化**(中位数 / MAD,对齐平台
`MathKernel.winsorize_mad` 的处置口径),避免少数极值主导。
- **传导项例外:不能用 MAD**。传导在池内约 **95% 为 0**(覆盖池内单日仅 83 行有值),
此时 `median = 0` 且 **`MAD = 0` → 除零**。传导项改用非稳健口径
`z_T = (log1p(x) − mean) / std`;`std = 0`(当日池内无任何传导)时整列置 0。
先 `log1p` 是为压长尾,避免单只票的极端路径数吃掉整个排序。
- **传导缺失 = 0,即"取基准值",不是剔除**。标准化后 0 会落在池内均值**之下**,
等价于对有传导者的相对加分——这正是想要的:传导项实质是**稀疏加分**而非连续排序,
少数被产业逻辑点名的票被显著抬升。若把传导设为必需项,候选池会塌缩到每日几十只
以下,既失去组合意义也无法做任何截面统计。
- **热度缺失 = 池内中位数**(视为"信息未知"而非"很冷");upside 已在门槛处保证非空。
- **门槛外的股票不出行(不写入),而不是写 0**。写 0 会被平台的分层/IC 计算当成
"中位水平",从而污染排序语义;不出行则由平台 Gen-2 的 Polars 外连接自然容忍。
- **时点对齐**:热度是 **T+1 到达**的日频数据,因此 `akg_score(T)` 的热度项实际使用
**T−1 日热度**(当日可得的最新一期)。这不是缺陷而是点时正确的必然结果,
必须在因子描述与调度设计里写明(§6.4、§8-G5)。
### 3.5 事件因子在 S1 的位置
用户给定的权重次序里没有事件项,因此 **`akg_event` 在 S1 不进主公式**。
保留它的理由和未来用法:A 股"利好往往是股票大跌的开始",**正向事件不可靠**;
但**负向事件(诉讼仲裁、行政处罚、股权质押)作为排除条件是稳健的**——它们不预测
上涨,但确实标记不该碰的标的。因此规划 **S2 把事件做成第三道软否决闸**:
`akg_event < −θ_e` 时剔除或大幅降权。这条不在 S1 上,先观察事件因子自身的分布与
覆盖(实测每日仅 195 行,稀疏)再定 θ_e。
---
## 4. 系统边界:基座 / 桥 / 平台
**三层职责切分(已锁定,不再讨论):**
- **astock-kg 基座**:只**暴露数据**,不算因子。对外只给一组**只读视图**(插槽接口);
基座内部随便重构、接口不变。**不新增任何因子计算**,守住"不打分"铁律。
- **`akg-factor-bridge`(独立工程 / 插槽)**:承载全部因子建模——读基座视图 + 直连 153
读热度 + 读平台行情,做子因子变换与**漏斗合成**,转前缀码,写平台因子表 + 注册。
所有建模决策(赛道清单、门槛阈值、权重、半衰期、极性表)集中在桥里,归属清晰;
赛道成员快照等桥自有中间产物落桥工程 `data/`,不外溢到基座或平台(§3.2)。
- **因子平台 `quant_factor_service`**:保持通用、不感知 astock-kg。只把桥写进来的因子
当普通因子,承担存储、注册、调度、**评价(仪表盘)**、下游服务。
> **为什么不合并进 astock-kg**:基座定位是"数据分析基座微内核",其他应用围绕它形成
> **插槽架构**。因子导出理论上只需要拿到数据库连接方式,不需要动基座。独立工程还带来
> 部署自由——桥落在哪台服务器只由"能否同时连通三处"决定。
```
astock-kg 基座(PostgreSQL)── 只读视图(插槽接口,零新增计算)
├ v_factor_universe (覆盖池,1675)
├ v_factor_consensus (一致预期 → upside)
├ v_factor_events (EVENT 断言,已解析 ts_code → event)
└ v_factor_transmission (传导未动成员 → transmission)
│ 热度不经基座:桥直连 153 代理 stock_fund_heat_scores
│ 现价不经基座:桥直连平台 gp_day_data
▼
akg-factor-bridge(独立 Docker 工程,可部署于任意能连通三库的服务器)
四路子因子变换 + 赛道成员快照(data/) + 【漏斗合成 akg_score】
▼
因子平台 quant_factor_service(通用、不感知 astock-kg)
t_factor_akg_{upside,heat,event,transmission,score} + factor_metadata
→ 评价(RankIC / IC-IR / 分层回测)= 仪表盘
→ 每日调度 / 下游策略消费
```
**因子表契约**(平台侧,不可改):
`t_factor_{code}(trade_date DATE, stock_code VARCHAR(15), factor_value DOUBLE)`,
主键 `(trade_date, stock_code)`;`stock_code` 为**前缀式** `SH600000`
(`600000.SH → SH600000`)。注册表 `factor_metadata(factor_code, display_name,
target_ds_name, target_table_name, category JSON, factor_type, frequency, status,
author, description)`。
---
## 5. 子因子口径(继承 v1.1 文档,按 v2.0 语义更新)
四路子因子**继续独立注册与落库**——它们是漏斗的原料,也是各自可独立观察的仪表。
### 5.1 `akg_upside` 预期空间 → **门槛② + 权重③**
- **源**:基座 `v_factor_consensus.target_mid_avg` ÷ 平台 `gp_day_data.close` − 1。
- **as-of 口径**:现价日取 `asof_date <= 当日`的最新一致预期(`merge_asof` backward),
杜绝前视。
- **实测**:2026-07-23 单日 **795 行**;一致预期在基座内只有 2026-07-11 起 7 天历史。
- **注意**:`gp_day_data` 的代码列是 **`symbol`**(前缀式,如 `SH688280`),
非 `ts_code`;桥内 `_read_gp_price()` 按候选列自动探测。
### 5.2 `akg_heat` 热度 → **权重②(语义取负)**
- **源**:153 代理 `stock_fund_heat_scores.score`(0~1,**T+1 日频**,已是前缀码),
取每日最新 batch。
- **v2.0 语义变更**:**不再当动量/alpha 源用,改为"还没热"取负号使用**。
子因子表 `t_factor_akg_heat` **仍存原始 score 不变**,取负只发生在漏斗内部
(保持子因子表语义中立、可被其他消费方复用)。**该语义翻转待用户确认**(§9-1)。
- **实测**:2026-07-23 单日 **1674 行**(覆盖最广);历史 2025-03-26 起 322 天。
### 5.3 `akg_event` 事件 → **S1 不入公式,S2 负面否决闸**
- **源**:基座 `v_factor_events`(`predicate='EVENT'`),ts_code 取**文档锚**
`documents.meta->>'company_ts_code'`(公告是单公司文档,锚定 100% 可靠),
**不用**未解析的 `claims.subject_id`。
- **构造**:Σ 窗口内事件极性 × 时间衰减 `exp(−交易日龄·ln2/半衰期)`,
半衰期 10 交易日、窗口 60 交易日(草案,见 §9-5)。
- **实测**:2026-07-23 单日 **195 行**(稀疏);历史 2014-01-04 起 843 天(最深)。
### 5.4 `akg_transmission` 板块传导 → **权重①(最重)**
- **源**:基座 `v_factor_transmission`(`transmission_candidates` 的 `quiet` 成员摊平)。
时点戳字段为 **`scan_date`**(传导扫描日,每日 18:15 后产出)。
- **构造**:`路径数 × (1 − 已动比例)`,同股同日多候选取最大。
对齐传导模块"多源汇聚=逻辑更硬、已动比例低=空间更大"的语义。
- **实测**:2026-07-23 单日 **83 行**;历史仅 2026-07-11 起 **3 天**。
- **使用约束**:**只 live 累积,不回填,不进任何拟合模型**(§2.2)。
---
## 6. 实现现状(截至 2026-07-24 实机验证)
### 6.1 已完成
- 基座四视图已建(`sql/astock_kg_slot_views.sql`,容器内 `psql` 应用)。
- 桥工程 `akg-factor-bridge` 全量落地(Docker + compose + CLI),
三库连通性全部打通:基座 PG ✅ / 153 热度 ✅ / 平台因子库 ✅
(**平台因子库亦可经 153 同一 ShardingSphere 访问** —— v1.1 文档 §8.1 已回答)。
- 四子因子**全部注册成功**(`factor_metadata` 含 `factor_type` 列)。
- 四子因子**全部落库成功**(2026-07-23):upside 795 / heat 1674 / event 195 /
transmission 83 行。
- **未完成**:赛道成员表、漏斗合成 `akg_score`、`factor_coverage_probe.py` 实跑。
### 6.2 实测数据历史深度(回填范围据此定)
天数列 = 该源 `COUNT(DISTINCT 时点列)`,为**有数据的日期数**(非交易日历天数)。
| 源 | 时点列 | 起 | 止 | 天数 |
|---|---|---|---|---|
| 行情 `gp_day_data` | `timestamp` | 1997-08-29 | 2026-07-23 | 5584 ⚠️ |
| 事件 events | `disclosure_date` | 2014-01-04 | 2026-07-20 | 843 |
| 热度 heat | `trade_date` | 2025-03-26 | 2026-07-23 | 322 |
| 一致预期 consensus | `asof_date` | 2026-07-11 | 2026-07-23 | 7 |
| 传导 transmission | `scan_date` | 2026-07-11 | 2026-07-23 | **3** |
覆盖池 universe:**1675 只**。
> ⚠️ **待实机复核**:`gp_day_data` 区间跨约 28.9 年,按 A 股年均 ~242 交易日应在 7000
> 上下,实测 5584 相当于年均 193 天——怀疑真实起始日晚于 1997(约在 2003~2006 之间,
> 早期只有零星记录)。**§7 中 upside "理论可回填到 2006"依赖这一行,需先复核**。
> 复核方式:按年统计 `COUNT(DISTINCT timestamp)`,看从哪一年起接近 242。
>
> 另注:consensus/transmission 的起始日 2026-07-11、事件起始日 2014-01-04 均为周六,
> 因这三者的时点列是**披露日/扫描日等自然日**而非交易日,属正常。
### 6.3 已解决的实现陷阱(记录以免重踩)
| 现象 | 根因 | 处置 |
|---|---|---|
| `factor_metadata 无 factor_code 列` | **ShardingSphere 代理不支持 `information_schema` 内省** | 改用 `SELECT * FROM factor_metadata LIMIT 0` 读 `cur.description` 取列名,附硬编码兜底 |
| `Unknown column 'ts_code'` on `gp_day_data` | 平台该表代码列实为 `symbol` | `_read_gp_price()` 按候选列 `symbol/ts_code` 逐个探测 |
| upside `MergeError: incompatible merge keys dtype` | pandas 2.x 两侧 datetime 分辨率不一致(us vs ns) | 两侧强制 `astype("datetime64[ns]")` 后单次 `merge_asof(by="k")` |
| event `'float' object has no attribute 'strip'` | SQL NULL direction → NaN 撞 `.strip()` | `event_type`/`direction` 先 `.fillna("")` |
| `build akg_heat --date 2026-07-24` 无数据 | 热度 T+1,当日尚无 | `views` 子命令增加**数据前沿/历史深度**报告,构建日期据实选 |
### 6.4 运维口径(Docker 铁律)
```bash
# 起容器
docker compose up -d --build
# 连通性 + 历史深度自检
docker compose exec akg-factor-bridge python run.py views
# 注册
docker compose exec akg-factor-bridge python run.py register
# 日更 / 回填
docker compose exec akg-factor-bridge python run.py build all --mode daily
docker compose exec akg-factor-bridge python run.py build akg_event \
--mode history --start 2024-01-01 --end 2026-07-24
# 基座建视图
docker exec -i akg-postgres psql -U akg -d akg < sql/astock_kg_slot_views.sql
```
所有写入**幂等**(删涉及日期区间 → 批插),可安全重跑。
**调度时点的已知约束**:传导 18:15 后落库,故 `akg_score(T)` 最早 T 日 18:40 可算;
但热度 T+1 到达,该次计算的热度项用的是 **T−1 日热度**(§3.4 末)。若要让热度项对齐
到 T 日,须改为 **T+1 早间补算 `akg_score(T)`**——两种方案的取舍见 §9-10。
---
## 7. 回填策略(分层,不追求全量对齐)
自洽公式路线**不再需要为了训练而凑齐历史**,回填的目的降为两条:
让评价仪表盘有足够样本、让子因子各自的分布可被观察。因此按可行性分层推进即可。
| 子因子 | 可回填性 | 路径 | 深度 |
|---|---|---|---|
| `akg_heat` | ✅ 直接 | 取 `stock_fund_heat_scores` 历史区间 | 2025-03-26 起 |
| `akg_event` | ✅ 直接 | EVENT claims 带真实 `disclosure_date` | 2014 起(依公告抽取进度) |
| `akg_upside` | ⚠️ 需重建 | 由 `gp_report_rc` 按披露日重建一致预期聚合 + 历史收盘 | 待 §6.2 复核后定 |
| `akg_transmission` | ❌ **不回填** | 回填=前视(§2.2) | 只 live 累积 |
| `akg_score` | 随最短板 | 门槛②依赖 upside,权重①依赖传导 | 见下 |
**`akg_upside` 重建的两条路(待定,§9-6)**:
- **甲案(基座侧)**:在 astock-kg 内回填 `consensus_daily` 历史,桥不动。
优点是基座产出一致、其他消费方同样受益;缺点是动基座、工作量在基座侧。
- **乙案(桥侧)**:桥直连 `gp_report_rc` 自行聚合。优点是不动基座、迭代快;
缺点是聚合逻辑在两处存在(基座有 live 版、桥有历史版),有漂移风险。
**已知陷阱(数据源盘点已记)**:`gp_report_rc.tp` 是**利润总额不是目标价**,
目标价走 `max_price/min_price`;点时一律用披露日。另需注意行情为**前复权**,
历史目标价(当时的名义价)除以前复权价会在除权点产生系统性偏移,重建时需做基准一致化。
**`akg_score` 的历史怎么办。** 因为传导不可回填,历史 `akg_score` 必然缺失第一权重项。
两种诚实的做法,二选一并在因子描述里写明:
- **A. 只从传导有值的交易日起算(推荐)**。注意一个易被忽略的坑:live 区间内部
也有空洞——2026-07-11~07-23 里 consensus 有 7 天而 transmission 只有 3 天,
按 §3.4 的 `std=0 → 整列置 0` 规则,那 4 天的 `akg_score` 会**静默退化成没有传导项
的版本**,却和真 live 值混在同一张表里,下游无从区分。
**因此 S1 的落库规则是:`akg_score` 只在当日传导表有数据的交易日出行**
(另在运行日志里记录被跳过的日期),保证表内每一行都真正包含了第一权重项。
- **B. 出一个明确标注的历史近似版** `akg_score_hist`:传导项置 0(即历史上只有
门槛+热度+便宜三项),**单独注册、单独命名**,绝不与 live 版混在一张表里。
它的用途仅限于观察门槛与另外两项的历史分布,**不得用于宣称因子有效性**。
**可选:外溢代理(spillover proxy)。** 若确实需要一个可回填的传导替身,可用
`A@R − R`(邻接矩阵 × 收益的一阶外溢减自身收益)构造。它可回填,但**携带成员性前视**
(用今天的产业链图谱定义邻接),故其历史 IC 只能作为**乐观上界**读取,不能当作
传导的历史业绩。列为 S3 可选,非必需。
---
## 8. 里程碑(G 系列,替代 v1.1 文档的 F 系列)
- **G0 · 文档评审**:本文评审通过。同步确认 **§9-1(热度语义)、§9-2(赛道清单)**。
- **G1 · 赛道覆盖体检**(**当前阻塞项**):拿到完整赛道清单后,逐赛道统计图谱内
可映射到的主题/环节/成员数,产出"哪些赛道有料、哪些是空的"的体检表。
**覆盖为空的赛道不进 S1 公式。** 同期完成三件事:
①补跑 `factor_coverage_probe.py`(v1.1 文档遗留的 F0 覆盖面诊断,只读,尚未执行);
②统计池内 upside 分布以定 **§9-3 的 q**;③复核 **§6.2 的 `gp_day_data` 起始日**。
- **G2 · 赛道成员表落地**:`config/frontier_tracks.yml` + `tracks.py` +
`data/track_members.csv` 快照;人工 review 一遍成员,确认没有明显错配。
- **G3 · 漏斗实现 + 注册 `akg_score`**:桥内实现两道门槛与三项加权,落
`t_factor_akg_score`,注册。**开工前确认 §9-8(权重量值)**。
同时输出**每日候选池规模**日志——若日均候选数长期低于 30,说明**组合层面无法分散
成篮**(这是组合可行性约束,**不是 IC 可算性约束**),需回头看是赛道覆盖太窄
(§9-2)、估值门槛太紧(§9-3)、还是券商覆盖率不足(§9-4)。
- **G4 · 回填与仪表盘**:**开工前确认 §9-6(upside 重建路径)、§9-7(score 历史处理)**。
按 §7 分层回填;挂上平台评价,产出第一版 RankIC / IC-IR / 分层读数。
**读数不作为判收条件**,作为观察记录。
- **G5 · 每日调度上线**:按 §9-10 定下的时点方案配置桥容器 cron 或平台 XXL-JOB;
`akg_score` 进入下游消费。
---
## 9. 开放问题(待拍板)
1. **热度语义翻转确认**:v2.0 把热度从"越热越好"改成"**还没热更好**"(漏斗内取负)。
这与"热度用于辅助验证传导是否启动、缩短左侧建仓时间"一致,但需要明确确认。
2. **完整赛道清单**:已明确核聚变、商业航空航天、通信、算力、人工智能、低空经济;
**需要补全"等领域"具体还包括哪些**(如生物制造、量子科技、脑机接口、
氢能与新型储能、6G、先进材料……?)。清单直接决定 C 门槛的范围。
3. **估值门槛的 q 分位**:`θ_v = max(0, 池内 q 分位)`,q 默认 0。若实测池内 upside
普遍为正(券商乐观),q 应上调到多少(0.3?0.5?)——G1 统计分布后定。
4. **无券商覆盖股的处置**:当前设计是 upside 缺失 → 不过门槛(保守)。
但这与"研报滞后反而是确定性体现"的论题有张力——最早期、最冷门、最符合论题的
标的可能恰恰没有覆盖。是否要为"赛道内 + 无覆盖"的股票开一条单独通道?
5. **事件极性表与半衰期**(继承 v1.1 文档 §8.3):`发行上市 / 并购交割 / 股权质押` 的
符号,以及半衰期 10 日 / 窗口 60 日是否合适。S1 事件不入公式,此题可延后到 S2。
6. **upside 历史重建走甲案还是乙案**(§7)。
7. **`akg_score` 历史处理走 A 还是 B**(§7 末)。建议 A。
8. **权重旋钮的默认值** 0.5/0.3/0.2 是否认可(次序已定,量值待认)。
9. **"还没热"是否要改成条件项**:S1 用无条件加性项(§3.4 退化说明)。
备选:`z_H · 1[z_T>0]`(仅对有传导的股生效)或 `z_T · z_H`(交互)。S2 评估。
10. **调度时点**:T 日 18:40 算(热度用 T−1)vs T+1 早间补算 `akg_score(T)`
(热度对齐 T,但因子延迟一天可用)。取决于下游策略的下单时点。
---
## 10. 判收标准(v2.0 重写)
**明确取消**"神经 IC-IR 需优于线性基线"这条 v1.1 判收项——它属于被推翻的路线。
**必须满足(工程正确性):**
- 四子因子 + `akg_score` 建表/注册成功,每日调度幂等,重跑不产生重复或漂移。
- **点时正确,全链无未来函数**:各源分别以 `disclosure_date` / `asof_date` /
`scan_date` / T+1 热度盖章;`akg_score` 在 T 日算出、用于 T+1 买入;
热度项使用 T−1 日值这一事实在因子描述中显式声明。
- **传导不出现在任何历史区间**(除非走 §7 末 B 方案且单独命名),杜绝前视污染;
且 `akg_score` 表内不含"传导项被静默置零"的行(§7 末 A 方案)。
- 赛道成员快照可审计:每只股票能追溯到"因哪个赛道、哪个环节、哪条映射规则"入选。
**必须满足(逻辑自洽性):**
- 公式的每一项都能用 §1 的论题解释;出现无法解释的项,删掉而不是保留
(已知的一处妥协——"还没热"退化为无条件项——已在 §3.4 显式记录并列入 §9-9)。
- 门槛与权重的角色不混淆:门槛不可被权重补偿。
- 截面标准化只在候选池内做,池外不出行。
**观察但不判死(仪表盘):**
- RankIC / IC-IR / 分层单调性 / 换手率 / 候选池规模。
- 这些读数用于回答"当前市场是否在奖励这套逻辑",以及"哪一项在拖后腿"。
**读数差不构成下线因子的理由**;构成的理由只有一个——**产业逻辑被证伪**。
**神经 GRU 的复活条件**(降级为"未来挑战者"):当且仅当
(a)传导积累出足够长的 live 历史(≥ 1 年,且期间图谱结构相对稳定),
(b)自洽公式已上线并有可对比的基准读数——此时才有必要让 GRU 去挑战公式,
并且必须是**严格 OOS、只用 live 区间**。在此之前不开这条线。
---
## 附录 A · 术语
| 词 | 含义 |
|---|---|
| 基座 | astock-kg,数据分析基座微内核,只暴露数据不算 alpha |
| 桥 | `akg-factor-bridge`,独立 Docker 工程,全部因子建模在此 |
| 平台 | `quant_factor_service`,通用因子管理平台;本文只用其注册/存储/调度/评价能力 |
| 覆盖池 U | `industry_pools` 全主题成员并集,实测 1675 只 |
| 候选池 P | U 中同时通过赛道门槛 C 与估值门槛 V 的子集 |
| 观察 / 推断 | 有耐久时间戳记录 / 依赖当时系统状态的当日判断(§2.2) |
| 漏斗 | 两道硬门槛 + 池内三项加权的复合结构 |
| `scan_date` | 传导扫描日,`transmission_candidates` 的时点戳(每日 18:15 后产出) |
| S1 / S2 / S3 | 因子自身的演进阶段(区别于文档版本 v1.1 / v2.0) |
## 附录 B · 关联文档
- astock-kg:`涌现式应用层重构设计.md`(四路信号即四条用户主线的数据面产物)、
`数据源盘点.md`(热度/一致预期/资金语义、`gp_report_rc.tp` 陷阱)、
`项目全景盘点_2026-07.md`。
- 桥工程:`akg-factor-bridge/README.md`(Docker 用法、待实机核实项)、
`sql/astock_kg_slot_views.sql`(四视图定义)。
- 平台:`quant_factor_service/readme.md`(多因子合成引擎技术文档)与运维手册
——本文只引用其**契约与评价能力**,不再引用其合成能力。
---
> **提交提醒**:本文档、`backend/scripts/factor_coverage_probe.py`,以及
> `akg-factor-bridge` 整个工程,均为未提交状态,请在开发机 `git commit` 后同步到服务器。