mirror of
https://github.com/exchanges-lab/tradesync.git
synced 2026-08-05 05:06:07 +08:00
docs: restructure README, add Chinese translation, Notion template and Docker Compose deployment
- Add README_CN.md as a full Chinese translation of README.md - Add a Notion Template & Preview section with the database template link, collapsible preview screenshots, and a note on the companion TradeSnap service that provides the TradingView screenshots - Add a Deployment section documenting Docker Compose (recommended) and local build - Use relative links so they resolve on GitHub - Drop the Code Example and Requirements sections and renumber Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
An efficient, decoupled Hyperliquid wallet position monitor and Notion database logger.
|
An efficient, decoupled Hyperliquid wallet position monitor and Notion database logger.
|
||||||
|
|
||||||
|
> 中文版:[README_CN.md](./README_CN.md)
|
||||||
|
|
||||||
## 1. Introduction
|
## 1. Introduction
|
||||||
`tradesync` is a real-time wallet position monitoring and analysis tool built with Rust. It subscribes to a specified Hyperliquid wallet address via WebSockets, captures position-opening trades in real-time, aggregates multi-tick partial fills of a single order (using a 500ms debounce aggregation mechanism), and automatically synchronizes the formatted trade data to a Notion database.
|
`tradesync` is a real-time wallet position monitoring and analysis tool built with Rust. It subscribes to a specified Hyperliquid wallet address via WebSockets, captures position-opening trades in real-time, aggregates multi-tick partial fills of a single order (using a 500ms debounce aggregation mechanism), and automatically synchronizes the formatted trade data to a Notion database.
|
||||||
|
|
||||||
@@ -13,7 +15,33 @@ An efficient, decoupled Hyperliquid wallet position monitor and Notion database
|
|||||||
* **Robust Reconnection**: Implements a robust connection loop that automatically reconnects after network glitches or WebSocket drops.
|
* **Robust Reconnection**: Implements a robust connection loop that automatically reconnects after network glitches or WebSocket drops.
|
||||||
* **Notion Integration**: Integrates `notion-client` API to write structured rows (`Symbol`, `Quantity`, `Filled Price`, `Direction`, `Exchange`, `DataTime`, `Order ID`, `Order Type`, `Check`) directly to a target Notion database.
|
* **Notion Integration**: Integrates `notion-client` API to write structured rows (`Symbol`, `Quantity`, `Filled Price`, `Direction`, `Exchange`, `DataTime`, `Order ID`, `Order Type`, `Check`) directly to a target Notion database.
|
||||||
|
|
||||||
## 3. Architecture & Modules
|
## 3. Notion Template & Preview
|
||||||
|
This project writes data into a Notion database, so you first need a database whose schema matches the expected fields. You can duplicate the official template directly (click **Duplicate** in the top-right corner to copy it into your own workspace):
|
||||||
|
|
||||||
|
> 📋 **Notion database template**: <https://annafish.notion.site/2026-2e08f81ac37080c6a474f00373d13287>
|
||||||
|
|
||||||
|
After duplicating, put the database ID into `NOTION_DATABASE_ID` in your `.env`, and connect your Notion integration to that page.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>🗂️ Notion database example (click to expand)</summary>
|
||||||
|
|
||||||
|
<img src="https://img.cathiefish.art/github/tradesync/tradesync1.png" width="720" alt="tradesync database example" />
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>📜 Full long screenshot of a single record page (click to expand)</summary>
|
||||||
|
|
||||||
|
<img src="https://img.cathiefish.art/github/tradesync/tradesync2.png" width="420" alt="tradesync record page example" />
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
> 🖼️ **About the real-time TradingView screenshots on the record page**
|
||||||
|
> The multi-timeframe (15m / 1h / 4h / 1D) real-time TradingView screenshots on each record page are **not** generated by `tradesync` itself, but by a companion service called **TradeSnap** (separate repo: <https://github.com/exchanges-lab/tradesnap>). After writing to Notion, `tradesync` calls TradeSnap via `TRADESNAP_URL` to fetch the screenshots and appends them to the corresponding page.
|
||||||
|
> This is optional and controlled by `ENABLE_SCREENSHOT`; when disabled, `tradesync` only writes trade data rows and does not depend on TradeSnap.
|
||||||
|
|
||||||
|
## 4. Architecture & Modules
|
||||||
The directory structure and modules are as follows:
|
The directory structure and modules are as follows:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -29,6 +57,8 @@ tradesync/
|
|||||||
├── tests/ # Integration and unit tests
|
├── tests/ # Integration and unit tests
|
||||||
│ └── monitor_test.rs # Monitor connectivity and reconnection loop tests
|
│ └── monitor_test.rs # Monitor connectivity and reconnection loop tests
|
||||||
├── references/ # Local reference submodules
|
├── references/ # Local reference submodules
|
||||||
|
├── docker-compose.yml # Docker Compose deployment orchestration
|
||||||
|
├── Dockerfile # Container image build file
|
||||||
├── .env # Local environment variables configuration (ignored by git)
|
├── .env # Local environment variables configuration (ignored by git)
|
||||||
├── .env.example # Environment configuration template
|
├── .env.example # Environment configuration template
|
||||||
├── Cargo.toml # Cargo package file with remote Git dependencies
|
├── Cargo.toml # Cargo package file with remote Git dependencies
|
||||||
@@ -39,11 +69,41 @@ tradesync/
|
|||||||
* **NotionWriter** (`src/notion.rs`): Formats and writes the captured row data to the Notion database.
|
* **NotionWriter** (`src/notion.rs`): Formats and writes the captured row data to the Notion database.
|
||||||
* **structs** (`src/structs.rs`): Defines data models like `PositionTradeEvent` and `NotionRowData`.
|
* **structs** (`src/structs.rs`): Defines data models like `PositionTradeEvent` and `NotionRowData`.
|
||||||
|
|
||||||
## 4. Requirements
|
## 5. Deployment
|
||||||
* **Rust**: `1.85.0` or higher (supports the 2024 edition)
|
|
||||||
* **OS**: Linux, macOS, Windows
|
### Option 1: Docker Compose (Recommended)
|
||||||
|
The project ships a `docker-compose.yml` that pulls the prebuilt image `ghcr.io/exchanges-lab/tradesync:latest` and runs it directly — no local Rust toolchain required.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone https://github.com/cathiefish/tradesync.git
|
||||||
|
cd tradesync
|
||||||
|
|
||||||
|
# Copy and configure environment variables
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your WALLET_ADDRESS, NOTION_API_KEY, NOTION_DATABASE_ID, etc.
|
||||||
|
|
||||||
|
# The compose file uses an external network named "cycle"; create it on first deploy
|
||||||
|
docker network create cycle
|
||||||
|
|
||||||
|
# Pull the latest image and start in the background
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Follow live logs
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
# Stop and remove the container
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Notes**
|
||||||
|
> - The service in `docker-compose.yml` joins the external network `cycle` so it can communicate with other services on the same network (e.g., the screenshot service `tradesnap`). If you enable screenshots, set `TRADESNAP_URL` to an address reachable within that network (default `http://tradesnap:8003`).
|
||||||
|
> - The container is configured with `restart: unless-stopped`, so it comes back up automatically after a host reboot.
|
||||||
|
|
||||||
|
### Option 2: Local Build & Run
|
||||||
|
Suitable for development, debugging, or building your own binary:
|
||||||
|
|
||||||
## 5. Getting Started
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
git clone https://github.com/cathiefish/tradesync.git
|
git clone https://github.com/cathiefish/tradesync.git
|
||||||
@@ -63,31 +123,7 @@ cargo run
|
|||||||
cargo run --example demo
|
cargo run --example demo
|
||||||
```
|
```
|
||||||
|
|
||||||
## 6. Code Example
|
## 6. Environment Variables
|
||||||
A minimal running example for the monitor is located at [examples/demo.rs](file:///home/cathiefish/App/tradesync/examples/demo.rs):
|
|
||||||
```rust
|
|
||||||
use alloy::primitives::address;
|
|
||||||
use tradesync::HyperliquidMonitor;
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let wallet = address!("0xc64cc00b46101bd40aa1c3121195e85c0b0918d8");
|
|
||||||
let monitor = HyperliquidMonitor::new(wallet, true); // true for Testnet
|
|
||||||
|
|
||||||
let (tx, mut rx) = mpsc::unbounded_channel();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let _ = monitor.run(tx).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
while let Some(event) = rx.recv().await {
|
|
||||||
println!("Captured Position Opening Event: {:?}", event);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 7. Environment Variables
|
|
||||||
| Variable | Description | Required | Default / Example Value |
|
| Variable | Description | Required | Default / Example Value |
|
||||||
| :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- |
|
||||||
| `WALLET_ADDRESS` | The Ethereum/Hyperliquid wallet address to monitor | **Yes** | `0xc64cc00b46101bd40aa1c3121195e85c0b0918d8` |
|
| `WALLET_ADDRESS` | The Ethereum/Hyperliquid wallet address to monitor | **Yes** | `0xc64cc00b46101bd40aa1c3121195e85c0b0918d8` |
|
||||||
@@ -104,7 +140,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
| `SYMBOL_1D_SNAPSHOT` | Capture and insert 1D interval screenshot (`true`/`false`) | No | `false` |
|
| `SYMBOL_1D_SNAPSHOT` | Capture and insert 1D interval screenshot (`true`/`false`) | No | `false` |
|
||||||
|
|
||||||
|
|
||||||
## 8. Development & Testing
|
## 7. Development & Testing
|
||||||
### Git Branching Strategy
|
### Git Branching Strategy
|
||||||
* `dev`: Active development branch. New features and fixes are merged here first.
|
* `dev`: Active development branch. New features and fixes are merged here first.
|
||||||
* `main`: Stable production-ready branch.
|
* `main`: Stable production-ready branch.
|
||||||
@@ -122,5 +158,5 @@ cargo clippy --all-targets --all-features -- -D warnings
|
|||||||
cargo test
|
cargo test
|
||||||
```
|
```
|
||||||
|
|
||||||
## 9. Changelog
|
## 8. Changelog
|
||||||
For a detailed log of project updates, please refer to [CHANGELOG.md](file:///home/cathiefish/App/tradesync/CHANGELOG.md).
|
For a detailed log of project updates, please refer to [CHANGELOG.md](./CHANGELOG.md).
|
||||||
|
|||||||
+162
@@ -0,0 +1,162 @@
|
|||||||
|
# tradesync
|
||||||
|
|
||||||
|
一个高效、解耦的 Hyperliquid 钱包持仓监控与 Notion 数据库记录工具。
|
||||||
|
|
||||||
|
> English version: [README.md](./README.md)
|
||||||
|
|
||||||
|
## 1. 简介
|
||||||
|
`tradesync` 是一个基于 Rust 构建的实时钱包持仓监控与分析工具。它通过 WebSocket 订阅指定的 Hyperliquid 钱包地址,实时捕获开仓交易,将单个订单的多笔分批成交(基于 500ms 防抖聚合机制)合并聚合,并自动将格式化后的交易数据同步到 Notion 数据库。
|
||||||
|
|
||||||
|
## 2. 核心特性
|
||||||
|
* **实时钱包订阅**:使用 `hyperliquid-rust-sdk` 与钱包的 `UserEvents` 建立持久化 WebSocket 连接,以毫秒级延迟感知持仓变化。
|
||||||
|
* **基于 `oid` 的成交聚合**:将同一订单(`oid`)在 500ms 窗口内的多笔分批成交聚合为一行统一记录,避免拆单产生重复的数据库条目。
|
||||||
|
* **开仓事件捕获**:通过校验起始仓位(`start_position`)是否为零来识别开仓动作。目前仅捕获开仓(忽略平仓,以规避拆单的复杂性)。
|
||||||
|
* **订单类型识别**:自动识别订单执行类型(taker 成交 `crossed == true` 记为 `MARKET`,maker 成交 `crossed == false` 记为 `LIMIT`)。
|
||||||
|
* **健壮的重连机制**:实现了健壮的连接循环,在网络抖动或 WebSocket 断开后自动重连。
|
||||||
|
* **Notion 集成**:集成 `notion-client` API,将结构化数据行(`Symbol`、`Quantity`、`Filled Price`、`Direction`、`Exchange`、`DataTime`、`Order ID`、`Order Type`、`Check`)直接写入目标 Notion 数据库。
|
||||||
|
|
||||||
|
## 3. Notion 模板与效果预览
|
||||||
|
本项目向 Notion 数据库写入数据,你需要先准备一个字段结构匹配的数据库。可直接复制官方模板(点击右上角 **Duplicate** 即可一键复制到你的工作区):
|
||||||
|
|
||||||
|
> 📋 **Notion 数据库模板**:<https://annafish.notion.site/2026-2e08f81ac37080c6a474f00373d13287>
|
||||||
|
|
||||||
|
复制后,将该数据库的 ID 填入 `.env` 的 `NOTION_DATABASE_ID`,并把你的 Notion 集成(integration)连接到该页面即可。
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>🗂️ Notion 数据库示例页面(点击展开)</summary>
|
||||||
|
|
||||||
|
<img src="https://img.cathiefish.art/github/tradesync/tradesync1.png" width="720" alt="tradesync 数据库示例" />
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>📜 单条记录页完整长截图(点击展开)</summary>
|
||||||
|
|
||||||
|
<img src="https://img.cathiefish.art/github/tradesync/tradesync2.png" width="420" alt="tradesync 记录页示例" />
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
> 🖼️ **关于记录页里的 TradingView 实时截图**
|
||||||
|
> 记录页中多周期(15m / 1h / 4h / 1D)的 TradingView 实时截图,并非由 `tradesync` 自身生成,而是由配套服务 **TradeSnap**(独立仓库:<https://github.com/exchanges-lab/tradesnap>)负责。`tradesync` 在写入 Notion 后,通过 `TRADESNAP_URL` 调用 TradeSnap 拉取截图并追加到对应页面。
|
||||||
|
> 该功能为可选项,由 `ENABLE_SCREENSHOT` 控制;关闭时 `tradesync` 仅写入交易数据行,不依赖 TradeSnap。
|
||||||
|
|
||||||
|
## 4. 架构与模块
|
||||||
|
目录结构与模块说明如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
tradesync/
|
||||||
|
├── src/
|
||||||
|
│ ├── lib.rs # 统一模块导出
|
||||||
|
│ ├── structs.rs # 数据模型与事件定义(如 NotionRowData)
|
||||||
|
│ ├── hyperliquid.rs # Hyperliquid WebSocket 监控实现
|
||||||
|
│ └── notion.rs # Notion 数据库写入实现
|
||||||
|
├── examples/ # 开发示例
|
||||||
|
│ ├── demo.rs # 实时钱包监控示例
|
||||||
|
│ └── fetch_notion_db.rs # 用于获取 Notion 数据库 schema 属性的开发脚本
|
||||||
|
├── tests/ # 集成测试与单元测试
|
||||||
|
│ └── monitor_test.rs # 监控连通性与重连循环测试
|
||||||
|
├── references/ # 本地参考子模块
|
||||||
|
├── docker-compose.yml # Docker Compose 部署编排
|
||||||
|
├── Dockerfile # 容器镜像构建文件
|
||||||
|
├── .env # 本地环境变量配置(已被 git 忽略)
|
||||||
|
├── .env.example # 环境变量配置模板
|
||||||
|
├── Cargo.toml # Cargo 包文件,含远程 Git 依赖
|
||||||
|
└── CHANGELOG.md # 变更日志
|
||||||
|
```
|
||||||
|
|
||||||
|
* **HyperliquidMonitor**(`src/hyperliquid.rs`):长期运行的服务,维护与 Hyperliquid API 的 WebSocket 连接,并发出聚合后的交易事件。
|
||||||
|
* **NotionWriter**(`src/notion.rs`):将捕获到的数据行格式化并写入 Notion 数据库。
|
||||||
|
* **structs**(`src/structs.rs`):定义 `PositionTradeEvent`、`NotionRowData` 等数据模型。
|
||||||
|
|
||||||
|
## 5. 部署
|
||||||
|
|
||||||
|
### 方式一:Docker Compose(推荐)
|
||||||
|
项目已提供 `docker-compose.yml`,直接拉取预构建镜像 `ghcr.io/exchanges-lab/tradesync:latest` 运行,无需本地安装 Rust 工具链。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆仓库
|
||||||
|
git clone https://github.com/cathiefish/tradesync.git
|
||||||
|
cd tradesync
|
||||||
|
|
||||||
|
# 复制并配置环境变量
|
||||||
|
cp .env.example .env
|
||||||
|
# 编辑 .env,填入 WALLET_ADDRESS、NOTION_API_KEY、NOTION_DATABASE_ID 等
|
||||||
|
|
||||||
|
# compose 使用了一个名为 cycle 的外部网络,首次部署需先创建
|
||||||
|
docker network create cycle
|
||||||
|
|
||||||
|
# 拉取最新镜像并后台启动
|
||||||
|
docker compose pull
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 查看实时日志
|
||||||
|
docker compose logs -f
|
||||||
|
|
||||||
|
# 停止并移除容器
|
||||||
|
docker compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
> **说明**
|
||||||
|
> - `docker-compose.yml` 中的服务接入外部网络 `cycle`,便于与同网络下的其他服务(如截图服务 `tradesnap`)通信。若启用截图功能,请将 `TRADESNAP_URL` 设为该网络内可达地址(默认 `http://tradesnap:8003`)。
|
||||||
|
> - 容器配置了 `restart: unless-stopped`,宿主机重启后会自动拉起。
|
||||||
|
|
||||||
|
### 方式二:本地构建运行
|
||||||
|
适合开发调试或自行构建二进制:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆仓库
|
||||||
|
git clone https://github.com/cathiefish/tradesync.git
|
||||||
|
cd tradesync
|
||||||
|
|
||||||
|
# 复制并配置环境变量
|
||||||
|
cp .env.example .env
|
||||||
|
# 编辑 .env 文件,填入你的 WALLET_ADDRESS、Notion 集成 token 与数据库 ID
|
||||||
|
|
||||||
|
# 构建项目
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
# 运行监控同步服务
|
||||||
|
cargo run
|
||||||
|
|
||||||
|
# 运行本地监控示例
|
||||||
|
cargo run --example demo
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. 环境变量
|
||||||
|
| 变量 | 说明 | 是否必填 | 默认值 / 示例值 |
|
||||||
|
| :--- | :--- | :--- | :--- |
|
||||||
|
| `WALLET_ADDRESS` | 要监控的 Ethereum/Hyperliquid 钱包地址 | **是** | `0xc64cc00b46101bd40aa1c3121195e85c0b0918d8` |
|
||||||
|
| `IS_TESTNET` | 连接 Hyperliquid 测试网(`true`/`false`) | 否 | `true` |
|
||||||
|
| `NOTION_API_KEY` | Notion 集成 token(内部密钥) | **是** | `secret_xxxxxx...` |
|
||||||
|
| `NOTION_DATABASE_ID` | Notion 数据库 ID | **是** | `2b08f81ac37083389c5c01242f3c1557` |
|
||||||
|
| `RUST_LOG` | 日志详细级别(error、warn、info、debug) | 否 | `info` |
|
||||||
|
| `ENABLE_SCREENSHOT` | 在 Notion 页面中启用 TradingView 图表截图(`true`/`false`) | 否 | `false` |
|
||||||
|
| `TRADESNAP_URL` | TradeSnap 服务的 API 端点 URL | 否 | `http://tradesnap:8003` |
|
||||||
|
| `BTCUSDT_SNAPSHOT` | 截图使用币安 USDT 合约(`true`)而非 USDC 合约(`false`) | 否 | `false` |
|
||||||
|
| `SYMBOL_15M_SNAPSHOT` | 捕获并插入 15m 周期截图(`true`/`false`) | 否 | `false` |
|
||||||
|
| `SYMBOL_1H_SNAPSHOT` | 捕获并插入 1h 周期截图(`true`/`false`) | 否 | `false` |
|
||||||
|
| `SYMBOL_4H_SNAPSHOT` | 捕获并插入 4h 周期截图(`true`/`false`) | 否 | `false` |
|
||||||
|
| `SYMBOL_1D_SNAPSHOT` | 捕获并插入 1D 周期截图(`true`/`false`) | 否 | `false` |
|
||||||
|
|
||||||
|
|
||||||
|
## 7. 开发与测试
|
||||||
|
### Git 分支策略
|
||||||
|
* `dev`:活跃开发分支。新功能与修复先合并到此分支。
|
||||||
|
* `main`:稳定的生产可用分支。
|
||||||
|
|
||||||
|
### 本地质量检查
|
||||||
|
在提交 Pull Request 之前,你**必须**运行:
|
||||||
|
```bash
|
||||||
|
# 自动格式化代码库
|
||||||
|
cargo fmt --all
|
||||||
|
|
||||||
|
# 运行 lint 检查
|
||||||
|
cargo clippy --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
|
# 执行测试套件
|
||||||
|
cargo test
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. 变更日志
|
||||||
|
有关项目更新的详细记录,请参阅 [CHANGELOG.md](./CHANGELOG.md)。
|
||||||
Reference in New Issue
Block a user