Files
cryptoHermes/docs/dev.md
dela 05dc2ef0e7 refactor: 去掉 GetDerivatives 的假 error 返回 + 同步 API 文档
GetDerivatives 签名里的 error 返回永远是 nil,controller 那段 if err != nil
是死分支,会误导调用方以为存在"全失败"语义。当前产品策略是 best-effort
response:局部失败 → warnings,bundle 永远非 nil,HTTP 永远 200。
等 Hermes 上游真要求"全失败 → 5xx"时再重新引入 error 返回。

同时把 docs/dev.md §13.5 示例补上 warnings 字段(上次重构遗漏的文档同步)。
2026-05-24 17:57:08 +08:00

1332 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
下面这份可以直接保存为:
```text
docs/development.md
```
# Hermes Market Data Gateway 开发文档
## 1. 项目目标
本项目用于给 Hermes 提供统一的币圈行情与衍生品分析上下文。
核心原则:
```text
1. Hermes 只调用本服务,不直接访问 Binance / CoinGlass / ETF 数据源
2. 本服务只提供市场数据与分析上下文,不做交易、不下单、不托管资金
3. 第一版只保留 REST API不引入 gRPC / NATS / RabbitMQ
4. usecase 只依赖接口,不直接依赖 Binance client
5. Binance / CoinGlass / ETF / Macro / CME 都放在 repo/webapi
6. PostgreSQL / TimescaleDB 放在 repo/persistent
7. K线、Funding、OI、多空比长期数据必须落库
```
项目架构参考 `go-clean-template` 的 Clean Architecture 思路:业务逻辑放在 usecase外部系统通过 repo/webapi 或 repo/persistent 实现接口,避免服务变大后 controller、client、DB 逻辑混在一起。该模板本身定位就是 Go 服务的 Clean Architecture 模板,并支持 REST、gRPC、AMQP RPC、NATS RPC 等 transport本项目第一版只启用 REST。([GitHub][1])
---
## 2. 第一版范围
### 2.1 必须实现
第一版只做 Binance Futures 基础数据。
```text
数据源:
- Binance USDⓈ-M Futures Public API
币种:
- BTCUSDT
- ETHUSDT
周期:
- 15m
- 1h
- 4h
- 1d
- 1w
数据:
- K线 / OHLCV
- 24h ticker
- 当前 funding
- 历史 funding
- 当前 OI
- 历史 OI
- Global long/short ratio
- Top trader position ratio
- Taker buy/sell volume
```
Binance K线接口为 `GET /fapi/v1/klines`K线由 open time 唯一标识limit 默认 500、最大 150024h ticker 接口为 `GET /fapi/v1/ticker/24hr`,返回 lastPrice、highPrice、lowPrice、volume、quoteVolume、priceChangePercent 等字段。([Binance Developer Center][2])
Funding 历史接口为 `GET /fapi/v1/fundingRate`limit 最大 1000当前 OI 接口为 `GET /fapi/v1/openInterest`,历史 OI 接口为 `GET /futures/data/openInterestHist`,并且 Binance 官方说明历史 OI 只提供最近 1 个月数据,所以必须自己长期落库。([Binance Developer Center][3])
Long/Short Ratio 接口为 `GET /futures/data/globalLongShortAccountRatio`,官方说明只保留最近 30 天数据,也需要定时采集入库。([Binance Developer Center][4])
---
## 3. 非目标
第一版不做:
```text
1. 不做下单
2. 不做账户资产查询
3. 不接私有 API Key
4. 不做交易信号自动执行
5. 不做 NATS / RabbitMQ / gRPC
6. 不做复杂权限系统
7. 不做多租户
8. 不做清算热力图
9. 不做 CVD
10. 不做链上数据
```
后续版本再接:
```text
v2:
- CoinGlass
- ETF Flow
- 清算数据
- CME 缺口
v3:
- CVD
- 链上稳定币流动性
- 宏观日历
- 多交易所聚合
```
---
## 4. 技术栈
```text
Language:
- Go 1.22+
HTTP:
- Gin 或 Fiber
- 如果你想贴近 go-clean-template可以用 Fiber
Database:
- PostgreSQL
- TimescaleDB 可选,但推荐
Cache:
- Redis可选
Scheduler:
- robfig/cron
DB Driver:
- pgx
Config:
- cleanenv 或 viper
Decimal:
- 推荐 shopspring/decimal
- 不建议用 float64 直接处理价格和成交量
```
推荐依赖:
```bash
go get github.com/gofiber/fiber/v2
go get github.com/jackc/pgx/v5/pgxpool
go get github.com/robfig/cron/v3
go get github.com/shopspring/decimal
go get github.com/ilyakaznacheev/cleanenv
```
---
## 5. 项目目录结构
```text
crypto-hermes-gateway/
cmd/
app/
main.go
config/
config.go
config.yml
internal/
app/
app.go
scheduler.go
controller/
restapi/
router.go
middleware.go
v1/
market_routes.go
health_routes.go
entity/
kline.go
ticker.go
funding.go
open_interest.go
long_short_ratio.go
taker_volume.go
market_context.go
technical_level.go
usecase/
ports.go
market_context.go
market_collector.go
indicator.go
repo/
webapi/
binance/
client.go
dto.go
mapper.go
market.go
derivatives.go
persistent/
postgres/
kline_repo.go
funding_repo.go
open_interest_repo.go
long_short_ratio_repo.go
taker_volume_repo.go
worker/
collector.go
kline_collector.go
derivatives_collector.go
migrations/
000001_market_klines.up.sql
000001_market_klines.down.sql
000002_funding_rates.up.sql
000003_open_interest.up.sql
000004_long_short_ratio.up.sql
000005_taker_volume.up.sql
pkg/
httpclient/
client.go
logger/
logger.go
postgres/
postgres.go
docs/
development.md
api.md
database.md
docker-compose.yml
Dockerfile
Makefile
go.mod
```
---
## 6. 分层说明
### 6.1 Controller 层
目录:
```text
internal/controller/restapi/v1
```
职责:
```text
1. 接收 HTTP 请求
2. 校验 query/path/body
3. 调用 usecase
4. 返回 JSON
```
禁止:
```text
1. 不直接调用 Binance client
2. 不写复杂业务逻辑
3. 不直接拼数据库 SQL
4. 不计算技术指标
```
示例接口:
```http
GET /v1/market/context?symbol=BTCUSDT
GET /v1/market/klines?symbol=BTCUSDT&interval=1h&limit=300
GET /v1/market/snapshot?symbol=BTCUSDT
GET /v1/market/derivatives?symbol=BTCUSDT&period=1h
GET /v1/health
```
---
### 6.2 Entity 层
目录:
```text
internal/entity
```
职责:
```text
1. 定义核心业务模型
2. 不依赖 Gin / Fiber
3. 不依赖 Binance DTO
4. 不依赖 PostgreSQL row
```
示例:
```go
package entity
type Kline struct {
Source string `json:"source"`
Symbol string `json:"symbol"`
Interval string `json:"interval"`
OpenTime int64 `json:"openTime"`
CloseTime int64 `json:"closeTime"`
Open string `json:"open"`
High string `json:"high"`
Low string `json:"low"`
Close string `json:"close"`
Volume string `json:"volume"`
QuoteVolume string `json:"quoteVolume"`
TradeCount int64 `json:"tradeCount"`
TakerBuyBaseVolume string `json:"takerBuyBaseVolume"`
TakerBuyQuoteVolume string `json:"takerBuyQuoteVolume"`
}
```
---
### 6.3 Usecase 层
目录:
```text
internal/usecase
```
职责:
```text
1. 编排业务流程
2. 聚合不同数据源
3. 计算 Hermes 需要的市场上下文
4. 通过接口依赖 repo不依赖具体 Binance client
```
核心 usecase
```text
MarketContextUsecase:
- 构建 /v1/market/context 返回结果
MarketCollectorUsecase:
- 定时采集 K线、Funding、OI、多空比
IndicatorUsecase:
- 计算支撑压力、均线、布林、Vegas、箱体等
```
---
### 6.4 Repo WebAPI 层
目录:
```text
internal/repo/webapi
```
职责:
```text
1. 调外部 API
2. 处理 Binance / CoinGlass / ETF 的原始 response
3. 将外部 DTO 映射成 entity
```
第一版只实现:
```text
internal/repo/webapi/binance
```
后续扩展:
```text
internal/repo/webapi/coinglass
internal/repo/webapi/etf
internal/repo/webapi/macro
internal/repo/webapi/cme
```
---
### 6.5 Repo Persistent 层
目录:
```text
internal/repo/persistent/postgres
```
职责:
```text
1. 落库
2. 查询历史数据
3. Upsert 去重
4. 提供给 usecase 使用的仓储接口实现
```
---
## 7. Usecase 接口设计
`internal/usecase/ports.go`
```go
package usecase
import (
"context"
"crypto-hermes-gateway/internal/entity"
)
type MarketDataProvider interface {
GetKlines(ctx context.Context, symbol, interval string, limit int) ([]entity.Kline, error)
GetTicker24h(ctx context.Context, symbol string) (*entity.Ticker24h, error)
}
type DerivativesProvider interface {
GetCurrentFunding(ctx context.Context, symbol string) (*entity.FundingRate, error)
GetFundingHistory(ctx context.Context, symbol string, limit int) ([]entity.FundingRate, error)
GetCurrentOpenInterest(ctx context.Context, symbol string) (*entity.OpenInterest, error)
GetOpenInterestHistory(ctx context.Context, symbol, period string, limit int) ([]entity.OpenInterest, error)
GetGlobalLongShortRatio(ctx context.Context, symbol, period string, limit int) ([]entity.LongShortRatio, error)
GetTopTraderPositionRatio(ctx context.Context, symbol, period string, limit int) ([]entity.LongShortRatio, error)
GetTakerBuySellVolume(ctx context.Context, symbol, period string, limit int) ([]entity.TakerBuySellVolume, error)
}
type KlineRepository interface {
UpsertMany(ctx context.Context, items []entity.Kline) error
FindRecent(ctx context.Context, symbol, interval string, limit int) ([]entity.Kline, error)
}
type FundingRepository interface {
UpsertMany(ctx context.Context, items []entity.FundingRate) error
FindRecent(ctx context.Context, symbol string, limit int) ([]entity.FundingRate, error)
}
type OpenInterestRepository interface {
UpsertMany(ctx context.Context, items []entity.OpenInterest) error
FindRecent(ctx context.Context, symbol, period string, limit int) ([]entity.OpenInterest, error)
}
type LongShortRatioRepository interface {
UpsertMany(ctx context.Context, items []entity.LongShortRatio) error
FindRecent(ctx context.Context, symbol, period, ratioType string, limit int) ([]entity.LongShortRatio, error)
}
```
---
## 8. 核心聚合接口
### 8.1 Hermes 主接口
```http
GET /v1/market/context?symbol=BTCUSDT
```
用途:
```text
Hermes 分析 BTC / ETH 时,只调用这个接口。
```
返回结构:
```json
{
"symbol": "BTCUSDT",
"generatedAt": 1710000000000,
"snapshot": {
"lastPrice": "108000.12",
"priceChangePercent": "2.14",
"highPrice": "109200.00",
"lowPrice": "104800.00",
"volume": "123456.78",
"quoteVolume": "13200000000.00"
},
"klines": {
"15m": [],
"1h": [],
"4h": [],
"1d": [],
"1w": []
},
"derivatives": {
"funding": {
"current": {},
"history": []
},
"openInterest": {
"current": {},
"history": []
},
"longShortRatio": {
"global": [],
"topTraderPosition": []
},
"takerBuySellVolume": []
},
"technical": {
"support": [],
"resistance": [],
"rangeHigh": null,
"rangeLow": null,
"longShortLine": null
},
"dataQuality": {
"source": "binance",
"warnings": []
}
}
```
---
## 9. Binance WebAPI 实现规范
### 9.1 Base URL
```text
https://fapi.binance.com
```
### 9.2 必接接口
```text
K线:
GET /fapi/v1/klines
24h ticker:
GET /fapi/v1/ticker/24hr
当前 funding:
GET /fapi/v1/premiumIndex
历史 funding:
GET /fapi/v1/fundingRate
当前 OI:
GET /fapi/v1/openInterest
历史 OI:
GET /futures/data/openInterestHist
全局多空比:
GET /futures/data/globalLongShortAccountRatio
大户持仓多空比:
GET /futures/data/topLongShortPositionRatio
主动买卖量:
GET /futures/data/takerlongshortRatio
```
### 9.3 HTTP Client 要求
```text
1. timeout: 10s
2. retry: 最多 2 次
3. retry only:
- 429
- 500
- 502
- 503
- 504
4. 所有请求带 context
5. 所有外部 API error 必须包装 source、path、status code
```
错误格式:
```go
type ExternalAPIError struct {
Source string
Path string
StatusCode int
Message string
}
```
---
## 10. 数据库设计
### 10.1 market_klines
```sql
CREATE TABLE IF NOT EXISTS market_klines (
source TEXT NOT NULL,
symbol TEXT NOT NULL,
interval TEXT NOT NULL,
open_time BIGINT NOT NULL,
close_time BIGINT NOT NULL,
open NUMERIC(36, 18) NOT NULL,
high NUMERIC(36, 18) NOT NULL,
low NUMERIC(36, 18) NOT NULL,
close NUMERIC(36, 18) NOT NULL,
volume NUMERIC(36, 18) NOT NULL,
quote_volume NUMERIC(36, 18) NOT NULL,
trade_count BIGINT NOT NULL,
taker_buy_base_volume NUMERIC(36, 18) NOT NULL,
taker_buy_quote_volume NUMERIC(36, 18) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (source, symbol, interval, open_time)
);
CREATE INDEX IF NOT EXISTS idx_market_klines_symbol_interval_time
ON market_klines(symbol, interval, open_time DESC);
```
---
### 10.2 funding_rates
```sql
CREATE TABLE IF NOT EXISTS funding_rates (
source TEXT NOT NULL,
symbol TEXT NOT NULL,
funding_time BIGINT NOT NULL,
funding_rate NUMERIC(36, 18) NOT NULL,
mark_price NUMERIC(36, 18),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (source, symbol, funding_time)
);
CREATE INDEX IF NOT EXISTS idx_funding_rates_symbol_time
ON funding_rates(symbol, funding_time DESC);
```
---
### 10.3 open_interest
```sql
CREATE TABLE IF NOT EXISTS open_interest (
source TEXT NOT NULL,
symbol TEXT NOT NULL,
period TEXT NOT NULL,
timestamp BIGINT NOT NULL,
open_interest NUMERIC(36, 18) NOT NULL,
open_interest_value NUMERIC(36, 18),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (source, symbol, period, timestamp)
);
CREATE INDEX IF NOT EXISTS idx_open_interest_symbol_period_time
ON open_interest(symbol, period, timestamp DESC);
```
---
### 10.4 long_short_ratio
```sql
CREATE TABLE IF NOT EXISTS long_short_ratio (
source TEXT NOT NULL,
symbol TEXT NOT NULL,
period TEXT NOT NULL,
ratio_type TEXT NOT NULL,
timestamp BIGINT NOT NULL,
long_short_ratio NUMERIC(36, 18) NOT NULL,
long_value NUMERIC(36, 18),
short_value NUMERIC(36, 18),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (source, symbol, period, ratio_type, timestamp)
);
CREATE INDEX IF NOT EXISTS idx_long_short_ratio_symbol_period_time
ON long_short_ratio(symbol, period, ratio_type, timestamp DESC);
```
`ratio_type` 可选值:
```text
global_account
top_trader_position
top_trader_account
```
---
### 10.5 taker_buy_sell_volume
```sql
CREATE TABLE IF NOT EXISTS taker_buy_sell_volume (
source TEXT NOT NULL,
symbol TEXT NOT NULL,
period TEXT NOT NULL,
timestamp BIGINT NOT NULL,
buy_sell_ratio NUMERIC(36, 18),
buy_volume NUMERIC(36, 18),
sell_volume NUMERIC(36, 18),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (source, symbol, period, timestamp)
);
CREATE INDEX IF NOT EXISTS idx_taker_buy_sell_symbol_period_time
ON taker_buy_sell_volume(symbol, period, timestamp DESC);
```
---
## 11. 定时采集设计
### 11.1 支持币种
配置文件:
```yaml
symbols:
- BTCUSDT
- ETHUSDT
intervals:
- 15m
- 1h
- 4h
- 1d
- 1w
```
---
### 11.2 采集频率
```text
K线:
- 15m: 每 15 分钟采集一次
- 1h: 每小时采集一次
- 4h: 每 4 小时采集一次
- 1d: 每天采集一次
- 1w: 每周采集一次
Ticker:
- 30s 或 60s 刷新,可先不落库
Funding:
- 当前 funding: 每 15 分钟
- 历史 funding: 每 8 小时后补一次
OI:
- 当前 OI: 每 5 分钟或 15 分钟
- 历史 OI: 每 15 分钟
Long/Short Ratio:
- 每 15 分钟或 1 小时
Taker Buy/Sell:
- 每 15 分钟或 1 小时
```
---
### 11.3 Collector 设计
```go
type Collector struct {
marketData usecase.MarketDataProvider
derivatives usecase.DerivativesProvider
klineRepo usecase.KlineRepository
fundingRepo usecase.FundingRepository
oiRepo usecase.OpenInterestRepository
lsRepo usecase.LongShortRatioRepository
symbols []string
intervals []string
}
```
核心方法:
```go
func (c *Collector) CollectKlines(ctx context.Context) error
func (c *Collector) CollectFunding(ctx context.Context) error
func (c *Collector) CollectOpenInterest(ctx context.Context) error
func (c *Collector) CollectLongShortRatio(ctx context.Context) error
```
---
## 12. MarketContextUsecase 设计
### 12.1 构造方法
```go
type MarketContextUsecase struct {
marketData MarketDataProvider
derivatives DerivativesProvider
klineRepo KlineRepository
fundingRepo FundingRepository
oiRepo OpenInterestRepository
lsRepo LongShortRatioRepository
}
func NewMarketContextUsecase(
marketData MarketDataProvider,
derivatives DerivativesProvider,
klineRepo KlineRepository,
fundingRepo FundingRepository,
oiRepo OpenInterestRepository,
lsRepo LongShortRatioRepository,
) *MarketContextUsecase {
return &MarketContextUsecase{
marketData: marketData,
derivatives: derivatives,
klineRepo: klineRepo,
fundingRepo: fundingRepo,
oiRepo: oiRepo,
lsRepo: lsRepo,
}
}
```
---
### 12.2 Build 流程
```text
输入:
- symbol
流程:
1. 校验 symbol
2. 并发获取 snapshot / funding / current OI
3. 从 DB 获取 15m / 1h / 4h / 1d / 1w K线
4. 如果 DB 数据不足,则回源 Binance
5. 从 DB 获取 funding history
6. 从 DB 获取 OI history
7. 从 DB 获取 long/short ratio
8. 计算技术结构
9. 返回 Hermes MarketContext
```
---
## 13. API 设计
### 13.1 Health Check
```http
GET /v1/health
```
Response:
```json
{
"status": "ok",
"time": 1710000000000
}
```
---
### 13.2 Market Context
```http
GET /v1/market/context?symbol=BTCUSDT
```
Query:
```text
symbol: required, example BTCUSDT
```
Response:
```json
{
"symbol": "BTCUSDT",
"generatedAt": 1710000000000,
"snapshot": {},
"klines": {},
"derivatives": {},
"technical": {},
"dataQuality": {
"source": "binance",
"warnings": []
}
}
```
---
### 13.3 Klines
```http
GET /v1/market/klines?symbol=BTCUSDT&interval=1h&limit=300
```
Query:
```text
symbol: required
interval: required, enum 15m/1h/4h/1d/1w
limit: optional, default 300, max 1000
```
---
### 13.4 Snapshot
```http
GET /v1/market/snapshot?symbol=BTCUSDT
```
---
### 13.5 Derivatives
```http
GET /v1/market/derivatives?symbol=BTCUSDT&period=1h
```
Response:
```json
{
"symbol": "BTCUSDT",
"funding": {
"current": {},
"history": []
},
"openInterest": {
"current": {},
"history": []
},
"longShortRatio": {
"global": [],
"topTraderPosition": []
},
"takerBuySellVolume": [],
"warnings": []
}
```
---
## 14. 配置文件
`config/config.yml`
```yaml
app:
name: crypto-hermes-gateway
env: local
port: 8080
http:
read_timeout: 5s
write_timeout: 10s
idle_timeout: 60s
binance:
base_url: https://fapi.binance.com
timeout: 10s
retry_count: 2
postgres:
dsn: postgres://postgres:postgres@localhost:5432/hermes_market?sslmode=disable
max_conns: 10
min_conns: 2
collector:
enabled: true
symbols:
- BTCUSDT
- ETHUSDT
intervals:
- 15m
- 1h
- 4h
- 1d
- 1w
default_limit: 500
```
---
## 15. Docker Compose
```yaml
version: "3.9"
services:
postgres:
image: timescale/timescaledb:latest-pg16
container_name: hermes-postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: hermes_market
ports:
- "5432:5432"
volumes:
- hermes_pg_data:/var/lib/postgresql/data
app:
build: .
container_name: hermes-market-gateway
depends_on:
- postgres
ports:
- "8080:8080"
environment:
CONFIG_PATH: /app/config/config.yml
volumes:
- ./config:/app/config
volumes:
hermes_pg_data:
```
---
## 16. Makefile
```makefile
run:
go run ./cmd/app
test:
go test ./...
lint:
golangci-lint run
docker-up:
docker compose up -d
docker-down:
docker compose down
migrate-up:
migrate -path ./migrations -database "$(DATABASE_URL)" up
migrate-down:
migrate -path ./migrations -database "$(DATABASE_URL)" down
```
---
## 17. Hermes 调用方式
Hermes 只调用:
```http
GET /v1/market/context?symbol=BTCUSDT
```
然后 Hermes prompt 使用:
```text
你是币圈量化分析引擎。请基于以下 JSON 市场上下文分析 BTCUSDT。
分析框架:
1. 多周期结构: 15m / 1h / 4h / 1d / 1w
2. 支撑压力: 前高、前低、箱体、成交密集区
3. 反弹质量: 量价、taker buy volume、OI、funding
4. 情绪拥挤: global long/short、top trader long/short
5. 判断是否诱多 / 诱空
6. 输出:
- 当前主方向
- 上方压力
- 下方支撑
- 多空分水岭
- 高空条件
- 低多条件
- 风险提示
市场上下文 JSON:
{{market_context_json}}
```
---
## 18. 开发里程碑
### Milestone 1项目骨架
```text
目标:
- 基于 go-clean-template 思路搭建项目
- 删除 gRPC / NATS / RabbitMQ
- 保留 REST API
完成标准:
- GET /v1/health 返回 ok
- 项目可本地启动
```
---
### Milestone 2Binance WebAPI
```text
目标:
- 实现 Binance client
- 实现 K线、ticker、funding、OI、多空比接口
完成标准:
- 可以成功请求 BTCUSDT / ETHUSDT
- 外部 API 错误有统一封装
- 不在 usecase 里直接依赖 Binance client
```
---
### Milestone 3PostgreSQL 落库
```text
目标:
- 建表
- 实现 repository
- 支持 upsert
完成标准:
- K线可入库
- Funding 可入库
- OI 可入库
- Long/Short Ratio 可入库
```
---
### Milestone 4定时采集
```text
目标:
- 实现 collector
- 定时采集 BTCUSDT / ETHUSDT
完成标准:
- 每 15 分钟采集 15m K线
- 每 1 小时采集 1h 级别数据
- 采集重复数据不会插入重复记录
```
---
### Milestone 5Market Context API
```text
目标:
- 实现 Hermes 主接口
完成标准:
- GET /v1/market/context?symbol=BTCUSDT 返回完整 JSON
- 包含 snapshot、klines、funding、OI、多空比
- 数据不足时返回 dataQuality.warnings
```
---
### Milestone 6技术结构计算
```text
目标:
- 初步计算支撑压力和趋势结构
完成标准:
- 返回 support
- 返回 resistance
- 返回 rangeHigh / rangeLow
- 返回 longShortLine
```
---
## 19. 后续扩展
### v2CoinGlass
```text
新增:
- 清算统计
- 清算热力图
- 跨交易所 OI
- 跨交易所 funding
- ETF Flow
```
Binance WebSocket 强平流 `<symbol>@forceOrder` 只能推送每个 symbol 在 1000ms 内最大强平订单快照;如果要做清算密集区、热力图、清算地图,后续更适合接 CoinGlass / Hyblock 这类专业数据源。([Binance Developer Center][5])
---
### v3ETF Flow
```text
新增:
- BTC ETF daily net flow
- ETH ETF daily net flow
- IBIT / FBTC / ARKB / BITB / GBTC 分项
- 最近 7 天 / 30 天净流入
```
---
### v4宏观与 CME
```text
新增:
- CPI
- FOMC
- 非农
- 利率决议
- CME BTC Futures K线
- CME gap 自动计算
```
---
## 20. 验收标准
第一版验收标准:
```text
1. 服务可启动
2. /v1/health 正常
3. /v1/market/context?symbol=BTCUSDT 正常返回
4. /v1/market/context?symbol=ETHUSDT 正常返回
5. Binance client 不出现在 controller 中
6. usecase 只依赖接口
7. K线、Funding、OI、多空比已经落库
8. 采集任务可重复执行且不会产生重复数据
9. Hermes 只需要调用 /v1/market/context
10. 没有任何下单、账户、私钥、API Key 相关逻辑
```
---
## 21. 推荐开发顺序
```text
第 1 步:
搭项目骨架,跑通 /v1/health
第 2 步:
实现 Binance client + DTO mapper
第 3 步:
实现 usecase ports
第 4 步:
实现 /v1/market/klines 和 /v1/market/snapshot
第 5 步:
实现数据库 migration 和 repository
第 6 步:
实现 collector 定时落库
第 7 步:
实现 /v1/market/derivatives
第 8 步:
实现 /v1/market/context
第 9 步:
接 Hermes
第 10 步:
补技术指标和支撑压力计算
```
---
## 22. 最小可运行版本定义
MVP 只需要这一个接口稳定:
```http
GET /v1/market/context?symbol=BTCUSDT
```
只要它返回:
```text
1. 15m / 1h / 4h / 1d / 1w K线
2. 当前价格
3. 24h 涨跌幅
4. 24h 成交量
5. funding
6. OI
7. global long/short ratio
8. top trader position ratio
9. taker buy/sell volume
```
Hermes 就可以开始做“加密仲达系统”第一版分析。
[1]: https://github.com/evrone/go-clean-template?utm_source=chatgpt.com "GitHub - evrone/go-clean-template: Clean Architecture template for ..."
[2]: https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Kline-Candlestick-Data?utm_source=chatgpt.com "Kline Candlestick Data | Binance Open Platform"
[3]: https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Get-Funding-Rate-History "Get Funding Rate History | Binance Open Platform"
[4]: https://developers.binance.com/docs/derivatives/usds-margined-futures/market-data/rest-api/Long-Short-Ratio "Long Short Ratio | Binance Open Platform"
[5]: https://developers.binance.com/docs/derivatives/usds-margined-futures/websocket-market-streams/Liquidation-Order-Streams?utm_source=chatgpt.com "Liquidation Order Streams | Binance Open Platform"