akg-factor-bridge/量化因子导出与合成设计.md

39 KiB
Raw Blame History

量化因子导出与合成设计v2.02026-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 变成某种公用服务或基础设施之后终结——那时它才会像新能源 或制造业那样"可研究"(业绩稳定、能做确定性高的预测)。在此之前,它不可研究。

不可研究意味着什么。 具体到方法论,处在这个阶段的赛道有三个特征:

  1. 大方向向上——产业趋势本身没有分歧,政策与产业资本都在推;
  2. 无法准确估值——收入曲线还没定型DCF/PE 给不出可信中枢;
  3. 没有另类领先数据——不像制造业有订单、排产、开工率可以先行跟踪。

三条同时成立时,自下而上的基本面精算是无效的(算不准),量价动量是滞后的(等确认 就已经在右侧了)。剩下唯一可行的办法是景气度投资:不追求算准,只追求 方向对 + 位置早 + 价格不离谱

落到选股上,就是找两类特征的交集:

  • 确定性高——确定性不来自盈利预测,来自产业逻辑:它在不在国家级主线上、 在产业链上占什么位置、这个位置有没有壁垒。
  • 相对较便宜——不是绝对估值便宜,是相对于预测的空间还在。因为系统赌的是 大方向正确,必须给自己留容错度;贵了就没有容错度了。

热度在这里的真实作用。 单一股票的热度本身没有太大意义。它的价值在于 辅助验证产业传导逻辑是否已经启动——用来缩短左侧建仓的时间和风险。所以热度 不是一个独立的 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 覆盖池 Uindustry_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/Parquetgit 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-9S2 再评估。

**几个必要的技术处置:**

- **截面标准化是自洽性的前提,不是可选项**。三项量纲完全不同(传导是"路径数 × 空间
  比例"的乘积量、热度是 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)` 的热度项实际使用
  **T1 日热度**(当日可得的最新一期)。这不是缺陷而是点时正确的必然结果,
  必须在因子描述与调度设计里写明§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-23upside 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 到达,该次计算的热度项用的是 **T1 日热度**§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-6upside 重建路径、§9-7score 历史处理)**。
  按 §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.30.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 算(热度用 T1vs 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 买入;
  热度项使用 T1 日值这一事实在因子描述中显式声明。
- **传导不出现在任何历史区间**(除非走 §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` 后同步到服务器。