前言及免责本实例代码及所涉场景仅作为Web3+AI落地应用的技术案例,旨在展示两者结合的实现切入点与思路框架,不构成任何投资建议或交易诱导。代码中涉及的自动化交易策略存在资金损失风险,包括但不限于智能合约漏洞、市场流动性不足、预言机争议及模型决策失误。请勿将本代码直接用于真实资金交易,使
本实例代码及所涉场景仅作为 Web3 + AI 落地应用的技术案例,旨在展示两者结合的实现切入点与思路框架,不构成任何投资建议或交易诱导。代码中涉及的自动化交易策略存在资金损失风险,包括但不限于智能合约漏洞、市场流动性不足、预言机争议及模型决策失误。请勿将本代码直接用于真实资金交易,使用前应充分理解其机制并进行严格的安全审计。作者不对任何基于本代码的操作后果承担责任。
一、预测市场的套利机会
Polymarket 作为全球最大的去中心化预测市场平台,其独特的二元市场结构(YES/NO)天然存在套利空间。在理想状态下,同一事件的 YES 和 NO 代币价格之和应等于 1.0 美元(因为事件必然发生或不发生)。然而,由于市场分割、流动性差异和信息传播延迟,这种平价关系经常出现偏离——这正是自动化套利机器人的狩猎场。
传统量化交易依赖硬编码规则,而本文介绍的系统创新性地引入大语言模型作为决策中枢,让 AI 自主理解策略目标、分析市场数据并执行交易。
我们的系统采用模块化设计,四个核心工具函数构成交易闭环:
// 工具矩阵:感知 → 决策 → 执行
const allTools = [
searchMarketTool, // 感知:扫描市场机会
getWalletBalanceTool, // 感知:风控检查(防止透支)
getOrderBookTool, // 感知:获取买卖深度
executeOrderTool // 执行:下单成交
];
关键设计决策:
size = total_dollars / price与传统策略不同,我们使用 DeepSeek-V3 作为推理引擎:
const llm = new ChatOpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: { baseURL: "https://api.deepseek.com" },
modelName: "deepseek-chat",
temperature: 0, // 确定性输出,减少随机交易
});
通过 createOpenAIFunctionsAgent,LLM 获得工具调用能力(Function Calling) 。当接收到策略指令时,AI 会自主决定调用哪些工具、以什么顺序调用,以及如何从工具返回中提取信息。
搜索工具对接 Polymarket 的 Gamma API,提取关键字段:
// 返回结构化的套利分析数据
{
title: "2024 US Presidential Election",
markets: [{
question: "Will Trump win?",
clobTokenId: "0x...", // YES 代币 ID
prices: [0.62, 0.40], // [YES价格, NO价格]
outcomes: ["Yes", "No"]
}]
}
套利信号计算:当 YES价格 + NO价格 ≠ 1.0 时,存在套利空间。例如:
获取订单簿不是为了显示,而是为了计算实际可成交的套利空间:
const book = await client.getOrderBook(tokenId);
// 分析前2档买卖盘,计算滑点成本
LLM 会评估:当前买一/卖一价差是否足够覆盖 3% 收益门槛?深度是否支持目标仓位?
// 三重防护
if (total_dollars > 50) return "拒绝执行:单笔金额严禁超过 50 USDC";
const size = Math.floor(total_dollars / price);
if (size <= 0) return "错误:投入金额不足以购买 1 份";
为什么用限价单而非市价单?
while (true) {
console.log(`[${new Date().toLocaleTimeString()}] 开始新一轮扫描...`);
await executor.invoke({ input: strategyGoal });
// 强制冷却:2分钟观察期
await new Promise(resolve => setTimeout(resolve, 120000));
}
工程考量:
最精妙的设计在于:策略本身用自然语言描述:
startAutoTrading("搜索关于『2024美国大选』的市场,寻找 YES 和 NO 之间价格加总偏离 1.0 太多的套利机会,并执行操作。");
LLM 理解:
这种声明式策略定义让非技术人员也能调整交易逻辑,无需修改代码。
| 风险类型 | 防护措施 |
|---|---|
| 资金风险 | 单笔50 USDC硬性上限 |
| 透支风险 | 交易前查询链上余额 |
| 价格风险 | 限价单控制成交价格 |
| 操作风险 | 2分钟冷却防止过度交易 |
client.postOrder 前增加 dryRun 参数空跑验证| 层级 | 技术选型 | 作用 |
|---|---|---|
| 区块链交互 | ethers.js |
Polygon 网络连接、USDC 合约查询 |
| 市场数据 | @polymarket/clob-client |
订单簿获取、下单执行 |
| AI 框架 | langchain |
Agent 编排、工具调用管理 |
| LLM 模型 | DeepSeek-V3 |
策略理解、决策推理 |
| 运行时 | Node.js + dotenv |
环境配置、无限循环守护 |
这个系统展示了LLM Agent 在金融交易领域的应用潜力:不是让 AI "预测"价格(这仍然困难),而是让 AI 理解规则、执行流程、管理风险。在预测市场这种规则明确、数据结构化、套利逻辑清晰的场景中,LLM 的推理能力可以显著降低策略开发门槛。
未来演进方向包括:多市场并行监控、动态调整扫描频率、基于历史胜率的学习优化,以及与其他 DeFi 协议的组合套利(如结合期权、永续合约进行对冲)。
import { ethers } from "ethers";
import { ClobClient } from "@polymarket/clob-client";
import { z } from "zod";
import dotenv from 'dotenv';
import { DynamicStructuredTool } from "@langchain/core/tools";
dotenv.config();
// --- 初始化驱动 ---
const provider = new ethers.JsonRpcProvider(process.env.POLYGON_RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
const client = new ClobClient(
"https://clob.polymarket.com",
137,
wallet,
{
apiKey: process.env.POLY_API_KEY,
apiSecret: process.env.POLY_API_SECRET,
apiPassphrase: process.env.POLY_PASS_PHRASE,
}
);
// 1. 搜索工具(修正 URL 和数据结构)
const searchMarketTool = new DynamicStructuredTool({
name: "search_polymarket",
description: "搜索 Polymarket 市场。返回包含 YES 和 NO TokenID 及价格的市场列表,用于计算套利空间(YES价格 + NO价格 偏离 1.0)。",
schema: z.object({
query: z.string().describe("关键词,如 'Election'")
}),
func: async ({ query }) => {
try {
// 修正后的 Gamma API URL
const url = `https://gamma-api.polymarket.com{encodeURIComponent(query)}`;
const response = await fetch(url);
const data = await response.json();
// 提取完整的市场对比数据
return JSON.stringify(data.slice(0, 3).map(event => ({
title: event.title,
markets: event.markets.map(m => ({
question: m.question,
// 同时返回 YES 和 NO 的 TokenID 供 Agent 对比
clobTokenId: m.clobTokenId,
prices: m.outcomePrices, // 通常 [YES价格, NO价格]
outcomes: m.outcomes // 通常 ["Yes", "No"]
}))
})));
} catch (error) {
return `搜索失败: ${error.message}`;
}
},
});
// 2. 余额查询工具(新增:防止透支报错)
const getWalletBalanceTool = new DynamicStructuredTool({
name: "get_wallet_balance",
description: "查询当前钱包在 Polygon 网络上的 USDC 余额。",
schema: z.object({}), // 无需参数
func: async () => {
try {
// Polymarket 主要使用 USDC (Polygon 上的地址)
const usdcAddress = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
const abi = ["function balanceOf(address) view returns (uint256)"];
const contract = new ethers.Contract(usdcAddress, abi, provider);
const balance = await contract.balanceOf(wallet.address);
return `当前钱包余额: ${ethers.formatUnits(balance, 6)} USDC`;
} catch (e) {
return `查询余额失败: ${e.message}`;
}
}
});
// 3. 下单工具(修正:金额到份数的换算)
const executeOrderTool = new DynamicStructuredTool({
name: "execute_polymarket_order",
description: "在 Polymarket 下达限价单。注意:amount 是你想投入的美元金额,我会自动换算成购买份数。",
schema: z.object({
tokenId: z.string().describe("目标的 Token ID"),
price: z.number().describe("下单价格/赔率 (0.01-0.99)"),
total_dollars: z.number().describe("准备投入的总美元金额"),
side: z.enum(["BUY", "SELL"])
}),
func: async ({ tokenId, price, total_dollars, side }) => {
try {
// 风控:硬性上限
if (total_dollars > 50) return "拒绝执行:单笔金额严禁超过 50 USDC。";
// 换算:Polymarket API 需要的是 size (份数)
// 份数 = 投入金额 / 单价
const size = Math.floor(total_dollars / price);
if (size <= 0) return "错误:投入金额不足以购买 1 份。";
const order = await client.createOrder({
tokenID: tokenId,
price: price,
side: side.toUpperCase(),
size: size,
});
// 重要:如果是第一次测试,可以将下一行改为 return JSON.stringify(order) 进行空跑
const response = await client.postOrder(order);
return `订单提交成功!ID: ${response.orderID}, 购买份数: ${size}`;
} catch (e) {
return `交易失败: ${e.message}`;
}
}
});
// 4. 订单簿查询(保持不变)
const getOrderBookTool = new DynamicStructuredTool({
name: "get_market_orderbook",
description: "获取买卖盘深度。",
schema: z.object({ tokenId: z.string() }),
func: async ({ tokenId }) => {
try {
const book = await client.getOrderBook(tokenId);
return JSON.stringify({ asks: book.asks.slice(0, 2), bids: book.bids.slice(0, 2) });
} catch (e) { return `获取深度失败: ${e.message}`; }
}
});
export const Tools = {
searchMarketTool,
getWalletBalanceTool,
getOrderBookTool,
executeOrderTool
};
import dotenv from 'dotenv';
import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
// import { DynamicStructuredTool } from "@langchain/core/tools";
// import { z } from "zod";
dotenv.config();
// import { Tools } from "./tools.js";
// const { searchMarketTool, getOrderBookTool, executeOrderTool } = Tools;
import { Tools } from "./tools1.js";
// AgentExecutor.js 中修改这一行
const { searchMarketTool, getWalletBalanceTool, getOrderBookTool, executeOrderTool } = Tools;
const allTools = [searchMarketTool,getWalletBalanceTool, getOrderBookTool, executeOrderTool].filter(
(tool) => tool !== undefined
);
// 检查工具数量是否符合预期
if (allTools.length < 4) {
throw new Error(`工具加载不完整!期望 4 个,实际加载了 ${allTools.length} 个。`);
}
// 定义策略逻辑
async function startAutoTrading(strategyGoal) {
// --- 1. 定义策略目标 ---
const prompt = ChatPromptTemplate.fromMessages([
["system", `你是一个专业的无人值守套利机器人。
你的任务是:
1. 扫描市场。
2. 分析买卖深度,寻找价格差或不合理的赔率。
3. 计算预期收益率(需扣除交易成本)。
4. 只有在收益率 > 3% 且单笔风险 < 50 刀时才下单。
5. 每一轮操作后,总结你的动作。`],
["human", "{input}"],
new MessagesPlaceholder("agent_scratchpad"),
]);
// --- 2. 配置 DeepSeek 模型 ---
const llm = new ChatOpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
configuration: {
baseURL: "https://api.deepseek.com",
},
modelName: "deepseek-chat",
temperature: 0,
});
const agent = await createOpenAIFunctionsAgent({ llm, tools: allTools, prompt });
const executor = new AgentExecutor({ agent, tools: allTools, verbose: true });
console.log("🚀 全自动交易机器人已启动...");
while (true) {
try {
console.log(`\n[${new Date().toLocaleTimeString()}] 开始新一轮扫描...`);
await executor.invoke({
input: strategyGoal
});
// 强制休眠 2 分钟,防止 API 频率受限或产生过多 token 费用
console.log("⏳ 扫描结束,进入观察期...");
await new Promise(resolve => setTimeout(resolve, 120000));
} catch (error) {
console.error("❌ 循环中出现异常:", error.message);
await new Promise(resolve => setTimeout(resolve, 30000)); // 遇到错误休息 30 秒
}
}
}
// 启动!
startAutoTrading("搜索关于『2024美国大选』的市场,寻找 YES 和 NO 之间价格加总偏离 1.0 太多的套利机会,并执行操作。"); 如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!