# 选股计划入池 —— 与决策系统夜间推理的对接说明 > 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 候选同口径)∪ 当前持仓(`trading_position` 数量>0) | | 留池 | 旧成员既不在计划也无持仓、但形态未恶化的,留下继续接受每晚分析——榜单是按条数截断过的,掉榜不等于变坏 | | 出池 | 无持仓、不在计划、且形态已恶化 → 移入回收站 `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 桥机 cron(UTC 23:10):build + 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. 部署(桥机 factorevaluation,akg-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。 判收纪律照旧:代码就绪 ≠ 接通 ≠ 判收。判收 = 上面这四条在实机各看到一次。