tradingSystem/HANDOFF_2026-08-06.md

11 KiB
Raw Permalink Blame History

交接:三系统量化交易 · 2026-08-06 收盘前

这份东西是写给下一个对话开头的。可以整段贴过去,也可以留在仓库里当阶段存档。

我们在推进三个相互衔接的量化交易系统。请先读项目记忆里的 tradingsystem-bionic-bridgeclock-and-timezonestradingsystem-silent-failure 三篇(都在 08-06 更新过), 背景需要时再读 tradingsystem-ws-channel 和 quant-factor-synthesis工作方式看 feedback-plan-first 和 writing-style-readability。读完再看下文然后等我给任务不要自行开工。


一、三系统与部署方式(改错部署方式等于白改)

tradingSystemPMS持仓管理 跑在 factor@factorevaluation。源码是打进镜像的, 所以改码必须 make deploy,跑完再 make test 看到 ALL SUITES PASS盯盘用 make watch容器时钟是北京时间。

bionic_trader决策系统 跑在 192.168.16.188:38000tlaipro 机)。挂载卷, git pull 之后 docker compose restart backend-api worker-brain 即可生效; 但新增 env 必须 docker compose up -d --force-recreaterestart 不重读 env容器时钟是 UTC。

akg-factor-bridge因子桥 在桥机 factorevaluation,容器名 akg_factor_bridge API 在 8300。常驻 API 改码要 compose restart。容器时钟是 UTC。

线上运行中的系统只做加法。

二、规矩(不变)

先出方案再动手;中文可读性第一,写完整自然句、不自造缩写;只做加法;宁可空池; 关键路径禁止丢弃返回值;全程 Docker不给宿主机直跑 pip/python/psql每条命令必须标注 运行在哪台机器,一块代码里只放一台机器;判收的标准是真机各见一次;写回 Mac 的文件以 written 回执加 md5 为准;看桥和 bionic 的任何时间戳,先加八小时再和对话里的时间对齐。

测试脚本由我在实机上运行,跑完把结果发给你,你不用跑复杂测试。里程碑的代码和文档 请提示我及时创建或上传到项目目录。

三、下一个任务:给动作引擎加「新建仓」动作

要解决的问题:不能每天靠人手工走一遍下命令、排方案那一串。正常应该是上游选股计划 出现之后PMS 按规则自己执行。

已经查清的现状,不用重查:整条链除了「下命令」这一步,其余全是自动的。调度表里 08:40 拉候选池08:50 盘前准备,每分钟跑命令轮询(把已下达的命令排成方案)、盘中执行 (方案转指令 + 自主提议扫描 + 择时出手)、成交入账加轻对账、消化决策系统的盘中信号, 14:50 T 仓平回15:10 日终结算加窗口收口15:30 日报。make t-* 只是这些调度位的手动 等价物,是排查用的,不是日常流程。

唯一要人的就是下命令,而且是刻意的:计划回答「能买哪些」,命令回答「今天打算投多少」。

三条路,性质完全不同

一是把下命令挂成定时,每天自动下一条升仓命令。改动最小,加一个调度位;代价是仓位单向 增长到撞上组合上限,而且不看市场状态。

二是把自主档位调到 full。这条解决不了问题——它只让已有持仓的增持类提议不用人确认, 而动作引擎产出的只有补足底仓、回踩补仓、盈利加仓、减持这四类,根本没有「新建仓」 这个动作

三是给动作引擎加新建仓动作,让自主提议除了管已有持仓,也能从候选池里挑新票,走同样的 规则闸、研判闸、档位分流。这才对得上要解决的问题,是新逻辑不是新调度位。

我选第三条。先出方案,我拍板之后再动手。

开工前要知道的约束:择时读的那张 strategy_daily_results 表,在盘中跑 push-pool 触发补扫时会被就地改写(详见第六节)。开发期靠「盘中不跑 push-pool」这条纪律规避 没有改代码。设计新建仓动作时要把这件事放进考虑,别让无人值守的建仓建在会漂移的输入上。

四、当前系统状态2026-08-06 盘中,约 11:15

账户总资产 2,000,288.86,可用 1,881,764.86,组合仓位 5.92%。参数:总规模 200 万, 自主档位 propose_only下发模式 ws择时档位 A组合上限 70%,单股上限 8%,最多 20 只, 执行窗口默认 3 个交易日。

持仓三只600150.SH 一千七百股、可卖一千二、摊薄成本 34.625、安全垫 +0.16%,参考位 支撑 34 压力 37 止损 34来源 bionic002335.SZ 一千九百股、可卖零、摊薄成本 30.984、 安全垫 +0.41%000035.SZ 一百股、可卖零、摊薄成本 5.028、安全垫 -1.55%决策系统对它 的定性是 SELL

在途四条000035 的减持一百股来源自主提议11:13 我在页面人工放行002335 的清仓 一千九百股(来源决策系统风控信号,置信度 95%002518 的买入九百股(被新装的定性闸 拦着窗口今天到期000063 的买入一千七百股(现价高于买入区间上沿,不追,窗口今天到期)。 前两条都要等明天 T+1 才能出手。

五、08-05 到 08-06 做完的事

买入侧补上了一道闸,两侧都已部署,真机判收成立。 起因是发现候选层的结论对执行层 完全不可见:桥用 strategy_daily_results.signal_type 落在 SELL、AVOID、DROPPED 就把票请出 候选池,而决策系统的择时应答读同一个字段、放进 observed.y_signal 原样回传却从不用它判断, PMS 又只解析 verdict、limit_price、reason。同一条结论一边当判决一边当摆设。 600841 就差一根 3.3% 的阴线会被买进来。

改动:决策系统 app/services/pms_advisor.pyBAD_Y_SIGNALS 常量和买入分支的闸, config/settings.py 加开关 PMS_EXEC_BLOCK_BAD_Y_SIGNALPMS 侧 app/core/rule_gate.pyBAD_SIGNAL 检查项并把定性无条件写进 hard_numbersapp/services/exec_advisor.pyobserved.y_signal 存进 advice 并挂到决策上,app/services/executor.py 传进规则闸 flags scripts/test_batch3_units.py 加一条用例。08-06 真机拦下第一笔002518 停在 PROPOSED、 成交 0、理由是新写的那句。 PMS 那道 BAD_SIGNAL 至今没真的触发过(决策系统先回 WAIT 就走不到规则闸),符合当初「第二道闸平时空转、只为留痕」的预期。

其余600841 的在途买入指令已撤(回执是 cancelled:0 加「仅本地置撤销」PROPOSED 从没 下发过子单时走的就是这个分支freeze 的 manifest.json 判收通过08-03 和 08-04 两天 都在XXL 例行调度的根因查实——从来没有自动拉起过,日志里只有手动触发的行,配置已重新设计。

六、悬而未决(按优先级)

  1. 主线:动作引擎加新建仓动作,见第三节。
  2. 昨夜结论会被盘中补扫就地改写。push-pool 跑完触发增量补扫,补扫用 trade_date=昨日 就地覆盖已有那行,而 fetch_yesterday_strategy 是取最新一行、不按日期过滤。实证: 000035 在 09:53 成交时定性是 WATCH、压力 5.2,补扫之后变 SELL、压力 5.15002335 的支撑 从 31.27 变成 29.00,差 7.3%。开发期靠「盘中不跑 push-pool」规避代码未改。 真要修,最小加法是给 fetch_yesterday_strategy 加「只取今天之前」的过滤,但那样盘中 补扫的产出就完全用不上了,是不是想要的要先拍板。
  3. 卖出侧的镜像缺口。桥对「持仓且形态恶化」只警示、明确不出池,而 PMS 没有任何机制 会因为决策系统的定性去减仓——研判闸只管买入侧的补足、加仓、补仓,规则闸的冻结和黑名单 只挡增持。买入侧补上了卖出侧还是空的。000035 现在就是这个状态。
  4. 总资产与持仓市值的口径。总资产来自 QMT 的 ws 资金快照,被组合刹车当权益基准用 高水位与回撤15:10 跑);持仓市值是 PMS 拿 Redis 分钟线自算的。08-05 两边差 564 元, 08-06 盘中只差 51 元。倾向是取数时点差不是口径差,收盘后价格静止时再对一次才能定案。
  5. 时区显示错位八小时_today_exit_verdict 把 created_at 直接截成「01:35」拼进理由 传到 PMS 页面和北京时间戳并排显示。给 bionic 容器设 TZ=Asia/Shanghai(新增 env 必须 force-recreate或者格式化时显式转。低优先。
  6. 600150 最后五百股买在区间上沿。区间连续四个交易日都是 [33.66, 34.9] 没变过, 今天现价正好等于上沿,闭区间判定放行,成交在 34.89,摊薄成本被从 34.514 抬到 34.625、 安全垫从峰值 +1.99% 压到 +0.01%。这是分批建仓遇上区间长期不变的固有副作用。 要不要改(现价等于上沿时不买,或者区间连续 N 天不变时降档)是策略取舍,未拍板。
  7. XXL 例行调度已重新配置,验证点是看桥的 data/xxl_build.log 有没有在北京时间 07:10 自动长出新行(日志是 UTC会写成前一天的 23:10
  8. trade_no 格式核验(关系 S3 收尾函第一节的阻断项): docker compose run --rm --no-deps pms-web python scripts/ws_smoke.py inbox --type trade --width 600。 是 SHADOW-xxxx#1 这种确定式就闭环,还是 T-SHADOW 随机串就继续追。这条一直没做。
  9. 命令目录里 FREEZE_STOCK 的说明写着「在途买入撤销」,与实现不符(它是参数类命令、 没有 planner只让规则闸的冻结项拦文案要补账。
  10. 文档补账:WS_INTEGRATION_STATUS.md 停在 07-30BIONIC_PMS_INTERFACE.md 第三节要 加一句新闸README 待办 9 和 10 标判收。
  11. 老悬项不变分歧票候选层拦截未拍板AKG_PLAN 并入 TECH_POOL 的共管规矩未拍板; 07-29 那 19 条 SIG_INVALID 未查明。

七、这轮我犯过的三个误判,别重犯

一是看见巧合就当线索。 600150 的现价 34.900 恰好等于两笔委托的限价,我据此断定取价 有问题还推出「安全垫其实是负的」。实际行情源是活的、分钟线连续34.900 就是当时的 真实价。先验证数据源是否在更新,再怀疑取值。

二是没换算时区。 审计行写着 01:35我当成北京时间于是把一个正常的四分钟赛跑 09:31 咨询干净、09:32 成交、09:35:51 结论落库、09:36 信号到达)判成了「老闸漏读」的 bug 差点去改代码。桥和 bionic 的时间戳一律先加八小时。

三是推理没落地就当结论。 我推定 audit_date 会因为容器在 UTC 而错位一天,实际写入侧 用的是北京日期,洞根本不存在。时间相关的猜测必须先查实际数据再下判断。