feat: 初始化 cryptoHermes 行情网关 v1 MVP + harness 工程文档
Binance USDⓈ-M Futures 行情网关,给上游 Hermes 量化分析引擎提供单一聚合 接口 /v1/market/context(K 线 + funding + OI + 多空比 + taker volume)。 只读公共行情,不下单、不接私钥、不查账户。 ## v1 实现范围(Milestone 1-5) - Clean Architecture 4 层(controller/usecase/repo/entity),接口边界在 internal/usecase/ports.go - Binance Futures REST client(K 线 / ticker24h / funding / OI / 多空比 / taker volume 共 9 个接口),全链路 string 价格避免 float64 精度问题 - TimescaleDB 5 张 hypertable(market_klines / funding_rates / open_interest / long_short_ratio / taker_buy_sell_volume),主键含 时间维度,UpsertMany 幂等 - robfig/cron 定时采集(15m/1h/4h/1d/1w 多周期 K 线 + 衍生品 15 分钟 落库),未收线 K 线 (close_time > now) 由 mapper/repo 双重过滤 - pkg/httpclient 统一限流(默认 20 req/s, burst 40)+ 重试,避免触发 Binance 2400 weight/min IP 上限 - /v1/market/context 聚合接口:errgroup 并发拉 snapshot/funding/OI,DB K 线不足 200 根回源 Binance 异步补 - cmd/backfill CLI 支持指定 from/to 大段回填(Binance 历史 OI / 多空比 官方只保留 30 天,必须自己存) - Docker Compose + Makefile + golang-migrate,本地一键启 技术指标(support/resistance/Vegas/箱体)留待 v2,技术段返回空对象 + warning 占位。 ## Harness 工程文档 - AGENTS.md — AI agent 工作速查(10 个章节) - ai/project-map.md — 仓库结构、扩展点、控制流 - ai/risk-guardrails.md — G1-G10 守卫规则(每条带可机械验证命令) - ai/adr/0001-architecture-foundations.md — 9 条架构基础决策 - ai/task-templates.md — 6 种任务契约模板 - ai/harness-health.md — 当前 harness 健康度评估 3 个 grep 守卫已验证通过:controller / usecase 无具体实现依赖,全项目 无私钥/签名字段。
This commit is contained in:
309
README.md
Normal file
309
README.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# 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 Architecture:controller / usecase / repo 分层,usecase 只依赖接口。
|
||||
- Fiber v2 REST API + robfig/cron 定时采集 + TimescaleDB hypertable 存时序数据。
|
||||
- Rate Limit 节流(默认 20 req/s),可重复运行的 upsert,K 线只入库已收线。
|
||||
|
||||
---
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 类型 | 选型 |
|
||||
|---|---|
|
||||
| 语言 | 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. 依赖
|
||||
|
||||
```bash
|
||||
# Go 1.23+
|
||||
go version
|
||||
|
||||
# golang-migrate CLI(用于跑 migration)
|
||||
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
|
||||
```
|
||||
|
||||
### 2. 启动数据库
|
||||
|
||||
```bash
|
||||
make docker-up
|
||||
```
|
||||
|
||||
会用 `timescale/timescaledb:latest-pg16` 启一个 Postgres,监听本地 5432。
|
||||
|
||||
### 3. 执行 migration
|
||||
|
||||
```bash
|
||||
export DATABASE_URL="postgres://postgres:postgres@localhost:5432/hermes_market?sslmode=disable"
|
||||
make migrate-up
|
||||
```
|
||||
|
||||
会建 5 张 hypertable:`market_klines` / `funding_rates` / `open_interest` / `long_short_ratio` / `taker_buy_sell_volume`。
|
||||
|
||||
### 4. (可选)回填历史 K 线
|
||||
|
||||
第一次启动时 DB 是空的,直接调 `/v1/market/context` 会触发回源 Binance。建议先回填:
|
||||
|
||||
```bash
|
||||
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 同上
|
||||
```
|
||||
|
||||
也可以指定起止时间做大段回填:
|
||||
|
||||
```bash
|
||||
make backfill ARGS="--symbol BTCUSDT --interval 1h --from 1704067200000 --to 1735689600000"
|
||||
```
|
||||
|
||||
### 5. 启动服务
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
服务会:
|
||||
|
||||
- 监听 `:8080`
|
||||
- 立刻启动 cron,每 15 分钟拉一次 funding / OI / 多空比 / taker volume / 15m K 线,整点拉 1h,每 4h 拉 4h,每日 00:05 拉 1d,每周一 00:10 拉 1w。
|
||||
|
||||
### 6. 验证
|
||||
|
||||
```bash
|
||||
curl -s localhost:8080/v1/health | jq .
|
||||
curl -s 'localhost:8080/v1/market/context?symbol=BTCUSDT' | jq 'keys'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 国内网络
|
||||
|
||||
`fapi.binance.com` 国内直连不稳定,通过环境变量挂代理即可(Go 默认尊重 `HTTPS_PROXY`):
|
||||
|
||||
```bash
|
||||
HTTPS_PROXY=http://127.0.0.1:7890 make run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置
|
||||
|
||||
`config/config.yml`(所有字段都可被环境变量覆盖,参见 `config/config.go` 的 `env:` tag):
|
||||
|
||||
```yaml
|
||||
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 中的 DSN(Docker Compose 里就是这么干的) |
|
||||
| `APP_PORT` | HTTP 端口 |
|
||||
| `HTTPS_PROXY` | 走代理访问 Binance |
|
||||
|
||||
---
|
||||
|
||||
## API
|
||||
|
||||
### `GET /v1/health`
|
||||
|
||||
```json
|
||||
{ "status": "ok", "time": 1717000000000 }
|
||||
```
|
||||
|
||||
### `GET /v1/market/context?symbol=BTCUSDT`
|
||||
|
||||
**Hermes 主接口**。聚合返回 K 线 + 衍生品 + 数据质量信息:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"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 线时间列存毫秒 epoch,Timescale chunk 间隔默认 1 周(衍生品表)/ 30 天(funding)。
|
||||
|
||||
---
|
||||
|
||||
## 常用命令
|
||||
|
||||
```bash
|
||||
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 边界(验收用)
|
||||
|
||||
```bash
|
||||
# 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。
|
||||
- **v3**:CME gap、CVD、链上稳定币流动性、宏观日历、多交易所聚合。
|
||||
|
||||
完整设计参见 [`docs/dev.md`](docs/dev.md)。
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
Internal project. Not for redistribution.
|
||||
Reference in New Issue
Block a user