📋 期货AI基金经理 · 工作日报 (交易日 2026-10-20_IFOS同类隐患排查) ⏭ 跳到最新(2026-11-12)
# 2026-10-20 IFOS 同类隐患专项排查(对照 TLM 失控开仓事故)
> 触发:`tq-strategy-tlm` 于 10:03 发生"成交待确认窗口重复挂单 → 2 秒 22 手"事故。
> 用户选定"把 IF 超卖策略也过一遍同类隐患"。
> 对象:`strategy_if_oversold.py`(`tq-strategy-ifos`,账户 18610083060,IF 主连 1 手)
---
## 一、结论先说
**IFOS 结构上不存在 TLM 那种"滚雪球式开仓"**,根因有三层天然防护:
| 防护 | 说明 |
|---|---|
| 每轮从**账户实仓**读持仓 | `evaluate()` 先 `net_position()`,有仓就只走"持有/离场",不会重复开 |
| **每日只动作一次** | `state['last_acted'] == today` 即 `continue` |
| **无被动挂单驻留** | 只有 `ensure_filled()` 的限价单,4 秒内未成就撤,不挂在盘口等成交 |
但排查出 **4 个竞态/可观测性隐患**(已修)和 **3 个设计层风险**(未改,需你决策)。
---
## 二、已修复(4 项,均不改变交易逻辑)
| # | 隐患 | 为什么危险 | 修复 |
|---|---|---|---|
| 1 | **启动不清遗留挂单** | 进程崩溃/重启时 `IFOS1_` 的活动挂单会留在盘口,可能在**非信号时点**成交 → 产生状态外持仓,破坏 H-O1 的"open[i+1]"执行口径(TLM 事故同族) | 新增 `cancel_stale_orders()`,启动时只撤 `IFOS1_` 前缀的 ALIVE/PENDING 单,不误伤其他策略 |
| 2 | **成交回报延迟的竞态** | `ensure_filled` 4 秒未看到 FINISHED 就撤单重试;若服务端回报慢于 4 秒,可能"已成交却判失败 → 再开一手" | 开仓前**二次确认净仓=0**,非 0 直接跳过并记日志(竞态窗口压到最小) |
| 3 | **平仓数量的 `or LOTS` 回退** | `abs(net_position()) or LOTS`:读仓失败返回 0 时会盲卖 1 手(无多仓时被交易所拒 → 触发告警邮件) | 平仓前先校验净仓 `> 0`,否则跳过;不再回退到固定手数 |
| 4 | **MISS 无日志** | 代码注释承诺"未运行则记 MISS 并写日志",实际未实现 → 前推证据链缺口 | 窗口外补记 MISS(每交易日一次,仅交易日) |
**附加**:开仓前增加**可用资金预检**(1 手 IF 需可用 ≥ 名义×12%×1.3 ≈ 19.7 万 @IF 4200),从源头消灭"开仓保证金不足"告警。
---
## 三、设计层风险(未改,建议你决策)
| # | 风险 | 说明 | 建议 |
|---|---|---|---|
| A | **无硬止损** | 预注册口径就是"RSI>70 或持仓≥250 根"才离场,没有价格止损。1 手 IF 名义 ≈ 123 万(账户约 97 万),10% 逆向 ≈ -12.3 万 | 若要坚持预注册口径,就别加止损(否则证据失效);但要接受单笔大回撤。**不要在两可之间偷偷加** |
| B | **与 TLM 共用保证金** | 同账户 18610083060;TLM 2 手占 ~8.2 万,IF 1 手需 ~14.8 万。当前可用 89 万,充足 | 若将来 TLM 提高手数或 IF 加仓,需做联合保证金预算;现已有资金预检兜底 |
| C | **重启会重置 MAXHOLD** | 本地 `entry_bar_date` 丢失时以"当天"为持仓起点 → 最长持仓可能超过预注册的 250 根 | 已在日志里显式提示;若要严格,应把 `entry_bar_date` 落盘到账户对账可还原(如按账单反推) |
---
## 四、验证
| 项 | 结果 |
|---|---|
| `py_compile` | 通过 |
| `test_ifos_guards.py` | ①只撤 IFOS1_、不误伤 TLM 挂单 ②资金预检阈值 ③6 项静态检查全过(含旧回退已移除) |
| 重启(10:55,窗口外,无持仓) | `启动时净持仓 = 0 手`、无遗留挂单、无异常;服务 active |
| 当前账户 | 权益 974,913.64 / 可用 892,517.64 / 保证金 0 / IF 持仓 0 |
---
## 五、顺带确认
- IFOS 今日 09:30 判定为 **"无操作 | 空仓等待 RSI=24.6"** —— 正确:策略要求的是"由 ≥30 下穿至 <30 的那一根",RSI 已在 30 下方多日、无新下穿事件,故不开仓(不是漏单)。
- 账户 60 上现在只有 TLM 的 2 张被动单,无 IFOS 遗留单。