tradingSystem/docs/交接_2026-09-10.md

188 lines
13 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-09-10
写给下一个接手的会话。读完这一份就能接着干,不需要回头翻聊天记录。
---
## 一、一句话现状
三个系统今天都有改动落地。**持仓管理系统与择时决策系统的改动已经重启生效****选股系统还有一批改动躺在服务器上没生效,等休市后重启**。今天开盘前出过一次页面超时故障,已经修好并验证。
---
## 二、最要紧的待办:休市后重启一个容器
**做什么。** 重启选股系统的接口容器,让今天中午之后的三件改动生效。
**在哪台机器。** 155用户名 factor端口 2280。
```bash
ssh -p 2280 factor@192.168.16.155 'cd /home/factor/project/akg-factor-bridge && docker compose restart -t 20'
```
**重启之后必须立刻做两件事。** 第一件是预热,因为重启会清空进程内缓存,不预热的话下一个访问的人要等三十三秒:
```bash
ssh -p 2280 factor@192.168.16.155 'curl -s -o /dev/null -w "预热 %{time_total}s\n" --max-time 120 "http://192.168.16.155:8300/plan?top=300&obs_top=100"'
```
第二件是确认新代码真的在跑:
```bash
ssh -p 2280 factor@192.168.16.155 'docker exec akg_factor_bridge python3 -c "import api;print(\"缓存存活\", api.PLAN_CACHE_SEC, \"秒;快照路径开关\", api.PLAN_FROM_SNAPSHOT)"'
```
预期读数是「缓存存活 43200 秒;快照路径开关 True」。
**为什么不能现在重启。** 现在是交易时段。重启会让持仓管理系统那一跳拉不到计划,还会清空缓存触发一次三十三秒的冷启动。而今天不重启也没有损失,理由见第四节。
---
## 三、今天做完了什么
### 甲、开盘前的页面超时故障(已修好并生效)
**现象。** 09-10 早上 09:02持仓管理系统页面报「上游的选股计划读不到 · timeout of 60000ms exceeded」加仓和建仓命令因此没有票可选。
**根因,两半。** 一是选股计划接口的缓存只活十分钟,盘前 08:40 预热那次花了三十九秒、08:50 就过期,用户 09:02 打开页面正好撞上冷启动。二是装配那一句写在锁外面,页面一次加载并发拉好几路,全部判缓存未命中、各自跑一趟三十多秒的装配、还互相抢同一批数据库连接,叠加破了六十秒。
**修法。** 缓存存活从十分钟改成十二小时(缓存键里带的是真实数据日,上游换日后旧那份立刻失效,新鲜度本来就不靠时间保);同一个键同时只算一次,第一个去算、后到的等它算完直接吃缓存,不同参数组合互不阻塞。
**状态。** 已重启生效,实测三路并发总墙钟三十四秒,等于单跑一次。台账记在选股系统第 056 条。
### 乙、那个故障的正解(代码就位,等重启)
用户问了一句「这个严重依赖实时失效的缓存的设计是对的么」。答案是不对,缓存只是把「每次都三十三秒」变成「每天第一次三十三秒」。于是做了正解,三件事:
1. **接口改读当日全量快照。** 出计划时本来就落了一份全量快照(不裁剪、不设主题限额),注释里写明它是「复盘与对账的唯一底本」,只是接口一直没读它。现在接口先读那份底本、按请求参数截取,读不到或太旧就自动回落到现算。实测零点四一秒对三十二点三秒,快七十八倍。
2. **新鲜度守卫。** 快照太旧就不能当今天的计划下发。两条判据:代码版本要与当前一致;生成时刻距今不超过十六小时。任一不满足就退回现算。
3. **取因果论断的查询补确定排序。这是今天最值钱的一条。** 那条查询原来没有排序,而它的文档串写着「每票取最近披露日的最多三条」。数据库在没有排序时返回顺序不保证,于是**同一个数据日、同一份代码,相隔三十二秒的两次装配结果就不一样**:候选卡差五处、逻辑线差五处、候选卡名次差二十处,顶层的候选单与关注名单也不同。计划因此不可复现。补上排序后两次现算完全一致。
**状态。** 代码已推到 155选股系统十个测试文件全部通过但**服务进程还没重启,尚未生效**。台账记在选股系统第 057 条。
### 丙、盘中改判与信号聚合09-09 做的,已重启生效)
两件事,都已在 09-09 傍晚重启生效:
- **点股票看它今天的全部信号。** 持仓管理系统新增按代码回扫五个上游源的接口,页面三处入口可点开抽屉。顺带修了四处「弹了遮罩但没有信息」。
- **盘中改判。** 持仓管理系统新增解锁重问(研判驳回后的当日闸可解除一次);择时决策系统新增盘中强势扫描(进攻侧第一条主动通道)与研判强制刷新;资金流分发加了方向闸、覆盖面闸与冷启动配额。
台账记在持仓管理系统第 001 到 005 条、择时决策系统第 001 到 004 条。
### 丁、通道横幅读错配置源(另一个会话做的,已生效,我复核过)
持仓管理系统的通道进程启动横幅说「模式 未启用(空转)」,而通道其实是启用的、握手在线。那一行读的是环境变量层,真实启停由运行参数表决定。已改成读同一个源。
我用六个维度做了复核,三十一条疑点全部被对抗性验证驳回,**零个确认的问题**。证据是同一份日志里三次启动的横幅对比:旧代码两次都说「未启用」但下一行就握手成功,新代码说「启用」,对上了。
---
## 四、还没生效的改动清单
只有选股系统这一批。重启后自动生效,不需要额外操作。
| 改动 | 生效条件 | 今天不生效有没有损失 |
|---|---|---|
| 接口读快照 | 重启 | 没有。快照路径今天本来就会因为代码版本不一致而回落到现算 |
| 新鲜度守卫 | 重启 | 没有。它本来就是配合上一条用的 |
| 取论断补排序 | 重启,且要等下次出计划才影响快照 | 没有。今天现算的结果已经被缓存住,重不重启下游拿到的都是同一份 |
**明早自然验证。** 次日早上七点十分出计划时会用带排序的新代码,之后接口就走快照路径了。查这条:
```bash
ssh -p 2280 factor@192.168.16.155 'docker exec akg_factor_bridge sh -c "grep \"^plan \" data/access.log 2>/dev/null | tail -3"'
```
预期日志里的 `source=``snapshot`、耗时零点几秒。看到 `source=live` 时,同一份日志里会有一行警告说明为什么没走快照。
---
## 五、盘中改判那两件事的上线顺序(尚未开始)
代码全部就位、测试全绿,但**开关还收着**,要分五段上,前两段不能同时开。
| 段 | 做什么 | 前提 | 观察多久 |
|---|---|---|---|
| 一 | 打开解锁重问:页面把 `PMS_OPEN_REASK_ENABLED` 改开,即时生效不用重启 | 现在就能开 | 三个交易日 |
| 二 | 打开强势扫描的观察档:`STRENGTH_SCAN_ENABLED=True` 且 `STRENGTH_SCAN_DRY_RUN=True`,一次大模型都不打 | 第一段观察满三天 | 两个交易日 |
| 三 | 关掉观察档,真派单 | 第二段读数正常 | 三个交易日 |
| 四 | 资金流分发半开:`WATCHER_METRICS_DISPATCH_MODE=full`,配 `WATCHER_METRICS_FULL_SIDES=inflow``WATCHER_METRICS_SCOPE=covered` | **必须单独一段** | 两个交易日 |
| 五 | 资金流分发全开:`SIDES=both` | 第四段全绿,且当日兜底卖出条数恒为零 | 两个交易日 |
**第一段与第二段为什么不能同时开。** 它们会互相喂 —— 强势扫描产的转多广播正好是解锁重问的第一条解锁条件。同时开就分不清「今天解锁了五次」是解锁阈值定得准,还是扫描在制造信号。
**第四段为什么必须单独。** 它改的是一条全市场的流,量级与前两件差两个数量级。任何异常读数出现时,必须能一眼确定是它引起的。
完整说明在两个仓库各自的 `docs/盘中改判与信号聚合方案_2026-09-09.md`
---
## 六、机器与部署方式
| 系统 | 仓库 | 机器 | 代码怎么生效 |
|---|---|---|---|
| 数据基座 astock-kg | astock-kg | 178`ssh -p 2280 tlai@192.168.16.178` | — |
| 选股系统 | akg-factor-bridge | 155`ssh -p 2280 factor@192.168.16.155`),仓库在 `/home/factor/project/akg-factor-bridge` | 源码挂载,`docker compose restart` 即可 |
| 持仓管理系统 | tradingSystem | 155同上仓库在 `/home/factor/project/tradingSystem` | 源码挂载(有 override 文件),`docker compose --profile sched --profile ws restart -t 30`。**`-t 30` 是必须的**,通道进程要二十五秒优雅退出 |
| 择时决策系统 | bionic_trader | 188`ssh -p 2280 tlai@192.168.16.188`),仓库在 `/mnt/work/project/bionic_trader` | 源码挂载,`docker compose restart` 即可 |
**不动运行中的容器就跑测试的办法。** 持仓管理系统那边挂载工作树到临时容器:
```bash
ssh -p 2280 factor@192.168.16.155 'cd /home/factor/project/tradingSystem && docker compose run --rm --no-deps -v /home/factor/project/tradingSystem:/app pms-web python scripts/run_tests.py'
```
择时决策系统那边直接 exec 一个新进程(运行中的工作进程用的还是旧代码,互不影响):
```bash
ssh -p 2280 tlai@192.168.16.188 'docker exec trader_worker_brain python3 scripts/selftest_strength_scan.py'
```
---
## 七、绝对不能碰的东西
**188 上那套持仓管理系统的容器pms-web、pms-ws是对着实盘通道部署的正式实例。** 判据三条任一成立即可定性:账本表前缀是 `real_`、通道端点指向 192.168.16.98(实盘端点)、配了独立的实盘密钥且通道开关开着。它的代码停在 08-28从没拉过 09-09 之后的提交,通道一直握手失败,是「实盘配置全部就位、通道未通、一单没下过」的状态。**正因为这样才更不能碰** —— 只差通道联通和一个参数就会真下单。
155 上那套才是模拟实例(表前缀为空、端点 192.168.18.182)。但要注意:**它的下发模式是 `ws` 不是影子模式**2026-08-03 由用户手动设的,会真向模拟盘发委托。出口表里有 196 笔真实指令单,时间跨度 8 月 4 日到 9 月 7 日。
**红线。** 禁止关机与重启机器。容器的重启、重建与其他关联操作必须先经用户同意。提交、拉取、验证可以直接做。**服务器上只做 `git pull`,不要跑 `git stash`** —— 09-09 我在 155 上跑过一次,把它本地未提交的一个脚本改动藏走了,靠 `git stash pop` 才还原。
---
## 八、两个容易再踩的坑
**一、时区。** 155 的宿主机与选股系统容器跑在世界协调时上,日志、快照里的生成时刻、构建日志的时刻**全是世界协调时**,加八小时才是北京时间。持仓管理系统的四个容器设了上海时区,所以它们的日志是北京时间。同一台机器上两种时区并存。判断「这个任务什么时候跑的」之前先确认容器时区:
```bash
ssh -p 2280 factor@192.168.16.155 'docker exec akg_factor_bridge date "+%F %T %Z"'
```
我因为这个坑犯过两次错。一次把宿主的 07:47 当成早上(实际是北京时间 15:47一次把快照的 `2026-09-09T23:10` 当成「前一晚跑的」(实际是北京时间 09-10 早上 07:10差点据此去修一个不存在的问题。
**二、一条方法上的教训。** 想验证「甲和乙为什么不一样」时,先做「甲和甲自己比」。今天本来以为是快照过时,做了「连着现算两次」的对照才发现现算自己跟自己都对不上,根因是查询没有排序。不做这一步就会去修一个不存在的问题。
**每日节奏(北京时间)。** 07:10 选股系统出计划并落全量快照08:40 持仓管理系统拉计划08:45 把当日区制追加进同一份快照。所以交易日盘中,最新数据日是**前一交易日**,它的快照当天早上就生成好了。
---
## 九、未决的事,等用户拍板
1. **README 与实际状态不符。** 持仓管理系统的 README 第 171 行写「当前仍是影子模式」、第 198 行写「依然没有任何系统会自动下单」,而实际从 8 月 3 日起就是 `ws` 下发模式、发出并成交了 196 笔。这不是代码缺陷(页面顶部有实时横幅显示真实模式),但是那种读了会做出错误安全判断的过时说法。我问过要不要改,用户还没答。
2. **不追高那道闸的口径名不副实。** 变量名与错误信息都说「当日涨幅」,实际算的是相对今日开盘的涨幅。改它会影响所有买入,要单独评估。已记台账(持仓管理系统第 002 条),本次没改。
3. **两处量比口径不一致。** 择时决策系统的弱市闸按「从开盘算的已过时段」折算,而新代码按「分钟线实际覆盖的时段」折算。后者才对(行情库那张键是滚动窗口,不保证从开盘存起)。改前者会影响所有建仓仲裁,已记台账(择时决策系统第 003 条),本次没改。
---
## 十、台账在哪
每个仓库各有一份,记的是每一条影响下单或候选单的规则改动、依据、预期、复核日期。
- 选股系统:`akg-factor-bridge/docs/复盘决定台账.md`,最新到第 057 条
- 持仓管理系统:`tradingSystem/docs/复盘决定台账.md`,第 001 到 005 条
- 择时决策系统:`bionic_trader/docs/复盘决定台账.md`,第 001 到 004 条