feat(market): Phase 1 扩展 — 更多 symbol + Bollinger/Vegas + 衍生品信号

- collector.symbols 与 supportedSymbols 加 SOL/BNB/DOGE,env-default 与 README 同步
- entity 追加 TechnicalStructure.Intervals(每周期 Bollinger + Vegas,omitempty 不破坏既有字段)与 DerivativesBundle.Signal
- 新增纯解析 usecase derivatives_signal.go:fundingBias 绝对阈值、oiSignal 用 P20 baseline + 价格方向(OI up + 价格 up/down → long/short_building,funding 不参与方向)、lsrRegime 绝对阈值;signal 数据不足走 warnings 进 DataQuality
- indicator.go 加 sma/stddev/ema/bollinger/vegas + computeIntervalTechnicals;IndicatorComputer 签名收 klines map
- harness 同步:G12 扩入 derivatives_signal.go(含 Makefile G12.5/6 + ADR-0002 适用范围 + project-map / harness-health 更新)
This commit is contained in:
dela
2026-05-24 23:19:57 +08:00
parent 622ff1d317
commit fa769331c2
16 changed files with 912 additions and 66 deletions

View File

@@ -3,7 +3,7 @@
**状态**Accepted
**日期**2026-05-24
**决策者**:项目维护者
**适用范围**`internal/usecase/indicator.go` 及其后续衍生指标实现
**适用范围**`internal/usecase/indicator.go``internal/usecase/derivatives_signal.go` 及其后续同形态的纯解析 usecase 实现
---
@@ -33,10 +33,11 @@ Milestone 6 引入技术指标计算pivot S/R、percentile range、LSR 穿越
边界规则:
- `float64` **只**出现在 `internal/usecase/indicator.go` 内部
- 进入 `entity.TechnicalLevel` / `entity.TechnicalStructure` 前必须 `strconv.FormatFloat(f, 'f', -1, 64)` 转回 string
- `float64` **只**出现在 `internal/usecase/indicator.go``internal/usecase/derivatives_signal.go` 等"纯解析 usecase 文件"内部
- 进入任何 entity 字段(TechnicalLevel / TechnicalStructure / DerivativesSignal 等)前必须 `strconv.FormatFloat(f, 'f', -1, 64)` 转回 string;类别型字段(如 `crowded_long`)用 string 字面量
- entity / DTO / persistence / transport 全部保持 string不变
- 任何其它 usecase 文件出现 `float64` 视为违规
- 新增同形态文件时:必须同步扩 Makefile 的 G12.1 白名单与 G12.5/6 子规则
这是 `ai/risk-guardrails.md` **G2 例外条款**"纯统计/分析(如指标计算的中间过程)可以用 float64但结果落库或返回 API 时必须转回 string")的具体落地。守卫 G12 把这条例外细化成可机械验证的命令。

View File

@@ -60,6 +60,7 @@
**现状**MVP 阶段重点是端到端可用,未补单测覆盖率。
**影响**refactor 时风险偏高。
**升级时机**Milestone 6 引入指标计算(计算正确性 critical先补 mapper / repo 的 table-driven 测试。
**2026-05-24 更新**Phase 1 扩展symbols + Bollinger/Vegas/derivatives signal落地时`indicator_test.go` 和新建的 `derivatives_signal_test.go` 都铺了表驱动 + 边界用例(含 funding-positive + price-down 的回归用例。mapper / repo 的覆盖率仍是 partial留待下一次纯解析工作之外的 PR 再补。
### W5. 部分 docs/* 未提交到 git
**现状**`docs/dev.md` 是 untrackedgit status 显示 `?? docs/`)。
@@ -91,14 +92,15 @@
## Harness 文件清单(截至本次 commit
```
AGENTS.md ← AI agent 速查
README.md ← 用户向使用文档
docs/dev.md ← 完整设计文档(源头)
ai/project-map.md ← 仓库结构与扩展点
ai/risk-guardrails.md ← G1-G13 守卫规则
ai/adr/0001-architecture-foundations.md ← 9 条架构基础决策
ai/task-templates.md ← 6 种任务模板
ai/harness-health.md ← 本文件
AGENTS.md ← AI agent 速查
README.md ← 用户向使用文档
docs/dev.md ← 完整设计文档(源头)
ai/project-map.md ← 仓库结构与扩展点
ai/risk-guardrails.md ← G1-G13 守卫规则
ai/adr/0001-architecture-foundations.md ← 9 条架构基础决策
ai/adr/0002-indicator-numeric-boundary.md ← float64 transient 边界 + G12 落地
ai/task-templates.md ← 6 种任务模板
ai/harness-health.md ← 本文件
```
CLAUDE.md / GEMINI.md / .cursor/*.md 等其他 AI 工具的入口文件——**暂不需要**,因为这些工具都会读 AGENTS.md。如未来要差异化对待再分裂。

View File

@@ -72,6 +72,7 @@ Clean Architecture 四层。**依赖方向单向:`controller → usecase → e
- **价格/成交量字段全部 `string`**,避免 float64 精度问题。落库时 PG 转 `NUMERIC(36,18)`
- `Kline``IsClosed bool` 字段——未收线 K 线 (`close_time > now()`) 由 mapper 自动判定。
- `LongShortRatio` 有常量 `RatioTypeGlobalAccount` / `RatioTypeTopTraderPosition` / `RatioTypeTopTraderAccount`
- `market_context.go` 还承载技术结构与衍生品信号的输出类型:`TechnicalStructure`(含 `Intervals map[string]IntervalTechnicals`,新增字段对消费方完全可选)、`Bollinger``Vegas``DerivativesSignal``fundingBias` / `oiSignal` / `lsrRegime`)。所有数值仍是 string。
**不依赖**fiber、pgx、binance、任何外部库。可以从这里 import 到任何其他层。
@@ -81,8 +82,11 @@ Clean Architecture 四层。**依赖方向单向:`controller → usecase → e
- `MarketDataProvider`K线、ticker24h
- `DerivativesProvider`funding/OI/多空比/taker volume 共 7 个方法)
- `KlineRepository` / `FundingRepository` / `OpenInterestRepository` / `LongShortRatioRepository` / `TakerVolumeRepository`
- `market_context.go`:聚合 `/v1/market/context`。errgroup 并发拉 snapshot/funding/OIDB K 线不足 200 根回源 Binance 补,异步写回。
- `IndicatorComputer`pivot S/R + range + LSR 中位 + 每周期 Bollinger/Vegas
- `DerivativesSignalComputer`funding/OI/LSR → fundingBias/oiSignal/lsrRegime返回 warnings 由 caller 合并到 DataQuality
- `market_context.go`:聚合 `/v1/market/context`。errgroup 并发拉 snapshot/funding/OIDB K 线不足 200 根回源 Binance 补,异步写回。`supportedSymbols` 白名单当前为 BTC/ETH/SOL/BNB/DOGE USDT 五个。
- `market_query.go``/v1/market/derivatives` 后端。`GetDerivatives(symbol, period)` 并发拉 current funding/OI + 串行查 funding/OI/多空比历史,错误降级为 warnings 返回。
- `indicator.go``derivatives_signal.go`**纯解析 usecase**,零 repo 依赖。允许 transient `float64`G12 例外),输出转回 string 写入 entity。新增同形态文件时必须同步扩 Makefile G12.1 白名单与 G12.5/6 子规则,参考 `ai/adr/0002-indicator-numeric-boundary.md`
**约束**grep 可验证):
```bash

View File

@@ -195,25 +195,29 @@ grep -rn "FundingRepo\|OIRepo\|LSRepo\|TakerRepo" internal/controller
## G12. 指标计算的 float64 边界
**规则**`float64``internal/usecase/` 下**只允许出现在 `indicator.go` 内部**作为 transient 计算变量;进入 `entity` / 返回上层之前必须 `strconv.FormatFloat(_, 'f', -1, 64)` 转回 string。`internal/usecase/indicator.go` 同时**禁止** import `internal/repo/...` 的任何子包。
**规则**`float64``internal/usecase/` 下**只允许出现在纯解析 usecase 文件**(当前为 `indicator.go``derivatives_signal.go`)内部作为 transient 计算变量;进入 `entity` / 返回上层之前必须 `strconv.FormatFloat(_, 'f', -1, 64)` 转回 string。这些文件同时**禁止** import `internal/repo/...` 的任何子包。
**为什么**G2 已经预留"指标计算中间过程可用 float64"的例外但没有可机械验证的边界。Milestone 6 之后会有更多指标加入,必须把例外明文化、可 grep 化,避免某天 float64 悄悄出现在 entity 字段或被 repo 持久化。决策细节见 `ai/adr/0002-indicator-numeric-boundary.md`
**为什么**G2 已经预留"指标计算中间过程可用 float64"的例外但没有可机械验证的边界。Milestone 6 之后会有更多指标和衍生品信号加入,必须把例外明文化、可 grep 化,避免某天 float64 悄悄出现在 entity 字段或被 repo 持久化。决策细节见 `ai/adr/0002-indicator-numeric-boundary.md`
**怎么验证**
**新增同形态文件时**:必须同步扩 Makefile 的 G12.1 白名单与 G12.5/6 子规则(参考 `derivatives_signal.go` 接入的方式),并把文件名加入本规则的"当前为"括注。
**怎么验证**(由 `make guard` 自动跑):
```bash
# usecase 下除 indicator.go 之外不得出现 float64
grep -rn --include="*.go" "float64\|float32" internal/usecase | grep -v indicator
# G12.1usecase 下除白名单文件外不得出现 float64
grep -rn --include="*.go" "float64\|float32" internal/usecase | grep -vE "indicator|derivatives_signal"
# 期望:无输出
# indicator.go 不得 import 任何 repo 子包
# G12.2/G12.3indicator.go 不得 import repo 子包,也不得 import binance/postgres/pgx
grep -n "internal/repo" internal/usecase/indicator.go
# 期望:无输出
# indicator.go 不得 import binance / postgres / pgx
grep -nE "binance|postgres|pgx" internal/usecase/indicator.go
# 期望:无输出(注释中的 ADR 引用不算)
# entity 字段任何位置不得 float
# G12.5/G12.6derivatives_signal.go 同上
grep -n "internal/repo" internal/usecase/derivatives_signal.go
grep -nE "binance|postgres|pgx" internal/usecase/derivatives_signal.go
# 期望:无输出
# G12.4entity 字段任何位置不得 float
grep -rn --include="*.go" "float64\|float32" internal/entity
# 期望:无输出
```