8.6 KiB
第一批实机验证清单(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. 先提交(改完再跑,出问题好回滚)
cd ~/Documents/work/project/akg-factor-bridge
git add -A
git commit -m "fix: 交叉评审第一批——传导口径/事件回填/年报污染/分块与冻结
- 视图 v2:n_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。
# 推荐:在桥这边跑,零新增凭据、全程 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. 起容器 + 连通性与视图版本自检
cd ~/Documents/work/project/akg-factor-bridge
docker compose up -d --build
docker compose exec akg-factor-bridge python run.py views
要看的三段:
- 连通性七项全 ✅;
- 新增的「视图版本」段——四项应该是
✅ n_sources/✅ mkt_trade_date/✅ source_type/⬜ v_factor_segment_members(最后一个是 G2 的第五插槽视图,现在未就绪是对的); - 末行打印当前口径:
SUBFACTOR_UNIVERSE=pool | EVENT_SOURCE_TYPES=['announcement'] | EVENT_MAX_PER_DOC=3。
若
mkt_trade_date是 ⬜,说明ALTER TABLE那段没跑到,回第 1 步。
3. ★ G1 体检(这一步的输出最关键,直接决定第三批怎么定)
# 三节可分开跑;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 跑完会自动冻结)
# 热度 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。
# 看一眼冻结产物
docker compose exec akg-factor-bridge cat /app/data/frozen/2026-07-24/manifest.json
ls -la data/frozen/2026-07-24/
5.(可选,但很值)事件回填冒烟——验证硬伤 3 真的修好了
# 改之前这条命令会静默返回空(日历取自热度表,最早 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(回答一个对回填边界很关键的问题)
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 累积」的边界
可以往前推一段(图谱漂移仍在,但至少多一个带明确标注的近似区间可选)。
把这些发我
run.py views全部输出probe --section corr全部输出 ← 最重要probe --section upside的 q 档位表build all --mode daily的日志(尤其 event 的剔除分布、transmission 的 ⚠️ 三项)- 第 6 步那条 SQL 的结果
拿到这五样,第三批(赛道门槛 C 的口径 + 权重结构)就能用你的真实数据定, 不用再靠我的模拟。
已记下的决定
- 传导新鲜度断言 → 照常落库,只打告警 + 记
mkt_trade_date(不中止扫描)。 理由:保覆盖,传导每日只有几十行,公告批量入库期间 beat 一旦被饿就整天空白, 代价太大;改由桥侧按mkt_trade_date自行判断是否采信。 第二批的transmission.scan已按此改写(allow_stale参数取消)。