akg-factor-bridge/docs/选股计划入池_对接说明.md

101 lines
6.6 KiB
Markdown
Raw Permalink 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-08-03 与用户定稿并落码。代码:`pool.py`(入口 `run.py push-pool`
> 纯逻辑单测 `test_pool_logic.py`。本文写清楚三件事:为什么这么接、规则是什么、怎么部署与验证。
## 1. 为什么走股票池,而不是新造一条推理链
决策系统bionic_trader每晚 22:30 的认知扫描,扫描范围就是 Mongo `stock_groups`
集合里**所有分组的股票代码并集**`daily_scan_v2.get_mongo_stock_pool()` 对整个集合取
并集,不看分组归属)。扫到的每只票会产出支撑位、压力位、定性结论,落在
`strategy_daily_results`——持仓系统PMS的参考位、择时执行区间、研判上下文全部读它。
所以把每日计划写成集合里的一个独立分组,候选票当晚就自动获得夜间推理,不需要在任何
系统里新增推理步骤。这正是「提前计算为主、盘中监控为辅」的落法:大模型的活儿全部发生
在凌晨,盘中各接口只读现成结论。
配套的收尾机制决策系统也已经有:掉出池子并集的票,下一次扫描会被
`prune_stale_strategies` 把策略标成 `DROPPED` 并生成离场报告——所以出池动作只需要在
Mongo 侧记账(回收站),分析侧的清理是自动的。
## 2. 入池、留池、出池的规则(用户拍板,`pool.decide()` 逐条对应)
| 规则 | 内容 |
|---|---|
| 入池 | 当日计划(强传导主榜前 `POOL_TOP`,与 PMS 候选同口径)∪ 当前持仓(首选 PMS 账本 `pms_position`——新架构下下游 `trading_position` 已无写入方,账本才是有人维护的持仓事实;账本读不到才退回下游表兜底) |
| 留池 | 旧成员既不在计划也无持仓、但形态未恶化的,留下继续接受每晚分析——榜单是按条数截断过的,掉榜不等于变坏 |
| 出池 | 无持仓、不在计划、且形态已恶化 → 移入回收站 `stock_recycle_bin`。恶化判据用决策系统自己的结论:`strategy_daily_results` 最新定性为 SELL / AVOID / DROPPED |
| 上限 | 池子超过 `POOL_MAX`(默认 60从「留池观察」里清最久没上过榜的这类清退不进回收站它们没有恶化记录出池后由决策系统的 DROPPED 机制收尾 |
| 底线 | **持仓永不出池**,即使形态恶化——恶化持仓在池子备注里给警示,处置是 PMS 风控与体检的事,池子只保证它每晚有结论可用 |
拿不到就不动的三条安全边界:计划数据缺失(因子表没跑出来)→ 整轮中止,池子保持原样;
持仓读不到 → 同样中止(否则可能把持仓票错清出池);决策系统结论读不到 → 本轮不判恶化、
一只都不回收,其余照常并在备注里说明。
## 3. 写进 Mongo 的东西
分组文档(`stock_groups`,按 `group_code=AKG_PLAN` + `org_id` 覆盖式更新):
`stock_codes`(前缀码)、`remark`summary 一句人话 + factor_details + retained_positions +
update_time_str格式沿用现有池子、`strategy_context`(每只计划票的分数/档位/主题/预期
空间,供人查)、`member_meta`(每只票的入池日与最近上榜日,上限清退的排序依据)。
回收站文档(`stock_recycle_bin`字段照抄现有格式group_id / group_name / org_id /
removal_batch / removed_at / stock_code**另加了一个 `reason` 字段**说明移入原因——
Mongo 加字段对老读者无影响,事后能分清是形态恶化还是别的原因。
老模拟系统目前处于停用状态2026-08-03 用户确认),所以新分组不会引发任何自动交易;
将来若重启那套系统,需要先确认它只认自己的分组。
## 4. 每天的时间线
```
07:10 桥机 cronUTC 23:10build + plan既有盘前链07-30 D 案)
07:1x 接着跑 push-pool计划写入池子恶化票移入回收站
07:1x push-pool 顺手触发决策系统增量补扫(/api/v1/xxl/daily-scan?mode=incremental
只补当天还没结论的票——通常就是几只新进榜的)
08:30 决策系统的例行查漏补缺照跑(另一层兜底)
08:40 PMS 拉 /plan 刷新候选池(原有流程,一字未动)
09:30 开盘:候选票的支撑/压力/定性已就绪 → 参考位、择时区间、研判全部可用
22:30 决策系统全量夜扫:覆盖整个池子并清理掉出池的票(终极兜底)
```
增量补扫失败只提示不报错——当晚全量扫是兜底,最坏情形是新进票当天白天没有结论
择时对它们回「不可用」PMS 自动退内置择时,行为与接入前相同)。
## 5. 部署(桥机 factorevaluationakg-factor-bridge 根目录)
```bash
git pull
# 新增 pymongo 依赖,需要重建一次镜像(代码本身是挂载卷,之后改码不用再 build
docker compose build && docker compose up -d
# .env 增补(对照 .env.example 底部「选股计划入池」一节):
# MONGO_* 五项(填决策系统 .env 里的同名值)
# BIONIC_SCAN_URL / BIONIC_SCAN_KEY可选触发增量补扫用
# 纯逻辑单测(不连库,秒级):
docker compose exec -T akg-factor-bridge python test_pool_logic.py
# 首次试跑(只看不写,核对入池/出池明细):
docker compose exec -T akg-factor-bridge python run.py push-pool --dry-run
# 确认无误后真写(写完会打印分组 _id 与回收站回执):
docker compose exec -T akg-factor-bridge python run.py push-pool
```
宿主 crontab把 push-pool **串在既有盘前链命令末尾**(用 && 衔接,链子没跑成就不动
池子),不要单独定时——单独定时撞上链子超时会拿昨天的因子重复入池:
```
# 既有UTC 23:10 = CST 07:10示意
10 23 * * 1-5 docker exec akg_factor_bridge python run.py build all --mode daily && \
docker exec akg_factor_bridge python run.py plan && \
docker exec akg_factor_bridge python run.py push-pool
```
## 6. 验证与判收
部署当天:`--dry-run` 的明细与预期一致;真写后在 Mongo 里能查到 `AKG_PLAN` 分组且
`stock_codes` = 计划 持仓。当晚 22:30 后:`strategy_daily_results` 里新进票有当日行。
次日盘中PMS 侧 `probe_bionic.py` 对候选票探活,择时接口应回 FIRE/WAIT 并带出区间
(不再是「没有昨夜结论」的不可用)。连续跑几天后:掉榜未恶化的票留在池里继续有结论;
出现 SELL/AVOID 的闲置票进回收站,且决策系统随后把它们标 DROPPED。
判收纪律照旧:代码就绪 ≠ 接通 ≠ 判收。判收 = 上面这四条在实机各看到一次。