做市机器人概览
Rocky 做市机器人(rocky-bot)是一个 Python 服务,部署在 EC2 上长期运行。它通过 30 个独立账号在 BTC-PERP / ETH-PERP 市场连续报价 + 主动成交, 为 demo.rocky.exchange 展示出多档深度的真实订单簿和持续的成交活动。
当前部署:systemd-user 服务
rocky-bot,单进程内运行 ~61 个 asyncio 任务。仓库:/Users/ubuntu/Desktop/Rocky/rocky-bot。
一、为什么需要做市机器人
Rocky 是一个早期 demo 环境,没有真实用户交易量。如果不有人持续报价:
- 订单簿是空的,看起来像死盘
- 没有成交活动,前端 K 线 / 成交流 永远是空白
- 用户即使下单也无人对手,无法验证撮合 / 结算流程
做市机器人替这个空白填上:
- 报价(Maker):在订单簿两侧挂限价单,形成多档深度
- 主动成交(Taker):每隔一段时间发起一笔积极挂单,确保有真实成交事件
- 链上奖励触发:每笔成交都触发
MiningReward合约创建,演示 MTC 挖矿机制(参见 MTC 挖矿奖励) - K 线 / 24h 统计填充:成交数据进入
ledger.trades,前端 K 线图、24h 量、最近成交都有数据
二、漏斗形态 (Funnel Geometry)
30 个账号按角色分布:
┌─────────────────────────────┐
Anchor (1 账号) │ mm-anchor │ best bid ± 1 bps
│ qty BTC: 0.0003 / ETH: 0.006
└─────────────────────────────┘
Ladder L1 (12 账号) │ mm-l1-{buy|sell}-{05..10}bps
│ qty BTC: 0.0005 / ETH: 0.01
Ladder L2 (8 账号) │ mm-l2-{buy|sell}-{15,20,25,30}bps
│ qty BTC: 0.001 / ETH: 0.02
Ladder L3 (4 账号) │ mm-l3-{buy|sell}-{50,100}bps
│ qty BTC: 0.002 / ETH: 0.04
Taker (5 账号) │ taker-{1..5}
│ qty BTC: 0.0005 / ETH: 0.01
│ cross 50 bps past mid, every 30s±10s
总账号数:1 anchor + 24 ladder + 5 taker = 30。
每个账号在 demo.rocky.exchange 是一个独立的注册用户,由 scripts/mint-30.sh 一次性 mint + seed $100 USDC。
2.1 为什么这种"漏斗"
- 中心密、边缘疏:anchor + L1 ladder 在 ±1-10 bps 范围内挂单,让 inside spread 永远很窄(看起来流动性好)
- L2/L3 提供深度:50-100 bps 处的挂单显示"市场承受得起大单",让深度图好看
- Taker 触发成交:纯挂单不会有成交活动;taker 主动 cross 50 bps 让每 30s 左右有一笔成交事件入账
- 多账号 vs 单账号:每个账号独立 risk budget($100 wallet),单账号爆仓不影响整体;同时演示"多个真实用户在交易"的视觉效果
2.2 容量数字
每账号 $100 USDC 种子资金。30 账号 = $3000 总流动性。
- 每个 ladder 账号最多承担 ~$15 仓位 margin($150 notional × 10x leverage / 10 = $15)
- 每个 taker 账号同上
- 总锁仓上限 = 30 × $30 ≈ $900(足以支撑深度展示而不被市场吃光)
详细的 risk 配置见 风控与杠杆。
三、整体架构
rocky-bot 是单进程多 asyncio 任务:
rocky-bot (systemd-user service on EC2)
│
├── BinanceFeed (1 task)
│ └── WebSocket 订阅 btcusdt + ethusdt bookTicker,缓存 mid price
│
├── For each account in .keys.json (30 总数):
│ │
│ ├── If role=ladder:
│ │ LadderMakerLoop × 2 symbols = 48 tasks
│ │ └── 每 3s ± 1s:取 mid → 算 target → 比对现有 open order → cancel/place
│ │
│ ├── If role=anchor:
│ │ AnchorMakerLoop × 2 symbols = 2 tasks
│ │ └── 每 2s ± 0.5s:取 mid → 两侧 ±1 bps 都报价
│ │
│ └── If role=taker:
│ TakerLoop × 2 symbols = 10 tasks
│ └── 每 30s ± 10s:选 side(按持仓再平衡)→ 50 bps 激进 cross
│
└── Per-account CircuitBreaker (30 instances)
└── 跟踪 wallet 损益、API 错误,超过阈值则暂停该账号所有动作
总任务数:1 feed + 48 ladder + 2 anchor + 10 taker = 61 个 asyncio 任务。
四、技术栈
| 部分 | 选型 | 原因 |
|---|---|---|
| 语言 | Python 3.12 | 快速迭代、生态成熟 |
| 并发 | asyncio | 单进程内 60+ I/O bound 任务,asyncio 比 threading 轻量得多 |
| HTTP | httpx (async) | 异步、连接复用、不阻塞事件循环 |
| 配置 | pydantic-settings + 自定义 .keys.json | 30 账号的 API key 直接写 .env 太丑 |
| 市场数据 | websockets → wss://fstream.binance.com | 免费、低延迟、不与 demo 后端的撮合冲突 |
| 部署 | rsync + uv + systemctl --user | 简单、低依赖、可观测 |
五、与 Rocky 后端的关系
rocky-bot rocky-backend (EC2)
├── 调用 /fapi/v1/order ─────────────► api-gateway → trading-api → internal-ledger
├── 调用 /fapi/v1/order DELETE ──────► ...
├── 调用 /fapi/v1/positionRisk ──────► api-gateway → matching-engine query
└── 调用 /fapi/v1/balance ───────────► api-gateway → internal-ledger query
Auth: HMAC-SHA256 签每个请求,密钥来自 .keys.json
机器人不走 /api/perp/* 这套 web BFF,而是直接打 /fapi/v1/*(Binance 兼容路径),用 API key + HMAC 签名认证。这套接口是为程序化交易者准备的,对应后端表 auth.api_keys(与 用户注册接口 的 auth.users 表完全独立)。