处理评述问题
This commit is contained in:
parent
bcf9ff0481
commit
1d003eee1a
|
|
@ -0,0 +1,165 @@
|
|||
# 交接:三系统量化交易 · 2026-08-07 开盘前
|
||||
|
||||
> 这份是给下一个对话窗口用的。详细节点在 `tradingSystem/DEVLOG.md`,那里按时间记着每一条
|
||||
> 「做了什么 / 动了哪些文件 / 部署方式 / 真机判收 / 还欠着什么」。**这份只写坐标、状态和待办,
|
||||
> 需要细节就去翻 DEVLOG,不要凭这份文件的概括去改代码。**
|
||||
>
|
||||
> 另一条更要紧的:**以项目代码为准,不要迷信文档。** 上一轮交接文档里有大量上一个对话
|
||||
> 汇总时产生的幻觉(例如把已经存在的 `A_OPEN` 说成不存在)。读代码,不读文档的结论。
|
||||
|
||||
---
|
||||
|
||||
## 一、三系统与部署方式(改错部署方式等于白改)
|
||||
|
||||
| 系统 | 位置 | 改码怎么生效 |
|
||||
|---|---|---|
|
||||
| **tradingSystem(PMS,仓位管理)** | `factor@factorevaluation` | 源码**打进镜像**,必须 `make deploy`;跑 `make test` 见 `ALL SUITES PASS`(当前 469 例);盯盘 `make watch` |
|
||||
| **bionic_trader(决策系统)** | `192.168.16.188:38000` | 挂载卷,`git pull` 后 `docker compose restart backend-api worker-brain`;**新增 env 必须 `docker compose up -d --force-recreate`**,restart 不重读 env |
|
||||
| **akg-factor-bridge(因子桥)** | `factorevaluation`,容器 `akg_factor_bridge`,API 8300 | 常驻 API 改码要 compose restart |
|
||||
|
||||
**时区(08-06 查实、08-07 再证一次,按「哪种时间」分,不能按「哪个系统」一刀切)**
|
||||
|
||||
- **容器时钟与容器日志正文** —— 北京时间,**不加八小时**。证据:bionic 容器内 `date` = `15:37 CST`。
|
||||
- **数据库时间列**(`strategy_audit_log.created_at`、`strategy_daily_results.updated_at`)—— **UTC,要加八小时**。证据:08-07 北京 09:03 时该库 `SELECT NOW()` = `2026-08-07 01:03:32`。
|
||||
- **日期列**(`audit_date`、`trade_date`)—— 北京日期,不换算。
|
||||
- `docker logs -t` 前缀是 UTC,跟正文里 Python logging 的时间不是一个口径,别混读。
|
||||
|
||||
> 上一轮交接文档写的是「bionic 容器时钟是 UTC,先加八小时」,**错的**,已在 DEVLOG 头部改正。
|
||||
|
||||
---
|
||||
|
||||
## 二、规矩(不变,逐条都被真实事故验证过)
|
||||
|
||||
1. **先出方案再动手。** 不要边想边改。
|
||||
2. **中文可读性第一**:写完整自然句、不自造缩写、不发明术语。(我发明过「干跑」,项目自己的词是「试算」,被当场纠正。)
|
||||
3. **只做加法。** 动线上系统只加不改,改既有行为要单独提、单独拍板。
|
||||
4. **宁可空池。** 数据不干净就交空的,不要凑。
|
||||
5. **关键路径禁止丢弃返回值**(静默失败是这个项目的头号 bug 模式,有 48 例专项单测盯着)。
|
||||
6. **全程 Docker**,不给宿主机直跑 pip / python / psql。
|
||||
7. **每条命令必须标注运行在哪台机器,一块代码里只放一台机器。**
|
||||
8. **判收标准是真机各见一次**,不写「应该没问题」。
|
||||
9. **写回 Mac 的文件以 written 回执加 md5 为准。**
|
||||
10. **测试脚本由用户在实机上跑**,跑完把结果贴回来;不要自己跑复杂测试。
|
||||
11. **里程碑要提示用户及时创建/上传到项目目录。**
|
||||
12. **动 tradingSystem 以外的系统之前先答三题**,第一题是「是否影响了原有业务系统」。决策系统本来就不管仓位,要加仓位信息只能单独处理 PMS 那部分逻辑。
|
||||
|
||||
**三个不许重犯的误判**(外加这轮新增的第四个)
|
||||
|
||||
1. 把巧合当证据。
|
||||
2. 时间不换算就下判断。
|
||||
3. 推理没落地就当结论。(这轮又犯了一次:我推断「新建仓没部署,所以那些 `PMS_REJECT` 不可能来自它」,而用户当时已经盘中部署了。)
|
||||
4. **新增:把「我没改过这个字符串」当成结论交付。** 今早那个「【手动重跑AKG_PLAN】」,正确做法是全仓库检索出唯一写入点、把调用链一行行走通、再用落库时刻查实,而不是止步于「不是我改的」。
|
||||
|
||||
---
|
||||
|
||||
## 三、当前系统状态(2026-08-07 开盘前)
|
||||
|
||||
- **新建仓(OPEN)自主提议已上线并跑过实盘**,`PMS_OPEN_AUTONOMY = full`,QMT 是模拟池。
|
||||
- **研判闸已真正接通**(`PMS_JUDGE_API_BASE` 之前一直是空的,08-06 才第一次真发请求)。
|
||||
- 决策系统的盘中买入信号已接进 PMS(此前一直被丢在门口)。
|
||||
- 两个 bug 已修:研判请求体的 `Decimal` 序列化、运维口径文本污染股票评述。
|
||||
|
||||
**最近提交**
|
||||
|
||||
| 仓库 | 最新提交 | 部署状态 |
|
||||
|---|---|---|
|
||||
| tradingSystem | `bcf9ff0 08-07 09:13 处理评述问题` | ✅ 已 `make deploy` + `make test` 通过(用户确认) |
|
||||
| bionic_trader | `6e82dcb 08-07 09:14 处理评述问题` | ⚠️ **未部署**,等收盘后 `docker compose restart worker-brain` |
|
||||
| akg-factor-bridge | `d076c96 08-05` | 本轮未动 |
|
||||
|
||||
---
|
||||
|
||||
## 四、08-06 → 08-07 做完的事(细节见 DEVLOG 同名节点)
|
||||
|
||||
1. **新建仓动作,两侧代码写完**。PMS 侧动了 `action_engine`(新增 `eval_open` / `scan_open`)、`proposal_service`(`_scan_open` / `_route_one` 的 OPEN 分支)、`judge`(OPEN 硬数字裁剪,只送定性材料不送仓位数字)、`exec_advisor`(参照位漂移保护)、`exec_timing`(窗口末日强制完成只对命令生效)、`signal_rules` / `signal_service`(新增 `NOTE_BUY`)、`param_store` / `settings`。新增 `test_batch12_units.py` 44 例,全量 469 例通过。bionic 侧只动 `tasks_intraday.py` 的两个 `PMS_JUDGE` 块(48 增 4 删),不加 env 所以 restart 即可。
|
||||
2. **决策系统买入信号接进 PMS**:并入既有 Redis 信号链,不轮询。
|
||||
3. **窗口末日追高修正**:`hard_gate` 的 `is_command` 改成必填无默认值,自主买入在窗口末日不强制完成、到期作废(可以接受买不上);卖出侧故意不动。
|
||||
4. **跳过原因分得开**:`skip` 从集合改成带原因的字典,四种处境(在途提议 / 在途指令 / 规则闸拒过 / 研判闸驳回)各有各的话。
|
||||
5. **研判闸的 `Decimal` 崩溃**(危害渐进,值得记住):`_recent_ledger()` 把 `price_at`(DECIMAL 列)塞进请求体,`requests.post(json=)` 序列化不了。只要一只票的评审账本里有过任何一行,它的研判就必然失败,而账本只会越积越多——过几天几乎所有票的研判都会失败并降级人工确认,而每一条看起来都只是「研判不可用,降级人工确认」这种系统里天天有的正常降级。修法是在请求出口统一做 `jsonable()` 递归转换,不是修单个字段。
|
||||
6. **运维口径护栏(今早)**:见下节。
|
||||
|
||||
---
|
||||
|
||||
## 五、今早这条单独说:【手动重跑AKG_PLAN】
|
||||
|
||||
**现象**:页面上部分股票的评述里冒出「【手动重跑AKG_PLAN】」这种看不懂的字段。
|
||||
|
||||
**根因**(全部源码验证,非推测):`bionic_trader/scripts/rerun_pool.py:237-238` 拼出
|
||||
`【手动重跑】手动重跑池 AKG_PLAN`,然后 `delay(c, reason, None, target_date)` ——
|
||||
**第二个位置参数不是留痕字段,是 `reviewer_feedback`,风控官质询通道**。
|
||||
文本不带「【盘中」前缀,`IntradayClassifier` 返回 None,于是掉进 `elif reviewer_feedback:`,
|
||||
被拼进提示词的 `[📢 CRITICAL CHALLENGE FROM RISK OFFICER]` 段,后面跟着
|
||||
`You MUST address this in your analysis`。那是命令,大脑照办写进 `analysis`,
|
||||
再经 `save_to_database` 覆盖进 `strategy_daily_results.analysis_summary`。
|
||||
|
||||
**比字段本身重要得多的收获——悬项二从推测变成实证。** `rerun_pool` 落库是
|
||||
`ON DUPLICATE KEY UPDATE`,把 `signal_type / support_level / pressure_level /
|
||||
analysis_summary` 一起就地覆盖。查实的落库时刻(库时钟 UTC,下表已换算北京时间):
|
||||
|
||||
| trade_date | 行数 | 落库时刻(北京) | 当时是什么时候 |
|
||||
|---|---|---|---|
|
||||
| 20260806 | 16 | 08-06 22:32 → 22:45 | 收盘后,安全 |
|
||||
| 20260805 | 18 | 08-05 22:30 → **08-06 11:04** | **盘中**,改写的是当时正被读的昨夜结论 |
|
||||
| 20260804 | 11 | **08-05 13:04** → 08-07 00:50 | **盘中**,补录历史日 |
|
||||
|
||||
这张表下游有两个读者:bionic `pms_advisor`(支撑压力位算 PMS 买卖区间、`signal_type` 走
|
||||
`BAD_Y_SIGNALS` 闸)与桥 `pool.py` 的 `BAD_SIGNALS`(决定把哪只票请出候选池)。
|
||||
所以「盘中不跑 push-pool」这条纪律不只针对桥,**`rerun_pool` 同样在内**。
|
||||
|
||||
**改法(两处,缺一不可)**:`rerun_pool.py` 下发固定传 `None`(根治),`--reason` 保留但只印在
|
||||
脚本输出里;`tasks_brain.py` 加 `_is_ops_note()` 前缀护栏认
|
||||
`【手动重跑】/【运维】/【回补】`,先打日志再置空(兜底)。只做根治不做兜底不行——脚本用法
|
||||
示例明写着鼓励人手填 `--reason "调整X因子后重跑"`。新增
|
||||
`scripts/selftest_ops_note_guard.py` 24 项,做过三次变异验证确认它真会失败。
|
||||
|
||||
**已污染的评述救不回来**:就地覆盖,没有历史表。
|
||||
|
||||
---
|
||||
|
||||
## 六、待办(按优先级)
|
||||
|
||||
**P0 — 收盘后第一件事**
|
||||
|
||||
- bionic:`git pull` → `docker exec trader_worker_brain python scripts/selftest_ops_note_guard.py`(见「全部通过」)→ `docker compose restart worker-brain`。没有新增 env,不用 `--force-recreate`;`backend-api` 没动,不用重启它。
|
||||
- 判收第二步:收盘后跑 `rerun_pool.py --group AKG_PLAN --limit 1 --reason "护栏验证"`,确认 worker 日志有「🛡️ 运维口径说明已从提示词中剔除」,且该票新落库的 `analysis_summary` 不含「手动重跑」。
|
||||
|
||||
**P1**
|
||||
|
||||
- 队列里那三条 `PRP_..._OPEN` 提议要在页面上驳回(它们的研判从来没成功过,留着会挡住这三只票的重新评估)。**08-07 早上是否已驳回,未确认。**
|
||||
- 第一周要盯的五个数:每天有几只候选落在买入区间内、研判驳回率、**研判 UNAVAILABLE 率**(Decimal 事故后新加的第五个)、`intraday_exec` 一跳的耗时分布、评审账本每天的行数。
|
||||
- OPEN 的研判驳回率要连着看几天。08-06 是 11 条全 REJECT(14:07–14:38,理由都在谈开新仓,框架是对的),零 PASS。理由引用宏观空头/熊市共振,当天 100% 驳回可能是对的,但 OPEN 的判据里有**双重保守**(「标准应当比加仓类更严」+「宁可错杀不可错放」),要盯几天看是不是压得过死。
|
||||
|
||||
**P2 — 需要用户拍板**
|
||||
|
||||
- **口径三**:信号票是否可以放宽「不追高」或择时闸。背景:信号池与候选池重叠只有 1/67,唯一重叠的 `300570.SZ` 倒在 `NO_CHASE_MA5: 距 MA5 12.22% > 上限 6%`。而那 67 条信号理由全是「放量突破 / 量比 8.55 / 站上关键位」——**按定义就是离 MA5 远的票**。所以口径一(信号只重排序、不放宽任何闸)结构上注定拿不到增量,只有口径三才有真增量。但它动的是「不追高、接受买不上」这条纪律,必须用户决定。
|
||||
- `SZ000800` 有两行打架的定性:`trade_date=20260806` 是 `SELL`(08-06 22:38 写入),`trade_date=20260804` 是 `DROPPED`(08-07 00:50 写入,**晚了两个多小时**)。补录历史日会写出「时间更新、日期更旧」的行,取数方按 `trade_date` 排还是按 `updated_at` 排会拿到不同答案。`pms_advisor` 与桥 `pool.py` 两处口径要对一遍。
|
||||
- 已污染的三批评述(16/18/11 行)要不要收盘后洗一遍。洗=再跑一次全量重算,支撑压力位会再动,只能收盘后做。
|
||||
|
||||
**P3**
|
||||
|
||||
- 给 `industry.get_many` 的 `gp_stock_category` 分支加按日缓存(每跳省几十次库查询,但改的是既有函数的时序行为,单独提、单独拍板)。
|
||||
- `rerun_pool.py` 里 `--dry-run` 的中文说明写的是「干跑」,项目里同类东西叫「试算」,措辞不统一。
|
||||
- 文档补账:`WS_INTEGRATION_STATUS.md` 停在 07-30;`BIONIC_PMS_INTERFACE.md` 要补新建仓这一路(研判闸第五类动作、硬数字裁剪、择时侧零改动)。
|
||||
|
||||
---
|
||||
|
||||
## 七、悬而未决
|
||||
|
||||
| # | 事 | 状态 |
|
||||
|---|---|---|
|
||||
| 二 | 盘中改写 `strategy_daily_results` 顶掉昨夜结论 | **已从推测变实证**,08-05 / 08-06 各发生一次。PMS 侧有 `PMS_OPEN_REF_DRIFT_MAX` 漂移保护,但那是止损不是免疫 |
|
||||
| 四 | 总资产与持仓市值的差额 | 已结:564(08-05)→ 51(08-06 盘中)→ **4.00 元**(收盘后),是时点与价格精度差,不是口径差。**但 `+ sell_return_today` 双算的假设没测过**(当天零卖出),仍开着 |
|
||||
| 八 | `trade_no` 幂等键 | `trade_no` 是随机串(`T-SHADOW-420911c4b8`),不是确定性的 `SHADOW-xxxx#1`。回放到底按 `trade_no` 还是按单调的 `seq` 去重,未确认 |
|
||||
| — | `trading_buy_plan` | 死枝:最新一行停在 07-30,ENTRY_GATE 已关(`ENTRY_GATE_ENABLED=False`),无重复买入风险 |
|
||||
|
||||
---
|
||||
|
||||
## 八、速查
|
||||
|
||||
**关键参数**:`PMS_AUTONOMY`、`PMS_OPEN_AUTONOMY`(新,默认 `full`)、`PMS_JUDGE_ACTIONS`(默认 `FILL,ADD,DCA,SWITCH,OPEN`)、`PMS_JUDGE_TIMEOUT=90`、bionic 侧 `PMS_JUDGE_TASK_TIMEOUT=75`、`PMS_OPEN_REF_DRIFT_MAX=0.03`、`PMS_JUDGE_TICK_BUDGET_SEC=150`、`PMS_OPEN_REQUIRE_WS_CASH=True`、`PMS_OPEN_SIGNAL_PRIORITY=True`、`PMS_PLAN_TOP_N=30`、`PMS_PLAN_TOP=300`。
|
||||
|
||||
**两道闸**:规则闸(`rule_gate.check`,纯代码,所有指令都要过)→ 研判闸(`judge.request` → bionic `POST /api/intraday/pms_judge`,LLM,30–90 秒,只管自主提议,命令驱动不过)→ 自主档位路由(`full` / `propose_only` / `off`)。
|
||||
|
||||
**择时**:实现A = bionic `POST /api/intraday/pms_exec`(读昨夜支撑压力位推买卖区间,秒级);实现B = PMS 内置保守择时(`exec_timing.decide`)。
|
||||
|
||||
**文档**:`DEVLOG.md`(节点日志,**最先读这个**)、`NEW_POSITION_ACTION_PLAN.md`(新建仓方案 V3 + 八步判收)、`BIONIC_PMS_INTERFACE.md`(欠更新)、`README.md`。
|
||||
Loading…
Reference in New Issue