608 lines
39 KiB
Markdown
608 lines
39 KiB
Markdown
# 量化因子导出与合成设计(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 变成某种公用服务或基础设施之后终结——那时它才会像新能源
|
||
或制造业那样"可研究"(业绩稳定、能做确定性高的预测)。在此之前,它不可研究。
|
||
|
||
**不可研究意味着什么。** 具体到方法论,处在这个阶段的赛道有三个特征:
|
||
|
||
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 覆盖池 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`):**
|
||
|
||
```yaml
|
||
# 示意结构,实际清单待 §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` 后同步到服务器。
|