feat: ECR-003 主站威科夫分析与图表叠层(已审)

独立 wyckoff 引擎 + 按需 include_wyckoff;主站 Lightweight 绘制区间/阶段/事件/VP。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-06 18:33:57 +08:00
co-authored by Cursor
parent df27b4dde8
commit 081a57a90e
30 changed files with 1330 additions and 52 deletions
+5 -3
View File
@@ -19,18 +19,20 @@
## 近期变更
- IDEA-002 / `9f1e736`:主站内存泄漏 dispose、首屏单次 analyze、ChanMACD 复用、chan_tv 体验
- ECR-002 Draft:拆 `web/services/runtime.py`、加深 analyze 契约
- ECR-002 Reviewed:拆 `web/services/runtime/`、加深 analyze 契约
- ECR-003 Reviewed:主站威科夫叠层(`chanlun/analysis/wyckoff/` + `include_wyckoff`
## 硬约束提醒
- `/api/analyze` 字段可增不可删
- 无 ADR 不改笔/段/中枢/买卖点语义
- 威科夫为独立叠层(ECR-003);勿借机改缠论算法
- 交易 L2+ → RISK_REVIEW + EXPLive 须 Human
## 已知债务
- ~~`runtime.py` 仍过大 → ECR-002~~ **已拆包**(待 CODE_REVIEW
- `chart_tv.js` 单体巨大 → 后续可选 ECR
- analyze 契约已加深(mock HTTP);可再加固定 JSON 快照文件
- analyze 契约已加深(mock HTTP + wyckoff opt-in);可再加固定 JSON 快照文件
- 内存泄漏尚无自动化 heap/监听断言
- `macd_config` POST 写本地 global 的历史 quirks(未改)
- 威科夫启发式参数未做 UI 调参
+8 -1
View File
@@ -2,7 +2,14 @@
## Unreleased — 2026-08-06
### ECR-002L3,待 Review
### ECR-003L2Reviewed
- 新增 `chanlun/analysis/wyckoff/`:交易区间、阶段 AE、Spring/SOS/LPS/UTAD 等事件、区间 VPPOC/VAH/VAL)、量能确认
- `/api/analyze` 按需 `include_wyckoff=1` 返回顶层 `wyckoff`
- 主站「威科夫」开关与 Lightweight 叠层(区间/阶段/事件/VP
- 单测与 analyze 契约 opt-in 断言
### ECR-002L3Reviewed
- 拆分 `web/services/runtime.py` 为包 `web/services/runtime/`state / timeframes / market_data / indicators / analyze / serialize
- 加深 analyze 契约测试(mock HTTP + analyze_chan 键集 + serialize JSON
+77
View File
@@ -0,0 +1,77 @@
# CODE_REVIEW — ECR-003
**Role:** REVIEWER
**Date:** 2026-08-06
**Scope:** 工作区未提交 ECR-003(相对 `origin/dev` @ `df27b4d`
**Decision:** Approve(带非阻断 Findings;建议合并前勿提交 `.DS_Store`
## Evidence loaded
- `chanlun/analysis/wyckoff/{engine,range,events,volume_profile}.py`
- `web/api/analyze.py``include_wyckoff`
- `web/templates/index.html``chart_view.js``macd_ui.js``chart_tv.js` 威科夫块
- `tests/test_wyckoff.py``web/tests/test_analyze_contract.py`
- ESSECR/PRODUCT/ENG/IMPL/TEST/HANDOFF
## Acceptance ↔ Evidence
| Acceptance | Verdict | Evidence |
|------------|---------|----------|
| `include_wyckoff=1` 返回约定键;默认不强制 | PASS | 契约测试;默认无 `wyckoff` 键 |
| 合成 TR + 事件;VP POC | PASS | `test_wyckoff.py`12 相关套件全绿) |
| 主站可开关绘制 | PASS | 主开关按需拉取;子项本地重绘 |
| golden 不变 | PASS | `test_golden_pipeline` |
| 未改缠论算法 / strategies / chan_tv | PASS | diff 范围核对 |
| ESS 闭环 | PASS | IMPL/TEST/TRACE/CHANGELOG/本文件 |
## 复跑
```text
PYTHONPATH=.:web python -m pytest \
tests/test_wyckoff.py tests/test_golden_pipeline.py \
web/tests/test_analyze_contract.py -q
→ 12 passed
```
## Findings
### Important(不挡 Approve,建议跟进)
1. **交易区间易吞并前置趋势**
`detect_trading_range` 从最长窗口向下搜,合成夹具下 `abs_start_idx=0`,箱体前下跌段被算进 TR。单测只断言「有区间 + 有事件」,未锁定高低/起点。
*建议:* 用「宽度/触边密度」评分取最优段,或要求近端触边;测试断言 `high≈60/low≈40` 与起点靠近箱体。
2. **VP 叠层系列数偏多,可能加压自动刷新内存**
开启 VP 时约每个 bin 一条 `addLineSeries`(默认 ~50),再加区间填充/阶段。与 IDEA-002 内存修复同路径全量重建时放大。
*建议:* 只画非零 bin 或合并为少量 series / histogram;或限制 `vp_bins` 上限到 24。
### Medium
3. **阶段 C–E 在事件扎堆时常退化重叠**
夹具输出中 D/E 起止几乎相同;状态机按事件锚点硬切,缺少最小阶段长度。展示可用,语义偏弱。
4. **`elements_only=true` 仍可能跑威科夫**
威科夫挂在路由末尾,不依赖 `not elements_only`。主站当前不这么发,但契约上奇怪;建议与主周期分析同门闩。
5. **单测断言偏松**
`Spring in types or SOS``abs(poc-50)<2` 对回归保护不足。
### Low
6. 失败时 `wyckoff.error` 回传异常字符串(与结构区 print 风格一致,信息暴露轻微)。
7. 事件 marker 一律 `arrowUp`(跌破类也可 `arrowDown`)。
8. 工作区 `.DS_Store` 脏文件——**勿纳入 commit**。
### No blockers
未发现:契约删键、缠论语义改动、策略/config 改动、未鉴权危险写操作、主站误引 WS。
## Decision
**Approve**
可合并提交(排除 `.DS_Store`)。Important #1/#2 可开后续 L1/L2,不阻塞本 ECR 着陆。
## Next owner
`engineer` / Human — commit(勿含 `.DS_Store`);可选跟进 TR 评分与 VP 绘图优化。
+62
View File
@@ -0,0 +1,62 @@
# ECR-003
**Title:** 主站威科夫分析与图表展示
**Status:** Done (Reviewed)
**Date:** 2026-08-06
**Change Level:** L2
## Change
在主站 `/` 增加威科夫交易区间、阶段(A–E)、关键事件(Spring/SOS/LPS/UTAD 等)、区间内简易 VPPOC/VAH/VAL)与量能确认;按需接入 `/api/analyze`
## Motivation
用户需要在缠论图上叠加威科夫结构解读;与现有结构区语义分离。
## Scope
### Allowed
- 新建 `chanlun/analysis/wyckoff/`
- `/api/analyze` 增加可选 `include_wyckoff` 与响应字段 `wyckoff`(可增不可删既有字段)
- 主站 UI 开关与 Lightweight 绘图
- 单测 + ESS 文档
### Forbidden
- 修改笔/段/中枢/买卖点算法语义
-`config/` / `strategies/`
- `/chan_tv` Study
- Vite/React、主站 WebSocket 实时(另 ECR
## Risk
| Risk | Mitigation |
|------|------------|
| 启发式误标 | 规格写明启发式;UI 可关;单测合成形态 |
| 负载 | 默认关闭,勾选才计算 |
| 与结构区混淆 | 独立开关与字段名 |
## Acceptance Criteria
- [x] `include_wyckoff=1` 返回约定 `wyckoff` 键;默认不强制计算
- [x] 合成 fixture:能检出 TR + 至少一类事件;VP POC 可测
- [x] 主站可开关绘制区间/阶段/事件/VP
- [x] golden 缠论基线不变
- [x] TEST/IMPL/CHANGELOG/TRACEABILITY + CODE_REVIEW
## Rollback
`git revert`;关闭 UI 开关即可无图面影响。
## Risk Review
- `docs/RISK_REVIEW/ECR-003.md` — N/A(展示分析,非 Live 策略)
## Linked
- IDEA: `docs/IDEA/IDEA-004-wyckoff-main.md`
- PRODUCT_SPEC / ENGINEERING_SPEC: 同目录 ECR-003-*
- EXPERIMENT: N/A
- TRACEABILITY: Yes
- CODE_REVIEW: `docs/CODE_REVIEW/ECR-003.md` — Approve
@@ -0,0 +1,46 @@
# ENGINEERING_SPEC — ECR-003
**Status:** Approved
**Date:** 2026-08-06
## Package
`chanlun/analysis/wyckoff/`
- `engine.py``analyze_wyckoff(df) -> dict`
- `range.py` — 交易区间检测(ATR 容差震荡箱)
- `phases.py` — AE 状态机
- `events.py` — Spring/SOS/LPS/UTAD(及 distribution 对称)
- `volume_profile.py` — 区间内分桶 VP
- `__init__.py` — 导出 `analyze_wyckoff`
## API
`GET /api/analyze?include_wyckoff=1``result["wyckoff"]`
```json
{
"trading_range": {"start_time","end_time","high","low","mid","active"},
"bias": "accumulation|distribution|unknown",
"phases": [{"phase","label","start_time","end_time"}],
"events": [{"type","time","price","note","volume_ratio","volume_ok"}],
"volume_profile": {"bins":[{"price","volume"}],"poc","vah","val","bin_count"},
"volume_confirm": {"avg_volume","event_checks":{}}
}
```
默认 `include_wyckoff` 假:可不返回或返回 `null`(实现选:不返回键以减负)。
## Detection heuristics
1. ATR(14) 容差;扫描最近窗口找高低点接近的连续段作为 TR。
2. 阶段:价格在 TR 内相对位置 + 假破/真破时间序。
3. Spring:下破 TR.low 后收回且收盘回到区间内;量能相对均量判断。
4. SOS:收盘站上 TR.high 且放量。
5. LPSSOS 后回踩不破 mid/high 带且缩量。
6. UTAD:上破后跌回区间内(派发)。
7. VPtypical=(H+L+C)/3volume 加权分桶,VA≈70% 围绕 POC。
## Frontend
主站 checkbox + `chart_view` 传参;`chart_tv.js` 绘制。
@@ -0,0 +1,27 @@
# HANDOFF — ECR-003 engineer → reviewer
**Date:** 2026-08-06
**From:** engineer
**To:** reviewer
## Summary
主站威科夫 L2:独立分析包 + 按需 API + Lightweight 叠层。
## Artifacts
- IMPL: `docs/IMPLEMENTATION_REPORT/ECR-003.md`
- TEST: `docs/TEST_REPORT/ECR-003.md`
- SPEC: PRODUCT / ENG `docs/*/ECR-003-wyckoff-main.md`
- RISK: N/A(展示分析)
## How to verify
```bash
PYTHONPATH=.:web python -m pytest \
tests/test_wyckoff.py \
tests/test_golden_pipeline.py \
web/tests/test_analyze_contract.py -q
```
主站勾选「威科夫」→ 区间/阶段/事件/VP 可见。
+26
View File
@@ -0,0 +1,26 @@
# Idea: 主站威科夫分析与图表展示
## Problem
主站仅有缠论叠层与结构价值区,缺少威科夫交易区间、阶段与关键事件的可解释展示。
## Observation
仓库无 Wyckoff 模块;`ChanZone` 是中枢+EMA 聚类,语义不同。主站 Lightweight 已有按需 `include_structure_zones` 模式可复用。
## Hypothesis
独立 `chanlun/analysis/wyckoff` + `/api/analyze?include_wyckoff=1` + 主站开关绘图,可在不碰缠论算法的前提下交付区间/阶段/事件/VP。
## Expected Impact
主站可叠加威科夫结构,辅助研判;与结构区开关并存。
## Change Level Guess
**L2**(新市场结构语义与图面;不改 strategies → EXP N/A
## Next
- [x] ECR-003
- [ ] 实现 + 测试 + Review
+30
View File
@@ -0,0 +1,30 @@
# IMPLEMENTATION_REPORT — ECR-003
**Date:** 2026-08-06
**Status:** Implemented
**Change Level:** L2
## What changed
| Area | Change |
|------|--------|
| Engine | 新建 `chanlun/analysis/wyckoff/`:交易区间、AE 阶段、Spring/SOS/LPS/UTAD/SOW/LPSY、区间 VPPOC/VAH/VAL)、量能确认 |
| API | `/api/analyze` 按需 `include_wyckoff=1` 返回顶层 `wyckoff`;默认可不计算 |
| Contract | `analyze_contract_keys.json` 扩展为 required + optional_when |
| UI | 主站「威科夫」及子项开关;Lightweight 绘制区间/阶段/事件/VP |
| Tests | `tests/test_wyckoff.py`;契约 HTTP opt-in |
## Compatibility
- 缠论算法与 golden 基线未改
- `/api/analyze` 既有字段未删;`wyckoff` 仅 opt-in
- 未改 `config/` / `strategies/`;未改 `/chan_tv`
## Tests
`docs/TEST_REPORT/ECR-003.md`
## Follow-ups
- CODE_REVIEW Approve
- 启发式参数(ATR 容差、lookback)后续可调
+24
View File
@@ -0,0 +1,24 @@
# PRODUCT_SPEC — ECR-003
**Status:** Approved
**Date:** 2026-08-06
## Goal
主站用户可在主周期图上开关查看威科夫:**交易区间、阶段、事件、Volume ProfilePOC/VAH/VAL)与事件量能确认**。
## User stories
1. 勾选「威科夫」后重新分析,图上出现交易区间框。
2. 可见阶段分段/标签(Accumulation/Distribution + AE)。
3. 可见 Spring / SOS / LPS / UTAD(及派发对称事件)标记。
4. 可选 VP 水平密度与 POC/VAH/VAL 线。
5. 取消勾选后不再请求威科夫计算(或仅隐藏叠层)。
## Non-goals
- chan_tv、策略下单、订单流 footprint。
## Success
人工可在合成/实盘图上辨认区间与事件;自动化单测覆盖核心检出。
+3 -2
View File
@@ -25,6 +25,7 @@ Trading System(缠论分析引擎 + 可视化 Web;Freqtrade 策略目录独
- 无 ECR 破坏 `/api/analyze` JSON 契约(可增不可删)
- 引入 Kafka / MongoDB / 微服务拆分(除非新 ADR)
- 本轮引入 Vite/React/TS 构建流水线
- 威科夫等**独立分析叠层**须走 ECR(可增 API 字段);不得借机改缠论算法
## Versioning
@@ -33,8 +34,8 @@ Trading System(缠论分析引擎 + 可视化 Web;Freqtrade 策略目录独
## Active anchors
- ECR: ECR-001 ReleasedECR-002 Draft
- EXP: N/A(当前无进行中的交易行为实验)
- ECR: ECR-002 / ECR-003 Reviewed(主站威科夫)
- EXP: N/A
- TRACEABILITY: `docs/TRACEABILITY.md`
- Memory: `docs/AGENT_MEMORY.md`
+8
View File
@@ -0,0 +1,8 @@
# RISK_REVIEW — ECR-003
**Status:** N/A
**Date:** 2026-08-06
展示用威科夫分析叠层,不改 Freqtrade 策略或 Live 下单。启发式误标风险由 UI 开关与文档说明缓解。
**Conclusion:** N/A(非交易执行变更)
+6 -6
View File
@@ -1,8 +1,8 @@
# STATE
**owner:** idle
**active_ecr:** noneECR-002 Reviewed;待合并提交)
**phase:** post-review
**active_ecr:** none
**phase:** idle
**system_version:** v1.0.0
**strategy_version:** unchanged
**updated:** 2026-08-06
@@ -13,10 +13,10 @@
|----|-------|--------|------|
| ECR-001 | L3 | Released `v1.0.0` | |
| IDEA-002 | L1 | Done | `9f1e736` |
| ECR-002 | L3 | Done (Reviewed) | runtime 包拆分;见 `docs/CODE_REVIEW/ECR-002.md` |
| ECR-002 | L3 | Done (Reviewed) | runtime 包拆分 |
| ECR-003 | L2 | Done (Reviewed) | 主站威科夫;待本提交合入 |
## Notes
- CODE_REVIEW**Approve**13 passed;非阻断项见 review Findings
- 工作区仍有未提交实现;合并后可清 active_ecr
- 未请求新 system tag
- ECR-003 CODE_REVIEW**Approve**Findings 另开 ECR-004
- 未请求新 system tag(仍 Unreleased 文档累计)
+7
View File
@@ -0,0 +1,7 @@
task_id: ECR-003
title: 主站威科夫分析与图表展示
status: done_reviewed
change_level: L2
ecr: docs/ECR/ECR-003-wyckoff-main.md
code_review: docs/CODE_REVIEW/ECR-003.md
notes: Main site only; independent of ChanZone. Approve 2026-08-06.
+29
View File
@@ -0,0 +1,29 @@
# TEST_REPORT — ECR-003
**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
**12 passed**
| Suite | Coverage |
|-------|----------|
| `test_wyckoff` | 合成箱体 TR + 事件;VP POC |
| golden / package / shim / contract keys file | 缠论基线 + 契约文档含 wyckoff optional |
| `test_analyze_contract` | 默认无 `wyckoff``include_wyckoff=1` 含约定键 |
## Notes
- 主站 UI 绘图无自动化;人工勾选「威科夫」验证叠层。
- 未改 golden JSON 内容。
+9
View File
@@ -27,3 +27,12 @@
| ECR-002 | 加深 analyze 契约 | ENG-002 | `web/tests/test_analyze_contract.py` | mock HTTP + 键快照 |
| ECR-002 | TF_DF 全量 init 冒烟 | ENG-002 | — | `tests/test_tf_df_init.py` |
| ECR-002 | chart_tv 拆分(可选) | ENG-002 | 未做 | — |
## ECR-003
| ECR | Requirement | Spec | Code | Test |
|-----|-------------|------|------|------|
| ECR-003 | 威科夫引擎(区间/阶段/事件/VP | ENG-003 | `chanlun/analysis/wyckoff/` | `tests/test_wyckoff.py` |
| ECR-003 | analyze 按需 `include_wyckoff` | ENG-003 | `web/api/analyze.py` | `test_analyze_http_wyckoff_opt_in` |
| ECR-003 | 主站 Lightweight 叠层 | PRODUCT-003 | `index.html` `chart_tv.js` `chart_view.js` | 人工 + 开关接线 |
| ECR-003 | 契约可选键文档 | ENG-003 | `analyze_contract_keys.json` | golden keys file 断言 |