akg-factor-bridge/docs/第一批验证清单_2026-07-26.md

185 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 第一批实机验证清单2026-07-26
> 已写入 `akg-factor-bridge`:改 7 个文件(+533/121新增 `freeze.py` / `probe.py` / `.gitignore`。
> 容器内与设备端 `py_compile` 均通过;`build_event` 的向量化改写做过逐位等值回归;
> `probe corr` 的边界情形(传导全 0、MAD=0、池内只剩 1~2 只)已跑过不炸。
> **本批不动 astock-kg 代码**,只替换基座上的四个视图(`CREATE OR REPLACE` + 一个可空列 + 一个索引)。
---
## 0. 先提交(改完再跑,出问题好回滚)
```bash
cd ~/Documents/work/project/akg-factor-bridge
git add -A
git commit -m "fix: 交叉评审第一批——传导口径/事件回填/年报污染/分块与冻结
- 视图 v2n_paths→n_sources(distinct 源数,修 cascade 变长边与三桶重复计数)
暴露 target/members_total/n_quiet_stored/mkt_trade_date 供桥自检上游截断;
v_factor_events 补 doc_id/source_type/tier
- common.trading_days 改用 gp_day_data —— 原用热度表(最早2025-03-26)导致
事件 history 回填静默返空
- factors: 事件加年报污染防护(source_type 白名单+同键去重+单文档封顶)、
衰减向量化(逐位等值);行情按月分块;传导上游截断/快照陈旧显式告警
- common.write_factor 分块提交(热度全史约54万行)
- 新增 freeze.py每日冻结 universe/传导原始行/一致预期/前复权close/热度+manifest
—— 上游不可复现(Neo4j无ORDER BY、前复权重写、池只存最新态)
\"可复现\"只能定义为\"能从冻结输入重算出同一个值\"
- probe 新增 corr 节:池内三项相关矩阵 + 权重体检(top-K 里几只是传导票)
- 新增 .gitignore(原来没有,.env 会被 git add -A 带进库)
- SUBFACTOR_UNIVERSE/EVENT_SOURCE_TYPES 等旋钮进 .env.example默认保持原行为"
```
> ⚠️ 顺带发现:**这个仓库原来没有 `.gitignore`**,一旦你在开发机建了 `.env`
> `git add -A` 会把三处数据库口令一起提交。已补上。
> 另外 `.idea/` 已经被跟踪了,`.gitignore` 对它无效——想清出去要
> `git rm -r --cached .idea && git commit -m "chore: .idea 移出版本控制"`(可选)。
`.review_backup_20260726/` 是改动前的原文件备份 + 补丁包,已在 `.gitignore` 里。
验证通过后整目录删掉即可。
---
## 1. 应用视图(基座侧,只建视图 + 加一个可空列 + 加索引)
> ⚠️ **勘误2026-07-26**:原来这里写的 `docker exec -i akg-postgres psql ...`
> 只在 **astock-kg 那台机器**上成立。桥是跨机部署的独立单元,桥的服务器上没有
> `akg-postgres` 容器桥容器本身python:3.11-slim也没有 psql 客户端。
> 已新增 `run.py apply-views`,用桥自己的 `AKG_PG_*` 连接执行 DDL。
```bash
# 推荐:在桥这边跑,零新增凭据、全程 Docker
docker compose exec -T akg-factor-bridge python run.py apply-views --dry-run # 先看清单
docker compose exec -T akg-factor-bridge python run.py apply-views
# 若日常账号是只读的,会逐条报 permission denied —— 用基座 owner 跑这一次:
docker compose exec -T \
-e AKG_PG_USER=<owner> -e AKG_PG_PASSWORD=<pw> \
akg-factor-bridge python run.py apply-views
# 必须用 -e 传进容器:写在 docker 前面只设置宿主机进程的环境变量,进不去
```
**预期**6 条语句逐条 ✅4 个 CREATE OR REPLACE VIEW + 1 个 ALTER TABLE + 1 个 CREATE INDEX
**不动任何一行数据**`claims` / `documents` 一个字节不变。
---
## 2. 起容器 + 连通性与视图版本自检
```bash
cd ~/Documents/work/project/akg-factor-bridge
docker compose up -d --build
docker compose exec akg-factor-bridge python run.py views
```
**要看的三段**
1. 连通性七项全 ✅;
2. 新增的「视图版本」段——四项应该是
`✅ n_sources` / `✅ mkt_trade_date` / `✅ source_type` / `⬜ v_factor_segment_members`
(最后一个是 G2 的第五插槽视图,现在未就绪是对的);
3. 末行打印当前口径:`SUBFACTOR_UNIVERSE=pool | EVENT_SOURCE_TYPES=['announcement'] | EVENT_MAX_PER_DOC=3`。
> 若 `mkt_trade_date` 是 ⬜,说明 `ALTER TABLE` 那段没跑到,回第 1 步。
---
## 3. ★ G1 体检(这一步的输出最关键,直接决定第三批怎么定)
```bash
# 三节可分开跑price 节全表聚合可能 1~3 分钟
docker compose exec akg-factor-bridge python run.py probe --section corr
docker compose exec akg-factor-bridge python run.py probe --section upside
docker compose exec akg-factor-bridge python run.py probe --section pools
docker compose exec akg-factor-bridge python run.py probe --section price
```
**`corr` 节要回答的两个问题**(把整段输出发我):
- **① `corr(z_H, z_V)` 是多少?** 若 |值| > 0.5,「还没热」与「便宜」高度共线,
「三项加权」实际是两项§9-8 的权重讨论要重开(而且门槛② 与 `z_V` 本就是同一变量进两次)。
- **② `w_T=0.50` 那行的 top-K 命中数。** 如果命中数 ≈ min(K, 传导票数)
就实锤了「0.5/0.3/0.2 事实上是传导优先而非加权混合」。
同一节还会打印**两段式与当前公式的 top20 重合度**——越接近 20/20
说明改成两段式零代价,那第三批 3.2 就直接选 A。
另外 `corr` 节末尾的 `U → 有 upside → 过门槛② → 其中有传导` 这条链,
最后一个数就是真正决定榜首的量级。
---
## 4. 因子构建 + 冻结daily 跑完会自动冻结)
```bash
# 热度 T+1构建日选有数据的那天views 的「数据历史深度」段会告诉你前沿在哪)
docker compose exec akg-factor-bridge python run.py build all --mode daily --date 2026-07-24
```
**要看的**
- 四路各自的写入行数和上次upside 795 / heat 1674 / event 195 / transmission 83对比
- **event 行数大概率会掉**——新加了 `source_type='announcement'` 白名单 + 单文档封顶,
日志会打印剔除了多少条、按来源分布是什么。**这个分布请一并发我**
如果剔除后接近 0说明基座里公告的 `source_type` 不是 `announcement` 这个字符串,
按实际值改 `.env``EVENT_SOURCE_TYPES` 即可;
- **transmission 那里的 ⚠️ 告警**——`quiet 存满 12 条` / `members_total >= 30` /
`mkt 快照日 ≠ scan_date` 各命中几个环节。这三个数就是硬伤 1 的实测量级,
直接决定第二批里 `topic_context` 的 cap 该提到多少;
- 末尾 `❄️ 冻结 ... → /app/data/frozen/2026-07-24`,各源行数 + warnings。
```bash
# 看一眼冻结产物
docker compose exec akg-factor-bridge cat /app/data/frozen/2026-07-24/manifest.json
ls -la data/frozen/2026-07-24/
```
---
## 5.(可选,但很值)事件回填冒烟——验证硬伤 3 真的修好了
```bash
# 改之前这条命令会静默返回空(日历取自热度表,最早 2025-03-26
docker compose exec akg-factor-bridge python run.py build akg_event \
--mode history --start 2024-01-01 --end 2024-03-31 --no-freeze
```
**预期**现在应该有真实行数2024 年的公告若已抽取),而不是「无数据(跳过)」。
若仍为空,看是不是被 `EVENT_SOURCE_TYPES` 过滤掉了(日志会说)。
---
## 6. 顺带跑一条 SQL回答一个对回填边界很关键的问题
```bash
docker exec -i akg-postgres psql -U akg -d akg <<'SQL'
SELECT kind, min(trade_date), max(trade_date), count(DISTINCT trade_date) AS days
FROM mkt_daily GROUP BY kind ORDER BY kind;
SQL
```
`mkt_daily` 是持久快照表(全库无删除),所以 `kind='stock'` 的天数决定了传导
**理论上**能重扫到哪一天。若明显多于 3 天,设计 §7 里「传导只 live 累积」的边界
可以往前推一段(图谱漂移仍在,但至少多一个带明确标注的近似区间可选)。
---
## 把这些发我
1. `run.py views` 全部输出
2. `probe --section corr` 全部输出 ← **最重要**
3. `probe --section upside` 的 q 档位表
4. `build all --mode daily` 的日志(尤其 event 的剔除分布、transmission 的 ⚠️ 三项)
5. 第 6 步那条 SQL 的结果
拿到这五样,第三批(赛道门槛 C 的口径 + 权重结构)就能用你的真实数据定,
不用再靠我的模拟。
---
## 已记下的决定
- **传导新鲜度断言 → 照常落库,只打告警 + 记 `mkt_trade_date`**(不中止扫描)。
理由:保覆盖,传导每日只有几十行,公告批量入库期间 beat 一旦被饿就整天空白,
代价太大;改由桥侧按 `mkt_trade_date` 自行判断是否采信。
第二批的 `transmission.scan` 已按此改写(`allow_stale` 参数取消)。