Skip to content

kuncle/perp-arbitrage-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Perpetual Arbitrage Bot

跨 DEX 永续合约套利机器人,运行在 Arbitrum 链上。监控 AZverse DEX 与多个永续合约交易所之间的价格差异,自动执行套利交易。

功能特性

  • 🔄 实时价格监控 - WebSocket 连接多个交易所,毫秒级价格更新
  • 🎯 套利机会检测 - 自动计算价差、手续费、滑点,筛选有利可图的机会
  • 自动交易执行 - 同时在两个交易所开仓,捕获价差收益
  • 📊 仓位管理 - 实时 PnL 监控,自动止盈止损
  • 🛡️ 风险控制 - 仓位限制、日亏损限制、最大持仓时间
  • 📢 告警通知 - 支持 Telegram、Discord、Webhook 通知
  • 💾 数据持久化 - MySQL 存储交易记录和历史价格
  • 📈 回测引擎 - 历史数据验证策略有效性

支持的交易所

交易所 类型 状态
AZverse DEX (Arbitrum) ✅ 已实现
Paradex DEX (Starknet) ✅ 已实现
Binance Futures CEX ✅ 已实现

快速开始

1. 环境要求

  • Rust 1.70+
  • MySQL 8.0+
  • 稳定的网络连接

2. 安装

# 克隆项目
git clone <repository-url>
cd perp-arbitrage-bot

# 编译
cargo build --release

3. 配置

# 复制配置模板
cp .env.example .env

# 编辑配置文件
vim .env

4. 数据库初始化

运行前需要先初始化数据库:

# 创建数据库
mysql -u root -p -e "CREATE DATABASE arbitrage_bot;"

# 执行建表脚本
mysql -u root -p arbitrage_bot < migrations/001_init.sql

程序启动时也会自动检查并创建缺失的表。

5. 运行

# Dry Run 模式 (只观察,不交易)
DRY_RUN=true cargo run --release

# 正式交易模式
DRY_RUN=false cargo run --release

Docker 部署

使用 Docker Compose (推荐)

# 复制配置文件
cp .env.example .env
# 编辑配置
vim .env

# 启动服务 (包含 MySQL)
docker-compose up -d

# 查看日志
docker-compose logs -f arbitrage-bot

# 停止服务
docker-compose down

单独构建镜像

# 构建镜像
docker build -t perp-arbitrage-bot .

# 运行 (需要外部 MySQL)
docker run -d \
  --name arbitrage-bot \
  --env-file .env \
  -e DB_HOST=host.docker.internal \
  perp-arbitrage-bot

生产环境部署

# 使用生产配置
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

配置说明

运行模式

# 设置为 true 启用观察模式,只输出机会不执行交易
DRY_RUN=true

AZverse 配置 (必需)

AZVERSE_WS_URL=wss://fstream.azverse.xyz/ws/market?type=SYMBOL
AZVERSE_API_URL=https://app.azverse.xyz/fapi
AZVERSE_TOKEN=your_token          # 从浏览器 Cookie 获取
AZVERSE_CLIENT_CODE=your_code     # 从浏览器 Cookie 获取
AZVERSE_SESSION_ID=your_session   # JSESSIONID

获取 AZverse 凭证:

  1. 登录 https://app.azverse.xyz
  2. 打开浏览器开发者工具 (F12)
  3. 在 Application > Cookies 中找到 token, client-code, JSESSIONID

Binance Futures 配置

BINANCE_WS_URL=wss://fstream.binance.com/stream?streams=btcusdt@bookTicker/ethusdt@bookTicker
BINANCE_API_URL=https://fapi.binance.com
BINANCE_API_KEY=your_api_key
BINANCE_API_SECRET=your_api_secret
BINANCE_ENABLED=true
BINANCE_MAKER_FEE=0.02
BINANCE_TAKER_FEE=0.04

Paradex 配置

PARADEX_WS_URL=wss://ws.api.prod.paradex.trade/v1?cancel-on-disconnect=false
PARADEX_API_URL=https://api.prod.paradex.trade/v1
PARADEX_ENABLED=true
PARADEX_MAKER_FEE=0.02
PARADEX_TAKER_FEE=0.05

Paradex 说明:

  • WebSocket 使用 JSON-RPC 格式
  • 交易对格式: BTC-USD-PERP, ETH-USD-PERP
  • 自动订阅 order_book 频道获取最优买卖价
  • 无需 API Key 即可获取行情数据 (交易需要)

风险参数

# 单个交易对最大仓位 (USD)
MAX_POSITION_SIZE_USD=10000

# 总敞口上限 (USD)
MAX_TOTAL_EXPOSURE_USD=50000

# 日亏损限制 (USD) - 超过后暂停交易
DAILY_LOSS_LIMIT_USD=1000

# 止损百分比
STOP_LOSS_PERCENT=2.0

# 最大持仓时间 (秒) - 超过后强制平仓
MAX_POSITION_DURATION_SECS=3600

套利参数

# 最小价差阈值 (%) - 低于此值不开仓
MIN_SPREAD_PERCENT=0.1

# 平仓价差阈值 (%) - 价差收敛到此值时平仓
EXIT_SPREAD_PERCENT=0.02

# 告警价差阈值 (%)
ALERT_SPREAD_PERCENT=0.05

# 交易对列表
TRADING_PAIRS=BTC_USDT,ETH_USDT

告警配置

# Telegram
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_CHAT_ID=your_chat_id

# Discord
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...

# 告警频率限制 (每分钟)
ALERT_RATE_LIMIT=10

数据库配置

DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=your_password
DB_DATABASE=arbitrage_bot

运行模式

Dry Run 模式 (推荐先使用)

只监控价格和检测机会,不执行实际交易。用于验证策略和配置。

DRY_RUN=true cargo run --release

输出示例:

INFO 🔍 DRY RUN MODE ENABLED
INFO 📊 Price: AZverse BTC_USDT | bid=50000.00 ask=50010.00 mid=50005.00
INFO 📊 Price: Binance BTC_USDT | bid=50050.00 ask=50060.00 mid=50055.00
INFO 🎯 OPPORTUNITY: BTC_USDT | spread=0.10% | net_profit=$15.00 | long@AZverse short@Binance
INFO    └─ [DRY RUN] Would execute: BUY on AZverse, SELL on Binance | size=$10000.00

正式交易模式

DRY_RUN=false cargo run --release

套利策略说明

工作原理

  1. 价格监控: 通过 WebSocket 实时获取各交易所价格
  2. 机会检测: 当 AZverse 与对冲交易所价差超过阈值时触发
  3. 方向判断:
    • AZverse 价格低 → 在 AZverse 开多,对冲交易所开空
    • AZverse 价格高 → 在 AZverse 开空,对冲交易所开多
  4. 利润计算: 净利润 = 毛利润 - 手续费 - Gas费 - 滑点
  5. 平仓时机:
    • 价差收敛到退出阈值
    • 达到止盈/止损
    • 超过最大持仓时间

风险提示

⚠️ 重要: 套利交易存在风险,包括但不限于:

  • 价格剧烈波动导致亏损
  • 交易所 API 故障
  • 网络延迟导致执行失败
  • 流动性不足导致滑点过大

建议:

  1. 先使用 Dry Run 模式观察
  2. 从小仓位开始
  3. 设置合理的止损
  4. 监控系统运行状态

回测

回测引擎用于在历史数据上验证策略效果。

运行回测

# 使用默认参数运行回测(使用模拟数据)
cargo run --bin backtest

# 自定义参数
cargo run --bin backtest -- \
  --start-date 2024-01-01 \
  --end-date 2024-12-31 \
  --capital 50000 \
  --min-spread 0.15 \
  --exit-spread 0.03 \
  --position-size 5

# 运行参数优化扫描
cargo run --bin backtest -- --sweep

回测参数

参数 说明 默认值
--start-date 开始日期 (YYYY-MM-DD) 30天前
--end-date 结束日期 (YYYY-MM-DD) 今天
--capital 初始资金 (USD) 10000
--min-spread 最小价差阈值 (%) 0.1
--exit-spread 平仓价差阈值 (%) 0.02
--position-size 仓位大小 (% of capital) 10
--sweep 运行参数优化扫描 -

回测输出

╔══════════════════════════════════════════════════════════════╗
║                     Backtest Results                         ║
╠══════════════════════════════════════════════════════════════╣
║ Performance Summary                                          ║
╠══════════════════════════════════════════════════════════════╣
║ Initial Capital:     $    10000.00                          ║
║ Final Capital:       $    12500.00                          ║
║ Total Return:               25.00%                          ║
║ Total PnL:           $     2500.00                          ║
╠══════════════════════════════════════════════════════════════╣
║ Trade Statistics                                             ║
╠══════════════════════════════════════════════════════════════╣
║ Total Trades:                 150                            ║
║ Winning Trades:               120                            ║
║ Losing Trades:                 30                            ║
║ Win Rate:                   80.00%                          ║
╠══════════════════════════════════════════════════════════════╣
║ Risk Metrics                                                 ║
╠══════════════════════════════════════════════════════════════╣
║ Max Drawdown:        $      500.00                          ║
║ Sharpe Ratio:                2.50                           ║
║ Profit Factor:               3.20                           ║
╚══════════════════════════════════════════════════════════════╝

使用真实数据回测

  1. 先运行 bot 收集历史价格数据到数据库
  2. 修改 src/bin/backtest.rs 中的 generate_demo_price_data 函数,改为从数据库加载:
// 从数据库加载价格数据
let price_data = data_store.get_price_history(
    "BTC_USDT",
    "AZverse", 
    config.start_date,
    config.end_date
).await?;

低成本刷量 (Volume Farming)

在 AZverse 和 Paradex 之间进行低成本交易量刷取,使用限价单 (Maker) 降低手续费。

成本分析

费用类型 AZverse Paradex 说明
Maker 费率 0.02% 0.02% 限价单成交
Taker 费率 0.05% 0.05% 市价单成交
往返成本 (Maker) - - 0.08%

使用 Maker 单可将成本从 0.20% 降至 0.08%,刷 $10,000 交易量节省 $12。

运行刷量回测

# 默认配置回测 (7天模拟数据)
cargo run --bin volume_farming

# 自定义参数
cargo run --bin volume_farming -- \
  --min-spread 0.08 \
  --exit-spread 0.02 \
  --position-size 1000 \
  --max-hold 600 \
  --days 14

# 参数优化扫描 (找最优配置)
cargo run --bin volume_farming -- --sweep

# 使用预设模式
cargo run --bin volume_farming -- --mode minimum_cost   # 最低成本模式
cargo run --bin volume_farming -- --mode aggressive     # 激进刷量模式

# 使用真实数据回测 (需要先收集数据)
cargo run --bin volume_farming -- --real-data --days 7

刷量参数

参数 说明 默认值
--min-spread 最小价差开仓阈值 (%) 0.10
--exit-spread 价差收敛平仓阈值 (%) 0.02
--position-size 单笔仓位大小 (USD) 500
--max-hold 最大持仓时间 (秒) 300
--cooldown 交易冷却时间 (秒) 30
--days 回测天数 7
--mode 预设模式: default/minimum_cost/aggressive default
--sweep 运行参数优化扫描 -
--real-data 使用数据库中的真实数据 否 (默认模拟数据)

数据来源说明

回测支持两种数据来源:

数据类型 说明 适用场景
模拟数据 (默认) 随机生成的价格数据,8% 概率产生价差机会 快速验证策略逻辑
真实数据 (--real-data) 从数据库 price_snapshots 表读取 准确评估策略效果

使用真实数据回测

  1. 先运行 bot 收集历史价格数据:

    # 以 Dry Run 模式运行,只收集数据不交易
    DRY_RUN=true cargo run --release
  2. 确保数据库中有数据:

    • 数据存储在 price_snapshots
    • 需要 AZverse 和 Paradex 的价格数据
    • 建议至少收集 1-2 天的数据
  3. 运行真实数据回测:

    cargo run --bin volume_farming -- --real-data --days 7

⚠️ 注意: 如果数据库中没有足够的历史数据,回测会自动回退到模拟数据。

推荐配置 (基于回测)

# .env 刷量配置
MIN_SPREAD_PERCENT=0.06
EXIT_SPREAD_PERCENT=0.02
MAX_POSITION_SIZE_USD=500
MAX_POSITION_DURATION_SECS=600

回测输出示例

╔══════════════════════════════════════════════════════════════╗
║              Volume Farming Backtest Results                 ║
╠══════════════════════════════════════════════════════════════╣
║ Volume Statistics                                            ║
╠══════════════════════════════════════════════════════════════╣
║ Total Trades:                3845                            ║
║ Total Volume:        $ 3845000.00                          ║
║ Avg Volume/Trade:    $    1000.00                          ║
╠══════════════════════════════════════════════════════════════╣
║ Cost Analysis                                                ║
╠══════════════════════════════════════════════════════════════╣
║ Total Fees Paid:     $    1538.00                          ║
║ Spread PnL:          $    1125.27                          ║
║ Net PnL:             $    -412.73                          ║
║ Cost per $1000 Vol:  $     0.5073                          ║
╠══════════════════════════════════════════════════════════════╣
║ Trade Performance                                            ║
╠══════════════════════════════════════════════════════════════╣
║ Win Rate:                    51.8%                          ║
║ Avg Spread Captured:      -0.1314%                          ║
║ Avg Hold Time:                143s                          ║
║ Spread Closes:               3136                            ║
║ Timeout Closes:               522                            ║
╚══════════════════════════════════════════════════════════════╝

✅ 刷 $100 万交易量成本约 $507 (0.05%)

策略说明

  1. 开仓条件: 当 AZverse 与 Paradex 价差超过阈值时
  2. 对冲方式: 价格低的交易所做多,价格高的做空
  3. 平仓条件:
    • 价差收敛到退出阈值 (盈利平仓)
    • 超过最大持仓时间 (超时平仓)
  4. 费用优化: 使用限价单 (Maker) 而非市价单 (Taker)

项目结构

src/
├── main.rs           # 主入口,交易循环
├── lib.rs            # 库导出
├── config.rs         # 配置加载和验证
├── types.rs          # 核心数据类型
├── price_monitor.rs  # WebSocket 价格监控
├── opportunity.rs    # 套利机会检测
├── executor.rs       # 交易执行
├── position.rs       # 仓位管理
├── risk.rs           # 风险控制
├── alert.rs          # 告警服务
├── storage.rs        # 数据库操作
├── backtest.rs       # 回测引擎
└── azverse.rs        # AZverse 适配器

API 参考

核心模块

PriceMonitor

// 获取价格
let price = monitor.get_price("AZverse", "BTC_USDT").await;

// 检查是否过期
let is_stale = monitor.is_stale("AZverse").await;

OpportunityDetector

// 检测机会
let opportunities = detector.detect_opportunities(&prices, position_size);

// 选择最佳机会
let best = detector.select_best_opportunity(&opportunities);

TradeExecutor

// 执行套利
let result = executor.execute_arbitrage(&opportunity, size).await;

// 平仓
let close_result = executor.close_arbitrage_position(&position).await;

RiskManager

// 检查是否可以开仓
risk_manager.can_open_position(size)?;

// 记录 PnL
risk_manager.record_pnl(pnl);

// 检查是否暂停交易
if risk_manager.is_trading_paused() { ... }

测试

# 运行所有测试
cargo test

# 运行特定模块测试
cargo test opportunity::tests

# 运行属性测试
cargo test prop_

日志级别

# 详细日志
RUST_LOG=debug cargo run

# 只显示警告和错误
RUST_LOG=warn cargo run

# 特定模块日志
RUST_LOG=perp_arbitrage_bot::opportunity=debug cargo run

常见问题

Q: WebSocket 连接失败?

A: 检查网络连接和 WebSocket URL 配置。系统会自动重连,使用指数退避策略。

Q: 交易执行失败?

A: 检查 API 凭证是否正确,账户余额是否充足。查看日志获取详细错误信息。

Q: 没有检测到机会?

A: 可能是价差未达到阈值。尝试降低 MIN_SPREAD_PERCENT 或使用 Dry Run 模式观察。

Q: 如何获取 AZverse 凭证?

A: 登录 AZverse 网站后,从浏览器 Cookie 中获取 token, client-code, JSESSIONID

License

MIT License

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors