fix: ECR-004 威科夫区间评分硬化与 VP 绘图减负(已审)

评分选 TR、阶段最小跨度、elements_only 门闩、Top-8 VP;无币种独立参数。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-06 18:46:08 +08:00
co-authored by Cursor
parent ac6be80278
commit d3188ca83c
19 changed files with 275 additions and 89 deletions
+1 -1
View File
@@ -21,7 +21,7 @@
- IDEA-002 / `9f1e736`:主站内存泄漏 dispose、首屏单次 analyze、ChanMACD 复用、chan_tv 体验
- ECR-002 Reviewed:拆 `web/services/runtime/`、加深 analyze 契约
- ECR-003 Reviewed:主站威科夫叠层(`chanlun/analysis/wyckoff/` + `include_wyckoff`)→ `081a57a`
- ECR-004 Draft:TR 评分硬化 + VP 少系列 + 阶段/门闩/单测(IDEA-005
- ECR-004 Reviewed:TR 评分硬化 + VP 少系列 + 阶段/门闩/单测(无币种参数
## 硬约束提醒
+4 -2
View File
@@ -2,9 +2,11 @@
## Unreleased — 2026-08-06
### ECR-004L2Draft
### ECR-004L2Reviewed
- 计划:威科夫 TR 评分硬化、主站 VP 绘图减负、阶段/门闩/单测(见 `docs/ECR/ECR-004-wyckoff-harden.md`
- 威科夫 TR 评分选段(防吞前置趋势);阶段非重叠最小跨度
- 主站 VP Top-8 + bins≤24;填充线减负
- `elements_only` 时不跑威科夫;收紧单测(无币种独立参数)
### ECR-003L2Reviewed
+43
View File
@@ -0,0 +1,43 @@
# CODE_REVIEW — ECR-004
**Role:** REVIEWER
**Date:** 2026-08-06
**Scope:** 威科夫硬化(评分 TR / 阶段 / VP 减负 / API 门闩)
**Decision:** Approve
## Evidence
- `chanlun/analysis/wyckoff/range.py``events.py`
- `web/api/analyze.py``chart_tv.js`
- `tests/test_wyckoff.py``web/tests/test_analyze_contract.py`
- IMPL / TEST / ENG SPEC
## Acceptance ↔ Evidence
| Acceptance | Verdict | Evidence |
|------------|---------|----------|
| 合成 TR 边界与起点 | PASS | `abs_start≥12`low/high∈箱体带 |
| VP series 减负 | PASS | Top-8 + 填充 3 + levelsbins≤24 |
| 阶段最小跨度/不重合 | PASS | 链式切分;单测 unique keys |
| elements_only 门闩 | PASS | 契约测试 |
| golden 不变 | PASS | golden 套件 |
| 无币种参数 / 无策略改动 | PASS | diff 范围 |
## 复跑
```text
→ 14 passed
```
## Findings
### Non-blocking
1. 尾部短时可能只输出 A–C(无 D/E)——符合「空间不足截断」规则。
2. 评分权重仍为启发式,实盘 BTC 以外未矩阵验证(本 ECR 明确不做币种表)。
### No blockers
## Decision
**Approve**
+16 -9
View File
@@ -1,7 +1,7 @@
# ECR-004
**Title:** 威科夫区间评分硬化与主站 VP 绘图减负
**Status:** Draft(待 Human/Architect Approve 后编码)
**Status:** Done (Reviewed)
**Date:** 2026-08-06
**Change Level:** L2
@@ -19,7 +19,7 @@
- `chanlun/analysis/wyckoff/range.py` / `events.py`(阶段)启发式与单测
- `web/static/js/app/chart_tv.js` 威科夫 VP/填充绘制路径
- `web/api/analyze.py``elements_only` 时不跑威科夫;可选调低默认 `vp_bins` 上限
- `web/api/analyze.py``elements_only` 时不跑威科夫;默认 `vp_bins` 上限 24
- ESS 文档与契约测试补充断言(不删既有 `wyckoff` 键)
### Forbidden
@@ -28,23 +28,29 @@
- `config/` / `strategies/`
- `/chan_tv`
- 新数据源 / 订单流
- **按币种独立参数表**(全局 ATR 相对即可;当前以 BTC 场景验证)
## DecisionsApprove 时锁定)
- VP**A+C**(前端 Top-N 有量 bin + 服务端 bins 上限 24
- 不做 per-symbol 参数
## Risk
| Risk | Mitigation |
|------|------------|
| TR 结果相对 003 漂移 | 合成夹具锁定高低与起点;文档标明启发式迭代 |
| 前端 VP 观感变化 | 保留 POC/VAH/VAL;密度可用更少线表示 |
| 前端 VP 观感变化 | 保留 POC/VAH/VAL;密度用 Top-N |
| 回归 | 扩展 `tests/test_wyckoff.py` + 既有契约套件 |
## Acceptance Criteria
- [ ] 合成箱体夹具:`trading_range` 高低接近箱体边界,起点不落入明显前置趋势段
- [ ] 开启 VP 时主图新增 series 数显著低于「每 bin 一条」(目标:填充+VP ≤ ~15 或等价合并策略)
- [ ] 阶段输出满足最小跨度或合并退化段;文档说明规则
- [ ] `elements_only=true` 即使 `include_wyckoff=1` 也不返回 `wyckoff`(或明确文档例外——实现选前者)
- [ ] golden 缠论基线不变;相关 pytest 绿
- [ ] TEST/IMPL/CHANGELOG/TRACEABILITY + CODE_REVIEW
- [x] 合成箱体夹具:`trading_range` 高低接近箱体边界,起点不落入明显前置趋势段
- [x] 开启 VP 时主图新增 series 数显著低于「每 bin 一条」(目标:填充+VP ≤ ~15 或等价合并策略)
- [x] 阶段输出满足最小跨度或合并退化段;文档说明规则
- [x] `elements_only=true` 即使 `include_wyckoff=1` 也不返回 `wyckoff`
- [x] golden 缠论基线不变;相关 pytest 绿
- [x] TEST/IMPL/CHANGELOG/TRACEABILITY + CODE_REVIEW
## Rollback
@@ -60,3 +66,4 @@
- 上游: `docs/CODE_REVIEW/ECR-003.md` Findings 15
- PRODUCT_SPEC / ENGINEERING_SPEC: 同目录 ECR-004-*
- TRACEABILITY: Yes
- CODE_REVIEW: `docs/CODE_REVIEW/ECR-004.md` — Approve
+19 -21
View File
@@ -1,45 +1,43 @@
# ENGINEERING_SPEC — ECR-004
**Status:** Draft
**Status:** Approved(实现锁定:评分选段;VP=A+C;无币种参数)
**Date:** 2026-08-06
## Range scoring
替换「仅取最长合格窗口」:
1. 仍在 `lookback` + `tail_reserve` 框架内扫描候选段(步长可保留)。
2. 对每段计算分数,例如:
- `touch_score` = near_hi + near_lo(触边上沿/下沿次数)
- `width_penalty` = width / ATR(过宽扣分)
- `recency_bonus` = 段终点靠近 core 末
- 可选:段内 close 在 [low,high] 比例
3. 取分数最高且满足既有硬门槛(near_hi/lo≥2、inside≥0.75 等)的段。
4. 单测:`_box_df` 断言 `low∈[38,42]``high∈[58,62]`,且 `start` 不早于箱体起始(允许小容差)。
1. 仍在 `lookback` + `tail_reserve` 框架内扫描候选段(步长 -4)。
2. 硬门槛不变:near_hi/lo≥2、inside≥0.75、宽度上限等。
3. 分数:`touch_density*50 + inside*30 - (width/ATR)*3 + min(length/40, 2)`,取最高。
4. 单测:`low∈[38,42]``high∈[58,62]`,起点不早于箱体(容差 8 根);`abs_start_idx >= 12`
## Phases
- 为 A–E 设最小 bar 数(如 ≥3);不足则与相邻段合并或跳过空标签
- 避免 D/E 完全同起止仍输出两条重复色带
- 非重叠链式切分;每段至少 `min_bars=3`
- 尾部空间不足则延长上一段并停止新增(避免 D/E 完全重合双画)
## API gate
```text
if include_wyckoff and not elements_only:
result["wyckoff"] = analyze_wyckoff(...)
result["wyckoff"] = analyze_wyckoff(..., vp_bins∈[10,24])
```
## Frontend VP
默认 `wyckoff_vp_bins=24`,上限 24。
任选其一(ENG 实现时定一种并写进 IMPL):
## Frontend VPA+C
- **A**:只画 volume>0 的 bin,且最多 N 条(按 volume 取 Top-N),POC/VAH/VAL 仍全画
- **B**:用少量水平线 + 透明度映射,或单 series 多段(若 Lightweight 版本支持)
- **C**:服务端默认 `vp_bins` 上限降到 24,前端再 Top-N
区间填充线可从 6 降到 3。
- 填充线 6→3
- 有量 bin 按 volume Top-8 绘制 + POC/VAH/VAL
- 目标:区间填充+边框+VP ≈ ≤15 series 量级
## Tests
- 扩展 `tests/test_wyckoff.py`
- 契约:`elements_only=true&include_wyckoff=1``wyckoff`
- `tests/test_wyckoff.py` 收紧
- `elements_only=true&include_wyckoff=1``wyckoff`
- 不改 golden 缠论 JSON
## Non-goals
- 按币种独立参数(全局 ATR 相对;以 BTC 场景验证)
@@ -0,0 +1,5 @@
# HANDOFF — ECR-004 engineer → reviewer
**Date:** 2026-08-06
已实现并自测 14 passed。请对照 `docs/CODE_REVIEW/ECR-004.md`
+24
View File
@@ -0,0 +1,24 @@
# IMPLEMENTATION_REPORT — ECR-004
**Date:** 2026-08-06
**Status:** Implemented
**Change Level:** L2
## What changed
| Area | Change |
|------|--------|
| `wyckoff/range.py` | 硬门槛上按触边密度/箱内比/宽度评分选最优段(非最长) |
| `wyckoff/events.py` `build_phases` | 非重叠 + 最小跨度;尾部不足则截断 |
| `web/api/analyze.py` | `include_wyckoff and not elements_only``vp_bins` 默认/上限 24 |
| `chart_tv.js` | 填充 3 线;VP Top-8 + POC/VAH/VAL |
| tests | 收紧 TR/事件断言;`elements_only` 契约 |
## Decisions
- VP**A+C**
- **无**币种独立参数(全局 ATR 相对;BTC 场景验证)
## Tests
`docs/TEST_REPORT/ECR-004.md`14 passed 相关套件)。
+1 -1
View File
@@ -1,6 +1,6 @@
# PRODUCT_SPEC — ECR-004
**Status:** Draft
**Status:** Approved
**Date:** 2026-08-06
## Goal
+1 -1
View File
@@ -34,7 +34,7 @@ Trading System(缠论分析引擎 + 可视化 Web;Freqtrade 策略目录独
## Active anchors
- ECR: ECR-004 Draft(威科夫硬化);ECR-002/003 Reviewed
- ECR: ECR-002/003/004 Reviewed(威科夫 + 硬化)
- EXP: N/A
- TRACEABILITY: `docs/TRACEABILITY.md`
- Memory: `docs/AGENT_MEMORY.md`
+5 -6
View File
@@ -1,8 +1,8 @@
# STATE
**owner:** architect
**active_ecr:** ECR-004
**phase:** draft_spec(待 Approve 后实现)
**owner:** idle
**active_ecr:** noneECR-004 Reviewed;待本批提交合入)
**phase:** post-review
**system_version:** v1.0.0
**strategy_version:** unchanged
**updated:** 2026-08-06
@@ -15,10 +15,9 @@
| IDEA-002 | L1 | Done | `9f1e736` |
| ECR-002 | L3 | Done (Reviewed) | runtime 包拆分 |
| ECR-003 | L2 | Done (Reviewed) | `081a57a` 主站威科夫 |
| ECR-004 | L2 | Draft | 威科夫硬化 / VP 减负;见 IDEA-005 |
| ECR-004 | L2 | Done (Reviewed) | 威科夫硬化 / VP 减负 |
## Notes
- ECR-003 已合入;Findings → ECR-004
- ECR-004 待 Human/Architect **Approve** 后再编码
- ECR-004**Approve**14 passed);无币种独立参数
- 未请求新 system tag
+3 -2
View File
@@ -1,7 +1,8 @@
task_id: ECR-004
title: 威科夫区间评分硬化与主站 VP 绘图减负
status: draft
status: done_reviewed
change_level: L2
ecr: docs/ECR/ECR-004-wyckoff-harden.md
idea: docs/IDEA/IDEA-005-wyckoff-harden.md
notes: Follow-up to ECR-003 CODE_REVIEW Findings 1-5. Await Approve then implement.
code_review: docs/CODE_REVIEW/ECR-004.md
notes: A+C VP; no per-symbol params; BTC-oriented validation. Approve 2026-08-06.
+29
View File
@@ -0,0 +1,29 @@
# TEST_REPORT — ECR-004
**Date:** 2026-08-06
**Level:** L2
## Command
```bash
PYTHONPATH=.:web python -m pytest \
tests/test_wyckoff.py \
tests/test_golden_pipeline.py \
web/tests/test_analyze_contract.py \
-q
```
## Result
**14 passed**
| Suite | Coverage |
|-------|----------|
| `test_wyckoff` | TR 边界/起点、Spring+SOS、阶段不重合、VP POC |
| golden | 缠论基线不变 |
| analyze contract | opt-in wyckoff`elements_only` 跳过 wyckoff |
## Notes
- 合成夹具下 `abs_start_idx=20`(箱体起点),高低≈40.1/59.9。
- 主站 VP series 减负无自动化计数;按 ENG Top-8+3 填充实现。
+4 -4
View File
@@ -37,10 +37,10 @@
| ECR-003 | 主站 Lightweight 叠层 | PRODUCT-003 | `index.html` `chart_tv.js` `chart_view.js` | 人工 + 开关接线 |
| ECR-003 | 契约可选键文档 | ENG-003 | `analyze_contract_keys.json` | golden keys file 断言 |
## ECR-004Draft
## ECR-004
| ECR | Requirement | Spec | Code | Test |
|-----|-------------|------|------|------|
| ECR-004 | TR 评分选最优段 | ENG-004 | TBD `wyckoff/range.py` | 收紧 `test_wyckoff` |
| ECR-004 | VP/填充少 series | ENG-004 | TBD `chart_tv.js` | 人工 / 约定上限 |
| ECR-004 | 阶段最小长度 + elements_only 门闩 | ENG-004 | TBD events + analyze | 契约补充 |
| ECR-004 | TR 评分选最优段 | ENG-004 | `wyckoff/range.py` | `test_wyckoff` / `test_range_scoring_skips_pretrend` |
| ECR-004 | VP/填充少 series | ENG-004 | `chart_tv.js` Top-8 + 填充 3bins≤24 | 人工 + ENG |
| ECR-004 | 阶段最小长度 + elements_only 门闩 | ENG-004 | `events.py` + `analyze.py` | 契约 `elements_only` |