dela c6c25d1a45 chore(harness): ADR-0002 + G12 立指标计算的 float64 边界
为什么:Milestone 6 引入 transient float64 用于 pivot/percentile/median
计算。G2 早已预留"统计中间过程可用 float64"的例外,但缺可机械验证
的边界。本提交把例外落地为:
- ADR-0002 记录"为什么不用 shopspring/decimal"
- G12 给出 4 条 grep 守卫(usecase float 仅限 indicator.go、
  indicator.go 不依赖 repo、不依赖 binance/postgres/pgx、entity
  仍禁 float)

代码无改动;下一 commit 开始铺 indicator.go 骨架。
2026-05-24 20:10:13 +08:00

cryptoHermes — Market Data Gateway

为上游 Hermes 量化分析引擎提供统一的币圈行情与衍生品上下文。Hermes 只需要调用本服务的 /v1/market/context 一个接口,就能拿到 BTC/ETH 多周期 K 线、当前价、funding、OI、多空比等用于策略分析的数据。

本服务只做行情采集与聚合,不下单、不接私钥、不查账户、不托管任何资金


特性

  • Binance USDⓈ-M Futures 公共接口,无需 API Key。
  • 多周期 K 线 / 24h ticker / funding / Open Interest / 全局多空比 / 大户持仓多空比 / Taker 主动买卖量。
  • 历史数据自动落库Binance 官方历史 OI / 多空比只保留 30 天,必须自己存)。
  • Clean Architecturecontroller / usecase / repo 分层usecase 只依赖接口。
  • Fiber v2 REST API + robfig/cron 定时采集 + TimescaleDB hypertable 存时序数据。
  • Rate Limit 节流(默认 20 req/s可重复运行的 upsertK 线只入库已收线。

技术栈

类型 选型
语言 Go 1.23
HTTP Fiber v2
DB TimescaleDB (PG 16)
DB Driver pgx v5 (pgxpool)
Scheduler robfig/cron v3
Config cleanenv (yaml + env)
限流 golang.org/x/time/rate
Migration golang-migrate CLI

快速开始

1. 依赖

# Go 1.23+
go version

# golang-migrate CLI用于跑 migration
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

2. 启动数据库

make docker-up

会用 timescale/timescaledb:latest-pg16 启一个 Postgres监听本地 5432。

3. 执行 migration

export DATABASE_URL="postgres://postgres:postgres@localhost:5432/hermes_market?sslmode=disable"
make migrate-up

会建 5 张 hypertablemarket_klines / funding_rates / open_interest / long_short_ratio / taker_buy_sell_volume

4. (可选)回填历史 K 线

第一次启动时 DB 是空的,直接调 /v1/market/context 会触发回源 Binance。建议先回填

make backfill ARGS="--symbol BTCUSDT --interval 15m --limit 500"
make backfill ARGS="--symbol BTCUSDT --interval 1h  --limit 500"
make backfill ARGS="--symbol BTCUSDT --interval 4h  --limit 500"
make backfill ARGS="--symbol BTCUSDT --interval 1d  --limit 500"
make backfill ARGS="--symbol BTCUSDT --interval 1w  --limit 500"
# ETHUSDT 同上

也可以指定起止时间做大段回填:

make backfill ARGS="--symbol BTCUSDT --interval 1h --from 1704067200000 --to 1735689600000"

5. 启动服务

make run

服务会:

  • 监听 :8080
  • 立刻启动 cron每 15 分钟拉一次 funding / OI / 多空比 / taker volume / 15m K 线,整点拉 1h每 4h 拉 4h每日 00:05 拉 1d每周一 00:10 拉 1w。

6. 验证

curl -s localhost:8080/v1/health | jq .
curl -s 'localhost:8080/v1/market/context?symbol=BTCUSDT' | jq 'keys'

国内网络

fapi.binance.com 国内直连不稳定通过环境变量挂代理即可Go 默认尊重 HTTPS_PROXY

HTTPS_PROXY=http://127.0.0.1:7890 make run

配置

config/config.yml(所有字段都可被环境变量覆盖,参见 config/config.goenv: tag

app:
  port: 8080
  env: local

binance:
  base_url: https://fapi.binance.com
  timeout: 10s
  retry_count: 2
  rps: 20            # IP 级限速,超过会自动 sleep
  burst: 40

postgres:
  dsn: postgres://postgres:postgres@localhost:5432/hermes_market?sslmode=disable
  max_conns: 10
  min_conns: 2

collector:
  enabled: true        # 设为 false 可只跑只读 API不开 cron
  symbols: [BTCUSDT, ETHUSDT]
  intervals: [15m, 1h, 4h, 1d, 1w]
  default_limit: 500

常用环境变量:

变量 说明
CONFIG_PATH 配置文件路径,默认 config/config.yml
POSTGRES_DSN 覆盖 yaml 中的 DSNDocker Compose 里就是这么干的)
APP_PORT HTTP 端口
HTTPS_PROXY 走代理访问 Binance

API

GET /v1/health

{ "status": "ok", "time": 1717000000000 }

GET /v1/market/context?symbol=BTCUSDT

Hermes 主接口。聚合返回 K 线 + 衍生品 + 数据质量信息:

{
  "symbol": "BTCUSDT",
  "generatedAt": 1717000000000,
  "snapshot": {
    "lastPrice": "108000.12",
    "priceChangePercent": "2.14",
    "highPrice": "109200.00",
    "lowPrice": "104800.00",
    "volume": "...",
    "quoteVolume": "..."
  },
  "klines": {
    "15m": [ /* 300  */ ],
    "1h":  [ /* 300  */ ],
    "4h":  [ /* 300  */ ],
    "1d":  [ /* 300  */ ],
    "1w":  [ /* 300  */ ]
  },
  "derivatives": {
    "funding":      { "current": { ... }, "history": [ ... ] },
    "openInterest": { "current": { ... }, "history": [ ... ] },
    "longShortRatio": {
      "global":            [ ... ],
      "topTraderPosition": [ ... ]
    },
    "takerBuySellVolume": []
  },
  "technical": {
    "support": [], "resistance": [],
    "rangeHigh": null, "rangeLow": null, "longShortLine": null
  },
  "dataQuality": {
    "source": "binance",
    "warnings": []
  }
}

technical.* 字段在 v1 留空。v2 会补支撑压力、箱体、多空线计算。

GET /v1/market/klines?symbol=BTCUSDT&interval=1h&limit=300

直接读 DB 返回 K 线数组。interval 取值 15m/1h/4h/1d/1w

GET /v1/market/snapshot?symbol=BTCUSDT

24h ticker 实时拉取(不走 DB

GET /v1/market/derivatives?symbol=BTCUSDT&period=1h

衍生品聚合funding / OI / 多空比。period 默认 1h


目录结构

cryptoHermes/
├── cmd/
│   ├── app/          # 主服务入口
│   └── backfill/     # 历史 K 线回填 CLI
├── config/           # cleanenv 配置
├── internal/
│   ├── app/          # 装配 DI、cron scheduler、graceful shutdown
│   ├── controller/   # Fiber 路由 + middleware
│   ├── entity/       # 业务实体(不依赖 Fiber/DB/Binance
│   ├── usecase/      # 业务接口与编排
│   ├── repo/
│   │   ├── webapi/binance/   # Binance HTTP client
│   │   └── persistent/postgres/  # 5 个 repository
│   └── worker/       # 实际跑采集逻辑的 collector
├── migrations/       # SQL migration含 hypertable 转换)
├── pkg/
│   ├── httpclient/   # 通用 HTTP client + retry + rate limit
│   ├── logger/       # slog 包装
│   └── postgres/     # pgxpool 初始化
├── docs/dev.md       # 完整设计文档
├── docker-compose.yml
├── Dockerfile
├── Makefile
└── go.mod

数据库

5 张 hypertable主键设计保证 upsert 幂等:

主键 时间列
market_klines (source, symbol, interval, open_time) open_time
funding_rates (source, symbol, funding_time) funding_time
open_interest (source, symbol, period, timestamp) timestamp
long_short_ratio (source, symbol, period, ratio_type, timestamp) timestamp
taker_buy_sell_volume (source, symbol, period, timestamp) timestamp

K 线时间列存毫秒 epochTimescale chunk 间隔默认 1 周(衍生品表)/ 30 天funding


常用命令

make run           # 跑服务
make build         # 编译两个二进制到 ./bin/
make test          # 跑测试
make tidy          # go mod tidy
make docker-up     # 起 Timescale
make docker-down   # 停 docker
make migrate-up    # apply migration
make migrate-down  # 回滚 1 步
make backfill ARGS="--symbol BTCUSDT --interval 1h --limit 500"

Clean Architecture 边界(验收用)

# controller 不应直接依赖 binance client
grep -r "repo/webapi/binance" internal/controller   # 期望: 无输出

# usecase 不应直接依赖具体 binance/postgres 实现
grep -r "repo/webapi/binance\|repo/persistent" internal/usecase   # 期望: 无输出

# 全项目不应出现私钥/账户/签名相关字段
grep -ri "apikey\|x-mbx-apikey\|hmac" .   # 期望: 无输出

路线图

  • v1当前Binance 行情 + 衍生品 + 落库 + /v1/market/context 聚合接口。
  • v2:技术结构计算(支撑压力 / 箱体 / 多空线 / 均线 / Vegas、CoinGlass 清算数据、ETF Flow。
  • v3CME gap、CVD、链上稳定币流动性、宏观日历、多交易所聚合。

完整设计参见 docs/dev.md


License

Internal project. Not for redistribution.

Description
No description provided
Readme 357 KiB
Languages
Go 97.9%
Makefile 1.6%
Dockerfile 0.5%