# Dry-Run Decision Checklist — GATED_V1_1_LOCKED ```text Purpose: 上线前不改规则,只验执行链 Stack: Market State → Decision → Frozen Signal Version: GATED_V1_1_LOCKED Mode: dry-run / monitoring only ``` 研究线已收手。本清单是 **operational acceptance**,不是新实验。 --- ## Locked defaults(不可在 dry-run 中改动) | Item | Value | |------|--------| | Strategy | `Wyckoff_BTC_GATED` | | Spring | `V1_BASELINE` FROZEN | | Gate | `market_state in {accumulation, markup}` → allow Spring | | Soft-score | rejected | | Range | observe only(非交易规则) | | gate_version | `GATED_V1_1_LOCKED` | --- ## 1. 信号一致性 上线前逐项勾选: - [ ] 同一根 entry candle 上,`market_state` **只使用已收盘 8h** 数据(无 lookahead;merge 后读的是上一根已完成 bias bar) - [ ] `allow_spring == True` **仅当** `market_state ∈ {accumulation, markup}` - [ ] `allow_spring == False` 当 `market_state ∈ {distribution, markdown, range}` 或缺失 - [ ] Baseline 产生 `SPRING_LONG` 且 Gate block 时:**不下单** - [ ] 同上 blocked 事件:**写入决策日志**(见 §2),与 kept 同 schema - [ ] UTAD(若启用)镜像:`allow_utad` 仅 `{distribution, markdown}`;本清单以 Spring 为主 快速自检(可在 dry-run 启动后抽查最近 N 条日志): ```text assert gate_version == "GATED_V1_1_LOCKED" assert allow ⇒ market_state in {accumulation, markup} assert market_state == "distribution" ⇒ allow == false assert block ⇒ order_not_sent ``` --- ## 2. 日志字段(每条候选信号一行) 必需字段: | Field | Example / notes | |-------|-----------------| | `timestamp` | entry candle open/close time(UTC) | | `pair` | e.g. `BTC/USDT:USDT` | | `signal_type` | `SPRING_LONG` / `UTAD_SHORT` | | `market_state` | accumulation \| markup \| distribution \| markdown \| range \| missing | | `allow` | `true` / `false` | | `gate_version` | `GATED_V1_1_LOCKED` | | `baseline_signal` | `SPRING_LONG`(Gate 前 Baseline 标签) | | `block_reason` | `not_in_allow_set` \| `state_missing` \| `state_lag` \| `""` if allow | 推荐附加(便于监控,非规则): | Field | Notes | |-------|--------| | `bias_bar_time` | 决策所用已收盘 8h bar 时间 | | `accumulation_score` … `range_score` | 诊断用,**不参与默认 Gate** | | `would_enter` | Baseline 是否曾置 `enter_long=1` | | `order_sent` | dry-run 下应为 `allow` 的结果 | Blocked 必须落盘;禁止静默丢弃。 --- ## 3. Dry-run 监控指标 周期性汇总(建议日 / 周): | Metric | 关注点 | |--------|--------| | `kept_n` / `blocked_n` | 量级是否合理,非零且非异常尖刺 | | blocked domain 分布 | **尤其 `distribution` 应仍为主要 block 源** | | kept trade PF / expectancy | 参考,不强求 > ungated baseline | | max DD(kept / 账户) | 应相对 ungated 历史继续偏低 | | range share among blocked | 仅观察;上升不自动改规则 | ### 2023+ OOS 参考阈值(研究窗,非调参目标) | | Gated(研究) | 解读 | |--|---------------|------| | PF | ~1.34(baseline ~1.45) | **不强求超过 baseline** | | DD | ~3.4%(baseline ~7.9%) | **DD 应继续低** | | full DD | ~9.6% vs ~26% | 结构性降 DD 仍是成功标准 | Dry-run 短期 PF 波动 **不触发规则变更**。 --- ## 4. 报警条件 | Severity | Condition | Action | |----------|-----------|--------| | P0 | `market_state` 缺失或滞后(bias bar 过旧 / merge 失败) | 停新开仓,查数据链 | | P0 | Gate 放行且 `market_state ∉ {accumulation, markup}` | 立即停机排查;视为执行链 bug | | P0 | `distribution` 被放行 Spring | 同上 | | P1 | blocked 样本中 `range` **长期主导** 且 kept PF/expectancy 同步恶化 | 记观察票;**不改规则**,升级人工 review | | P2 | kept/blocked 比为 0 或异常尖刺(数据空洞) | 查 feed / 时区 / 8h 对齐 | 报警只服务执行完整性,不服务「再优化一次 Gate」。 --- ## 5. 不允许事项(硬禁) - 不调 Spring(TF / ATR / stoploss / entry 形态) - 不调 soft-score,不把 soft-score 接回默认路径 - 不全样本扫 Gate 阈值 / 状态集合 - 不因短期 dry-run PF 调规则 - 不因 `range` 小样本表现把 range 升格为交易域 - 不默认合并 ETH/SOL 进生产路径 - 不复活 LPS 分支 违反任一条 = 退出 dry-run,回到研究流程(需新证据包)。 --- ## 6. Go / No-Go(dry-run → 有限实盘) **Go**(全部满足): - [ ] §1 信号一致性全部勾选 - [ ] §2 日志字段齐全,blocked 可见 - [ ] §4 无未关闭的 P0 - [ ] 监控窗内 blocked 仍以坏域为主(distribution 不消失为噪音) - [ ] 规则文件与运行配置仍为 `GATED_V1_1_LOCKED` / `state_set` **No-Go**: - 任一 P0 - 日志无法区分 kept vs blocked - 发现非因果 8h 状态 - 有人为改动 Spring / Gate 默认值 --- ## Related - Status: `research/SYSTEM_STATUS.md` - Boundary: `research/VALIDITY_BOUNDARY.md` - Strategy: `strategies/Wyckoff_BTC_GATED.py` - State engine: `engine/market_state.py` - Audit evidence: `scripts/wyckoff_negative_domain_audit_result.json` - Robustness: `scripts/wyckoff_gate_robustness_slices_result.json`