自建的实时加密货币数据采集与可视化平台,适用于 Binance USDS-M 永续合约。结合高性能 Rust 后端与专业图表前端,提供机构级市场数据工具。
这个项目主要是我自用的,实在没太多精力维护。我也不擅长前端,前端代码可能不太规范。欢迎大家发起 Pull Request 和 Issue!
如您所见,这并不是一个简单的一键启动的傻瓜工程,也不是面向小白的玩具项目。请原谅我没有时间也没有能力将其简单化。最简单的部署方式就是让 Claude Opus 4.6 研究完整个项目,然后让它来指导你启动。
如果后端部署实在太过困难,您可以暂时直接使用我的公开后端 API 端口:api-view.cathiefish.org,这样您只需将前端部署到 Cloudflare Pages 即可。注意该端口仅保证提供 BTCUSDT, ETHUSDT, SOLUSDT, BNBUSDT, XRPUSDT, SUIUSDT 的数据。请参阅下方部署章节了解如何配置。
- 实时 WebSocket 推流 — 从 Binance 合并流实时接收 1 分钟 K 线数据,支持自动重连和缺口回补
- 三级历史数据同步 — 月度 ZIP → 每日 ZIP → REST API,从 Binance 数据归档 尽可能快速回补
- TimescaleDB 时序存储 — Hypertable 优化,支持
time_bucket聚合,覆盖 8 个时间周期(1m, 5m, 15m, 1h, 4h, 1D, 1W, 1M) - 代理池支持 — 最多 100 个并发代理客户端,用于高吞吐量并行下载
- Binance 现货支持 — 现货市场数据采集,使用
.P后缀区分合约与现货 - MCP 支持 — Model Context Protocol 集成
- 专业图表引擎 — 完整的指标和画图工具支持
- 自定义指标 — 净成交量(NV-C)和累积成交量差(CVD-C)
- 多图表布局 — 单图、垂直分割、水平分割、1 左 + 2 右布局,分隔线可拖动
- 图表保存/加载 — 通过内置
save_load_adapter实现保存/加载(元数据存 localStorage,图表内容存后端 API),支持自动保存 - 深色/浅色主题 — 主题切换同步到图表组件和 UI
- 实时自选列表侧栏 — 实时价格、24 小时涨跌幅、拖拽排序
- 多自定义列表 — 创建和管理多个自选列表
- 前端品种管理 — 从前端 UI 添加/移除追踪品种(目前
TRACKED_SYMBOL仅通过后端.env文件控制)
- Google OAuth 保护 — 邮箱白名单访问控制,144 小时会话持久化
- Docker 就绪 — 多阶段构建,Docker Compose 共享网络
- Google Firebase 集成 — 通过 Firebase 连接后端 API,实现托管认证与托管部署
view/
├── backend/ # Rust 数据引擎 & API 服务
│ ├── src/
│ │ ├── main.rs # Axum HTTP 服务启动
│ │ ├── binance_collector.rs # WebSocket 实时采集 + REST 同步
│ │ ├── historical_downloader.rs # Binance 数据归档 (ZIP) 下载器
│ │ ├── database.rs # TimescaleDB 操作与聚合
│ │ ├── scheduler.rs # 任务调度与采集器生命周期
│ │ ├── klinechart.rs # KlineChart REST API 处理
│ │ ├── tradingview.rs # TradingView UDF API + WebSocket + Canvas
│ │ ├── structs.rs # 数据类型(CandleData, Interval, WsMessage…)
│ │ ├── error.rs # 自定义错误类型
│ │ └── lib.rs # 公开模块导出
│ ├── tests/
│ │ ├── connection_test.rs # 数据库连接测试
│ │ ├── database_test.rs # CRUD 与查询测试
│ │ ├── scheduler_test.rs # 调度器命令与生命周期测试
│ │ ├── sync_test.rs # 单品种同步测试
│ │ └── sync_full_history_test.rs
│ ├── examples/
│ │ ├── sync_all.rs # 同步所有品种(标准模式)
│ │ ├── sync_all_fast.rs # 同步所有品种(代理池并行)
│ │ └── sql.txt # TimescaleDB 建表 SQL
│ ├── Dockerfile
│ └── docker-compose.yml
│
├── frontend/ # 图表库前端
│ ├── index.html # 主应用(图表 + 自选列表 + 布局)
│ ├── login.html # Google OAuth 登录页
│ ├── auth.js # AuthGuard — 会话管理
│ ├── auth-config.js # OAuth 与 API 配置
│ ├── charting_library/ # 图表库资源
│ ├── datafeeds/ # UDF 数据源适配器
│ ├── Dockerfile
│ └── docker-compose.yml
│
└── references/ # Git 子模块
├── binance-rust/ # Binance 连接器 SDK
└── library/ # 图表库源码
| 层级 | 技术 |
|---|---|
| 后端 | Rust, Axum, sqlx, tokio, tokio-tungstenite |
| 数据库 | PostgreSQL + TimescaleDB |
| 前端 | Charting Library v29.4, Vanilla JS |
| 认证 | Google Identity Services (OAuth) |
| 部署 | Docker, Nginx, Docker Compose |
对于第一次接触 Nginx Proxy Manager、TimescaleDB、PgAdmin、Docker 或 Cloudflare 的用户,最简单的部署方式就是让 Claude Opus 4.6 研究这个项目,然后让它一步步指导你部署。如果持续失败,请在本仓库提交 Issue。
在自己的服务器上部署全套服务,使用 Docker 和 Nginx Proxy Manager 作为反向代理。
Note
如果不清楚以下任何步骤,请咨询 Claude Opus 4.6,它可以详细指导你完成每一步。
┌─────────────────── Docker 网络: cycle ──────────────────────┐
│ │
│ ┌──────────────────┐ ┌──────────────┐ │
│ │ Nginx Proxy Mgr │ │ TimescaleDB │ │
│ │ :80 / :443 │ │ :5432 │ │
│ └────────┬─────────┘ └──────┬───────┘ │
│ │ │ │
│ │ │ │
│ ┌────────▼──┐ ┌───────────┐ │ │
│ │ Frontend │ │ Backend │───┘ │
│ │ :80 │ │ :3000 │ │
│ │ (nginx) │ │ (axum) │ │
│ └───────────┘ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
▲
公网域名
view.yourdomain.com
所有容器必须在同一个 Docker 网络 cycle 中运行,这样才能通过容器名互相通信。只有前端需要通过 Nginx Proxy Manager 暴露到公网 —— 后端(端口 3000)由前端容器通过 Docker 内部 DNS 访问。
docker network create cycle为 TimescaleDB 创建 docker-compose.yml,加入 cycle 网络:
# database/docker-compose.yml
services:
timescaledb:
image: timescale/timescaledb:latest-pg16
container_name: timescaledb
networks:
- cycle
environment:
- POSTGRES_USER=quant
- POSTGRES_PASSWORD=your_secure_password
- POSTGRES_DB=crypto_database
volumes:
- timescaledb_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
timescaledb_data:
networks:
cycle:
external: truedocker compose up -d然后使用 backend/examples/sql.txt 中的 SQL 初始化数据库:
docker exec -i timescaledb psql -U quant -d crypto_database < backend/examples/sql.txtTip
建议同时部署 PgAdmin 用于数据库管理。详见这篇教程。新手建议直接让 Claude Opus 4.6 来指导。
1. 配置 .env
cd backend
cp .env.example .env编辑 backend/.env:
RUST_LOG="INFO,binance_sdk::common::utils=off,binance_sdk::common::websocket=off"
DATABASE_URL="postgres://quant:your_secure_password@timescaledb:5432/crypto_database"
TRACKED_SYMBOL=[BTCUSDT,ETHUSDT,BNBUSDT,SOLUSDT,XRPUSDT]
# 代理设置(可选 — 留空则直连)
PROXY_HOST=dc.your-proxy-provider.com
PROXY_USERNAME=your_username
PROXY_PASSWORD=your_password
PROXY_PROTOCOL=https
PROXY_PORT_START=10000
PROXY_PORT_END=10099Note
DATABASE_URL 使用容器名 timescaledb 作为主机名 —— 因为两个容器都在 cycle 网络中。也可以使用数据库容器的绝对 IP(通过 docker inspect timescaledb --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 查询)。确保数据库容器也在 cycle 网络中。TRACKED_SYMBOL 目前仅支持 USDS-M 永续合约(Swap),不支持现货。
Warning
强烈建议配置代理。 后端需要从 Binance 数据归档 下载所有追踪品种的历史数据。使用多端口代理池(如 100 个并发连接)。不使用代理的话,同步可能需要几天时间。 如果 PROXY_HOST 留空,后端将使用单一直连。
2. 构建并运行
docker build -t backend .
docker compose up -d构建前端容器之前,需要先配置认证和 API 连接。
1. 配置 auth-config.js
前端在 Docker 网络内部运行,通过容器名访问后端:
window.API_CONFIG = { baseUrl: 'http://backend:3000' };
const AUTH_CONFIG = {
clientId: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
onSuccess: (user) => { console.log('Auth successful:', user.email); },
onError: (error) => { console.error('Auth error:', error); }
};
window.AUTH_CONFIG = AUTH_CONFIG;
window.ALLOWED_EMAILS = ['your-email@gmail.com'];将 clientId 替换为你从 GCP Console 获取的 Google OAuth Client ID,将 ALLOWED_EMAILS 替换为你的邮箱白名单。
查询后端容器 IP(调试用):
$ docker inspect backend --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
172.18.0.3Important
Google OAuth 需要从 GCP Console 获取 Client ID。教程待补充。
3. 构建并运行
cd frontend
docker build -t frontend .
docker compose up -dWarning
前端和后端容器必须在同一个 Docker 网络(cycle)中。两个 docker-compose.yml 文件已通过 networks: cycle: external: true 配置好。
Nginx Proxy Manager 也必须在 cycle 网络中运行。创建 docker-compose.yml:
# npm/docker-compose.yml
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
networks:
- cycle
ports:
- "80:80"
- "443:443"
- "81:81"
volumes:
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
restart: unless-stopped
volumes:
npm_data:
npm_letsencrypt:
networks:
cycle:
external: truedocker compose up -dTip
Nginx Proxy Manager 的详细部署和 Docker 最佳实践,请参阅这篇教程。新手建议直接让 Claude Opus 4.6 来指导。
访问管理面板 http://你的服务器IP:81(默认账号:admin@example.com / changeme)。
为前端创建 Proxy Host:
| 域名 | 转发主机名 | 转发端口 | SSL |
|---|---|---|---|
view.yourdomain.com |
frontend_tv |
80 |
✅ Let's Encrypt |
Tip
"转发主机名"使用的是容器名(不是 IP),因为所有容器共享 cycle 网络。后端不需要公网代理 —— 前端通过 Docker 内部 DNS(http://backend:3000)访问。
部署完成后,即可通过 https://view.yourdomain.com 访问。
在方案一的基础上,额外将后端 API 暴露到公网,并将前端部署到 Cloudflare Pages,而不是自建托管。
Note
如果不清楚以下步骤,请咨询 Claude Opus 4.6 —— 这是很简单的操作。
Caution
Cloudflare Pages 项目名和自定义域名中不要包含 "tradingview"。TradingView 会主动维权,你的部署会被下架。使用中性名称如 view、chart、crypto-dash。
完成方案一的第一至三步(创建 cycle 网络、部署 TimescaleDB、部署后端)。
由于前端将从 Cloudflare 提供服务(在 Docker 网络外部),后端 API 必须可以从公网访问。在 Nginx Proxy Manager 中添加一个 Proxy Host:
| 域名 | 转发主机名 | 转发端口 | SSL |
|---|---|---|---|
api.yourdomain.com |
backend |
3000 |
✅ Let's Encrypt |
Important
为此 Proxy Host 启用 Websockets Support —— 实时 K 线推送需要 WebSocket。
- Fork 或 Clone 本仓库到你自己的 GitHub 账号
- 进入 Cloudflare 控制台 → Workers & Pages → 创建
- 选择 Pages → 连接到 Git
- 授权 Cloudflare 访问你的 GitHub 账号,选择仓库
- 配置构建设置:
| 设置 | 值 |
|---|---|
| 生产分支 | main |
| 构建命令 | sh build.sh |
| 构建输出目录 | frontend |
- 添加环境变量(设置 → 环境变量):
| 变量 | 值 | 说明 |
|---|---|---|
API_BASE_URL |
https://api.yourdomain.com |
第二步的公网后端 API 地址 |
GOOGLE_CLIENT_ID |
YOUR_CLIENT_ID.apps.googleusercontent.com |
从 GCP Console 获取的 Google OAuth Client ID |
ALLOWED_EMAILS |
alice@gmail.com,bob@gmail.com |
逗号分隔的邮箱白名单 |
- 点击 保存并部署
Note
build.sh 脚本会在构建时从环境变量生成 auth-config.js。仓库中不存储任何敏感信息 —— 所有凭据通过 Cloudflare 环境变量面板配置。
Cloudflare 会分配一个 *.pages.dev 域名。你可以在 Pages → 自定义域 中添加自定义域名。
MIT
Generated By Claude Opus 4.6



