前言
关于NestJS框架的基础知识,您可以前往官网查阅相关文档,或参考作者之前的文章《NestJS连接MySQL数据库实现CRUD接口》。本文主要介绍如何借助NestJS框架和Polymarket提供的API,实现一个自动套利的MVP(最小可行产品)版本。当然,在开始之前,您还需要了解一些Polymarket平台的基本玩法以及相关智能合约的基础知识。本文的目的主要是提供实现思路和可行性方案。
一、这是什么?
这是一个基于 NestJS 框架开发的自动化套利交易系统,专门对接 Polymarket(全球最大的去中心化预测市场平台)的 CLOB(Central Limit Order Book,中央限价订单簿)API。
核心定位
- 市场:Polymarket 预测市场(Polygon 链上)
- 策略:二元市场无风险套利(Yes/No 对冲)
- 技术栈:NestJS + TypeScript + Ethers.js + Polymarket CLOB Client
二、它能做什么?
1. 账户资产管理
| 功能 | 说明 |
|---|---|
| USDC 余额查询 | 实时获取钱包中的 USDC 余额及授权额度 |
| 自动授权检测 | 检查并自动完成 USDC 对 CLOB 交易所的无限授权 |
| Gas 与余额预检 | 下单前验证余额是否充足(2倍安全边际) |
代码核心逻辑:
async getUsdcBalance() {
const data = await this.client.getBalanceAllowance({
asset_type: AssetType.COLLATERAL
});
return { usdc: data.balance, allowance: data.allowance };
}
2. 市场数据分析
| 功能 | 说明 |
|---|---|
| 指定市场分析 | 通过 slug 获取特定市场的订单簿深度 |
| 热门市场扫描 | 按 24h 交易量排序获取活跃市场列表 |
| 并行套利计算 | 同时分析多个市场的 Yes/No 价格组合 |
套利检测原理:
// 当 Yes 和 No 的卖价之和小于 1 时,存在套利空间
const combinedPrice = yesAsk + noAsk;
const profitPotential = 1 - combinedPrice;
const isProfitable = profitPotential > 0.001; // 0.1% 利润阈值
示例场景:
- Yes Token 卖价:0.48 USDC
- No Token 卖价:0.51 USDC
- 组合成本:0.99 USDC
- 到期收益:1 USDC
- 无风险利润:1%(扣除手续费后净赚)
3. 自动化交易执行
| 功能 | 说明 |
|---|---|
| 对冲下单 | 同时买入 Yes 和 No,锁定利润 |
| 滑点保护 | 按 Ask 价格 +0.1% 溢价确保成交 |
| 模拟模式 | 支持 Dry Run 测试,不实际下单 |
| 一键全扫描 | 自动遍历热门市场,发现机会立即执行 |
下单逻辑:
async executeArbitrageOrder(slug: string, amountPerSide: number) {
// 1. 验证套利空间
const opp = await this.getArbitrageOpportunity(slug);
if (!opp.isProfitable) throw new Error('无利润空间');
// 2. 计算滑点后价格
const yesPrice = Math.min(0.99, opp.yesPrice * 1.001);
const noPrice = Math.min(0.99, opp.noPrice * 1.001);
// 3. 执行双边买入(当前为模拟模式)
return { status: 'Simulated', slug };
}
4. REST API 接口
系统暴露以下 HTTP 端点供外部调用:
| 端点 | 方法 | 功能 |
|---|---|---|
GET /clob/balance | 查询 | 获取 USDC 余额和授权状态 |
GET /clob/status | 查询 | 系统健康状态检查 |
GET /clob/analyze?slug=xxx | 分析 | 分析指定市场的套利机会 |
GET /clob/execute?slug=xxx&amount=5 | 交易 | 执行指定市场的套利下单 |
GET /clob/scan-hot?limit=10 | 扫描 | 并行扫描热门市场套利机会 |
三、技术亮点
1. 代理与网络优化
private readonly agent = new HttpsProxyAgent({
keepAlive: true,
proxy: 'http://127.0.0.1:xxxx',//自己vpn的端口
});
- 支持本地代理(如 Karing)解决网络访问问题
- 长连接保持,减少握手开销
2. 并行异步处理
const results = await Promise.allSettled(
hotMarkets.map(market => this.clobService.getArbitrageOpportunity(market.slug))
);
- 使用
Promise.allSettled并行分析多个市场 - 单个市场失败不影响整体扫描
3. 风险控制机制
- 余额预检:下单前确保 2 倍资金储备
- 价格上限:买入价格不超过 0.99(防止极端报价)
- 利润阈值:仅当利润 > 0.1% 才触发交易
四、使用场景
| 场景 | 操作 |
|---|---|
| 手动套利 | 发现特定市场机会 → 调用 /execute 下单 |
| 自动监控 | 定时调用 /scan-hot 扫描 → 自动执行高利润机会 |
| 风险管理 | 通过 /balance 监控资金,设置告警阈值 |
| 策略回测 | 使用 Dry Run 模式验证策略有效性 |
五、架构图
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ NestJS API │────▶│ ClobService │────▶│ Polymarket │
│ (Controller) │ │ (Business) │ │ CLOB API │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Ethers.js │
│ (Polygon链交互) │
└─────────────────┘
六、注意事项
⚠️ 实盘交易前请确认:
- 私钥已正确配置且资金安全
- USDC 已授权给 CLOB 合约
- 考虑交易手续费对利润的影响(Polymarket 收取 2% 手续费)