关于 PMWallets copy-trading bot
PMWallets copy-trading bot 是 Node.js 和 TypeScript 机器人,可用操作者自己的账户,按设定限额复制已订阅交易者在 Polymarket 的成交。它默认使用模拟模式,密钥保留在本机,并能在中断后重放遗漏成交。
主要功能
- 01复制已订阅交易者的成交
- 02配置交易与持仓限额
- 03实盘交易前先模拟运行
- 04停机后重放遗漏成交
- 05保存决策与待处理订单
- 06通过命令行买入和卖出
适用场景
- 01不下单地测试跟单规则
- 02在支出上限内复制选定交易者
- 03机器人重启后恢复处理
- 04查看持仓、余额和交易决策
MCP 相关
`pmwallets-copytrade mcp` 命令根据机器人的配置,将其操作作为 MCP 工具提供。下单行为遵循配置的模拟或实盘模式。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Polymarket 跟单机器人(Node.js / TypeScript)
基于 PMWallets 构建的开箱即用 Polymarket 跟单机器人:它会跟随你订阅的交易者,并在你设定的限额内,使用你自己的账户在 Polymarket CLOB 上复制他们的成交。
pmwallets-copytrade npm 包 · 中文说明 · Python 版本:polymarket-copy-trading-bot-python ·
SDK:pmwallets-node
机器人功能
- 选择要跟随的交易者:在 pmwallets.com 上根据胜率置信区间下界、剔除表现最佳的单个市场后的利润、活跃度和交易风格筛选列表,然后订阅。
- 机器人接收这些交易者的每笔成交:通过 PMWallets WebSocket 接收,通常在区块生成后一秒内到达(延迟测量)。机器人会检测遗漏的帧(
session/seq),并从上次处理的成交开始重放,包括机器人停机期间发生的所有交易。 - 在 Polymarket 上复制他们的交易:使用你自己的账户,并遵守你设定的限额。你的密钥不会离开你的机器;PMWallets 看不到密钥,也不会下单。
快速开始
# Node.js ≥ 20
npm install -g pmwallets-copytrade
pmwallets-copytrade init # writes config.yaml
export PMW_API_KEY=pmw_... # https://pmwallets.com/keys
pmwallets-copytrade run # dry-run: logs every decision, trades nothing
试运行日志看起来没问题后,切换到实盘模式:
mode: live
polymarket:
privateKey: ${POLY_PRIVATE_KEY} # signs your orders
signatureType: 3 # see "Set up a Polymarket account for the bot"
funderAddress: ${POLY_FUNDER_ADDRESS} # your Polymarket profile address (holds the USDC)
pmwallets-copytrade status 会打印未平仓头寸、今日支出,以及仍在确认中的订单。如果机器人无法自行确认订单是否成交,就会保留该订单的预留额度(因此不会有后续 BUY 因此超出你的限额),并提示你:检查 polymarket.com,然后在机器人停止时运行 pmwallets-copytrade reconcile <key> --none 或 --filled <shares> --usdc <usdc>。每项决策——包括每次跳过及其原因——都会追加到 pmw-data/decisions.<mode>.jsonl,机器人打印的所有内容也会写入 pmw-data/bot.<mode>.log。
遇到问题? 运行 pmwallets-copytrade diagnose,然后将它生成的 pmw-diagnose-<time>.json.gz 发送至 [email protected],并简单说明发生了什么。文件包含机器人的版本、check 结果、已移除密钥的配置、状态文件,以及最新日志和决策。文件不包含私钥或 API 密钥(它们会先按名称删除,再从整个文件中按值删除),但会显示你的钱包地址、你跟随的交易者、你的交易记录和机器的 IP。切勿发送 config.yaml 或 .env 文件本身。
决策规则
这些规则来自一个曾在 Polymarket 上实盘运行的跟单机器人;每条规则都是因为一次亏损交易或被拒绝的订单而加入的。
BUY(交易者买入)
- 跳过早于
maxFillAgeSec的成交(停机后的重放不能买入历史交易)、低于minTargetNotionalUsdc的成交,或来自你排除的角色的成交; - 每笔交易者交易最多复制一次,每个(交易者、结果)最多建立一个头寸;每个结果最多买入
maxBuysPerOutcome次(DCA),并遵守maxOpenPositionsPerTarget/maxOpenPositions/maxDailySpendUsdc限额; - 市场必须处于开放状态、接受订单,并且距离结算时间不少于
minSecondsToEndDate; - 最优卖价必须位于
[minPrice, maxPrice]范围内,且相对于交易者的成交价格,价差不得超过maxSlippage;订单簿必须有至少minBookDepthUsdc的深度; - 订单:按最优卖价,以确切的股数提交全部成交或立即取消的订单(
orderSizeUsdc/ 卖价),并进行舍入以满足 CLOB 要求。特意使用股数作为计价单位——按 USDC 预算下达的市价单可能会超量成交。 卖出(交易员已卖出) sellMode: all会退出机器人跟随该交易员买入的所有仓位。记在同一结果下其他交易员名下的份额绝不会卖出:最多只会卖出你的代币余额减去其他交易员持有的份额。如果没有可卖份额,机器人会停止并要求你对账;- 退出操作会保存并重试(采用退避策略,重启后也会继续),直到仓位清空。退出时不检查新鲜度:如果交易员在机器人离线期间离场,机器人仍会退出;
- 订单:以最佳买价提交成交或取消订单——部分退出也好过完全没有,剩余部分会重试。
Polymarket V2 市场(目前为金丝雀市场;自 2026-11-02 起适用于所有新市场)
- 规则相同,但使用 Polymarket 的新交易所(ExchangeV3,份额由 PositionManager 而非 Conditional Tokens 持有)。市场使用哪个交易所,取决于 CLOB 市场的
version,且必须与结果 ID 的格式一致(V2 仓位 ID 不是哈希)。如果两者不一致,或对于格式像 V2 仓位 ID 的 ID,CLOB 未提供版本信息,机器人会跳过买入(skipped_market_version),并保留退出操作以供重试:机器人绝不会猜测应为哪个交易所签名; - 组合单(多条腿的串关)通过 RFQ 报价,不会在订单簿上交易:始终跳过(
skipped_combo); - 这些市场需要单独授权——请参阅下方账户部分。
安全性
- 默认试运行;实盘模式必须显式设置
mode: live; - 最多执行一次:发送任何订单之前,成交就会先标记为已在状态文件中处理,因此崩溃时可能漏掉一次复制,但绝不会重复下单。每个数据目录只能运行一个机器人:第二个实例会拒绝启动;
- 成交不丢失:每笔订单都会在发送前保存为待处理。对于交易所报告为已取消的订单(这类回复中曾包含真实的部分成交),机器人会通过订单 ID 并采用退避策略反复查询,直到确认其成交情况——或确认没有成交,即使重启后也会继续。完全没有收到回复的订单没有可查询的 ID:如果出现匹配的交易,机器人不会猜测交易归属(可能是你手动下单,也可能是复制了另一位交易员的交易),而是交由你
reconcile; - 每 10 分钟清理一次已结算市场,避免它们继续计入上限。
运行位置。 PMWallets 的服务器位于英国,但 Polymarket 不接受来自英国、美国、德国、法国及其他若干国家和地区的新 API 订单(Polymarket:地理限制)。**爱尔兰(AWS eu-west-1)**是最近的可用区域,离我们的服务器和位于伦敦的 Polymarket 都很近。check 会报告你的机器所在区域是否受支持。实测延迟:https://pmwallets.com/latency。
每个账户只能有一个数据流,且机器人优先。 PMWallets 为每个账户保留一个 WebSocket 连接。使用 API 密钥建立的连接(即机器人)优先级更高:pmwallets.com 上的实时数据页面绝不会抢占机器人的数据流——机器人连接期间,页面会显示这一状态并保持关闭。在两个 API 连接之间,先连接者保留数据流:同一账户上的第二个机器人(使用另一个密钥,或同一个机器人启动两次)会被拒绝,并显示明确错误后停止。要主动将数据流切换到新机器人,请在新机器人中设置 pmwallets.takeover: true——旧机器人会收到已被替换的通知并停止。机器人因网络中断自行重连时不需要此设置。PMWallets 重启数据流服务后,机器人会立即重新连接并重放错过的内容。
面向 AI Agent 和脚本
除了 run,机器人还提供一些一次性命令,可打印 JSON,让 AI Agent(或脚本)自行决策并交易——例如,处理 pmwallets watch --exec 交给它的成交记录。这些命令使用相同的配置;配置中的 mode 决定运行方式:dry-run 会针对实时订单簿模拟每笔订单,不会发送订单;live 则会进行交易。
pmwallets-copytrade market <tokenId> # question, outcomes, prices, order book
pmwallets-copytrade balance # USDC to trade, approvals
pmwallets-copytrade positions # open positions, value, PnL
pmwallets-copytrade trades --limit 20
pmwallets-copytrade order buy <tokenId> --usdc 5 --max-price 0.45 --key <eventId>
pmwallets-copytrade order sell <tokenId> --all --min-price 0.40 --key <eventId>:exit
pmwallets-copytrade mcp --config /abs/path/config.yaml # the same as MCP tools
- BUY 为全额成交或取消;
--usdc是上限(按限价计算金额,因此订单费用不会超过该数值)。SELL 为全部成交或取消,且最多卖出账户持有的数量。 --key可确保重试安全:订单发送前,该键会写入dataDir,相同的键绝不会发送第二笔订单。请使用成交记录的eventId。status: unknown(或verify: true)表示订单可能已成交——发送另一笔订单前,请先检查trades。退出代码 0 = 已成交或 dry_run,2 = 未交易,3 = 状态未知。- 这些订单是你自己的交易:机器人的账本(持仓、每日上限)不会计入它们。请勿用这些订单卖出正在运行的机器人为某个目标持有的资产。
配置
pmwallets-copytrade init 会生成带注释的 config.yaml。文件中的 ${NAME} 会替换为环境变量 NAME;如果变量缺失,机器人会在启动时停止。无效值会在启动时被拒绝,绝不会被静默忽略。
为机器人设置 Polymarket 账户(推荐)
请为机器人提供一个独立账户,其中只存放你愿意让它交易的资产。这是我们推荐并记录的设置方式;请按步骤操作:
此设置已通过真实资金测试——使用 MetaMask(或其他浏览器钱包)账户连接 polymarket.com,并通过该钱包自己的私钥签名。通过电子邮件或 Google 创建的账户、较早的 Safe / Proxy 账户以及普通钱包均受代码支持,但我们尚未用它们进行实盘测试。如果可以,请按以下步骤创建新账户,而不要重复使用这些账户。
- 在 MetaMask(或 Rabby)中创建一个新的钱包账户:账户菜单 → 添加账户。该账户只能用于此用途。
- 连接该钱包,在 polymarket.com 上注册(在登录对话框中选择 MetaMask)。2026-05-04 及之后在 polymarket.com 上创建的每个账户都会获得一个存款钱包——即
signatureType: 3。 - 在 polymarket.com 上存入少量资金(存款)。机器人交易时使用的余额,就是 polymarket.com 显示的余额。
- 复制两个值:
funderAddress——polymarket.com 个人资料菜单中的账户钱包地址(不是 MetaMask 地址);privateKey——第 1 步中 MetaMask 账户的密钥(MetaMask → 账户详情 → 显示私钥)。请将其放入环境变量,切勿放入config.yaml。
- 配置
signatureType: 3、privateKey: ${POLY_PRIVATE_KEY}、funderAddress: ${POLY_FUNDER_ADDRESS},然后运行pmwallets-copytrade check。该命令不会下单;它必须显示你的余额以及 账户可以开仓。 - 先以
mode: dry-run运行,直到决策日志看起来正确,然后将模式切换为mode: live,并设置较小的copy.orderSizeUsdc。
使用独立账户的原因:机器人持有的私钥可以转移该账户中的所有资产,而复制交易绝不能触及你原本无意承担风险的资金。私钥不会离开你的机器。
已有账户?确认账户类型(polymarket.signatureType)
第一行适用于通过连接 MetaMask 或其他浏览器钱包注册的账户,已在实盘中测试过。其他行依据 Polymarket 文档编写,但尚未使用此机器人测试:先运行 check,再运行 dry-run,然后将 copy.orderSizeUsdc 设为非常小的值进行实盘测试;如果出现任何问题,请告知 [email protected]。
此类型决定哪个密钥为你的订单签名,以及资金存放在哪个地址 (Polymarket:钱包类型)。它没有默认值——你必须先设置,否则机器人会拒绝交易,因为使用错误的类型签名会导致所有订单被拒绝。
signatureType | 如果你的账户符合以下情况,则属于此类型…… | privateKey | funderAddress |
|---|---|---|---|
| 3 · Deposit Wallet ✅ 已测试 | 于 2026-05-04 当天或之后在 polymarket.com 上通过连接 MetaMask 或其他浏览器钱包创建 | 该浏览器钱包的密钥 | 个人资料菜单中的账户钱包(不是 MetaMask 地址) |
| 3 · Deposit Wallet(未测试) | 于 2026-05-04 当天或之后在 polymarket.com 上通过电子邮件或 Google 创建 | polymarket.com 允许你导出的账户登录钱包密钥 | 个人资料菜单中的账户钱包 |
| 2 · Safe Wallet | 于 2026-05-04 之前通过连接 MetaMask、Rabby 或其他浏览器钱包创建 | 该浏览器钱包的密钥 | 个人资料菜单中的账户钱包(不是 MetaMask 地址) |
| 1 · Proxy Wallet | 于 2026-05-04 之前通过电子邮件或 Google(Magic)创建 | polymarket.com 允许你导出的 Magic 密钥(在设置中查找 Export Private Key) | 个人资料菜单中的账户钱包 |
| 0 · 普通钱包 | 你使用自己的地址进行交易,资金也存放在该地址中,而非通过 polymarket.com 账户交易 | 该地址的密钥 | 相同地址(可省略) |
普通钱包(类型 0)在首次交易前还必须在链上批准 Polymarket 的交易合约——机器人不会代你执行此操作(参见 Polymarket 的 批准示例)。 在 polymarket.com 上创建的账户(类型 1–3)已由 Polymarket 完成设置。
Polymarket V2 市场还需要另外两项批准:上述批准不涵盖 ExchangeV3
(0xe3333700cA9d93003F00f0F71f8515005F6c00Aa)。要买入,pUSD(0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB)必须
对 ExchangeV3 执行 approve;要卖出,PositionManager(0x006F54F7f9A22e0000CC2AB60031000000ae9fEF)必须
执行 setApprovalForAll(ExchangeV3, true)(Polymarket:V2 迁移)。
普通钱包需要自行发送这两项批准(上面的示例尚未包含它们);对于在 polymarket.com 上创建的账户,请接受 polymarket.com 显示的批准提示。check 会在单独一行报告 ExchangeV3 的 pUSD 批准状态。它无法检测 PositionManager 的批准:缺少此项时,V2 市场中的 SELL 会被拒绝并重试。
无论账户类型如何,在设置 mode: live 之前都要运行 pmwallets-copytrade check。如果余额显示为 $0,但 polymarket.com 上显示有资金,则类型或地址有误。Polymarket 还会限制某些地区的交易;如果账户可能只能平仓,check 会报告此情况。
所有选项
| 键 | 默认值 | 作用 |
|---|---|---|
mode | dry-run | dry-run 会记录每项决策,并模拟以订单簿上的最佳价格成交;live 会发送真实订单。 |
pmwallets.apiKey | —(必填) | 你的 PMWallets API 密钥(pmw_…,可从 pmwallets.com/keys 获取)。 |
pmwallets.baseUrl | https://api.pmwallets.com | PMWallets API 端点。 |
pmwallets.takeover | false | 从持有账户成交流的客户端接管该流(该客户端会停止)。默认情况下,如果已有客户端持有该流,则拒绝启动。 |
polymarket.signatureType | — | 账户类型 0–3,见上文。无默认值:mode: live 和 check 必填。 |
polymarket.privateKey | — | 用于签署订单的密钥。实时模式下必填。 |
polymarket.funderAddress | — | 持有资金的地址。实时模式下必填,除非 signatureType 为 0。 |
polymarket.apiKey / apiSecret / apiPassphrase | 派生 | Polymarket CLOB API 凭据;如果未提供,启动时会从 privateKey 派生。 |
polymarket.clobUrl | https://clob.polymarket.com | Polymarket CLOB 端点。 |
targets | [] | 要复制的实体(0x 地址,或在你拥有该地址后使用的看板句柄)。留空 = 账户订阅的所有实体。 |
targets[].orderSizeUsdc | copy.orderSizeUsdc | 每个目标的订单规模。 |
targets[].maxBuysPerOutcome | copy.maxBuysPerOutcome | 每个目标在同一结果上的 BUY 上限。 |
copy.orderSizeUsdc | 10 | 每笔复制的 BUY 使用的 USDC 数量,按最佳卖价换算为份额,并向下取整至 CLOB 接受的规模。 |
copy.roles | [taker, maker] | 复制目标的 taker 成交、maker 成交或两者。跟随 taker 成交更容易。 |
copy.maxBuysPerOutcome | 3 | 最多复制同一结果的 BUY 数量(分批买入),之后只持有。 |
copy.maxOpenPositions | 20 | 所有目标合计同时持有的结果数量(未确认的 BUY 也计入)。 |
copy.maxOpenPositionsPerTarget | 5 | 每个目标同时持有的结果数量。 |
copy.maxFillAgeSec | 60 | 目标的 BUY 到达机器人时若已超过此时长,则不复制(停机后重放时不得买入历史订单)。SELL 永远不会过期。 |
copy.minTargetNotionalUsdc | 25 | 忽略低于此金额的目标 BUY。 |
copy.minPrice / copy.maxPrice | 0.05 / 0.95 | 仅当最佳卖价处于此范围内时才 BUY。 |
copy.maxSlippage | 0.03 | 如果最佳卖价高于目标价格超过此数值,则跳过(0.03 = 3 美分)。 |
copy.minBookDepthUsdc | 50 | 如果我们要成交的一侧持有的 USDC 少于此数值,则跳过。 |
copy.minSecondsToEndDate | 60 | 不要 BUY 结束时间早于此时长的市场。 |
copy.maxSecondsToEndDate | 0 | 不要 BUY 结束时间晚于此时长的市场;0 = 不限。 |
copy.sellMode | all | all:目标卖出时,平仓机器人跟随该目标在该结果中买入的仓位。none:持有至结算。 |
risk.maxDailySpendUsdc | 200 | 每个 UTC 日复制 BUY 的 USDC 总额,包含未确认订单;0 = 不限。 |
dataDir | ./pmw-data | 状态、流游标、锁文件和决策日志的存放位置。 |
命令、环境和文件
pmwallets-copytrade init [file] | 写入示例配置。 |
pmwallets-copytrade run [--config file] [--json] | 启动机器人(--json:每个事件输出一行 JSON 日志)。 |
pmwallets-copytrade check [--config file] | 验证交易设置,不执行交易:密钥、订阅、账户类型、余额、限制。 |
pmwallets-copytrade status [--config file] | 未平仓头寸、今日支出、仍在确认的订单、正在重试的平仓操作。 |
pmwallets-copytrade reconcile [<key> --none | <key> --filled <shares> --usdc <usdc>] | 结算机器人无法自行确认的订单。运行前先停止机器人。 |
pmwallets-copytrade diagnose [--config file] | 生成 pmw-diagnose-<time>.json.gz 供支持人员使用(不含密钥;见上文)。 |
pmwallets-copytrade --version | 打印版本号。 |
HTTPS_PROXY / HTTP_PROXY / NO_PROXY | 适用于 PMWallets API、WebSocket 和 Polymarket CLOB。 |
<dataDir>/state.<mode>.json | 头寸、已判定的成交、正在确认的订单、待处理的平仓操作、今日支出。 |
<dataDir>/stream.<mode>.json | 重启后恢复成交流的位置。 |
<dataDir>/decisions.<mode>.jsonl | 每项决策,包括每次跳过及其原因。达到 20 MB 时轮换,保留 5 个旧文件(.1 … .5)。 |
<dataDir>/bot.<mode>.log | run 输出的所有内容,每个事件占一行 JSON,从版本号开始。达到 10 MB 时轮换,保留 5 个旧文件。 |
<dataDir>/lock.<mode> | 每个数据目录和模式只能运行一个机器人。 |
开发
npm install
npm test
npm run build
Python 版本也使用相同的 config.yaml、状态文件和锁文件。testdata/ 存放两种实现都必须通过的契约测试用例——请确保两个代码库中的内容完全一致。
将 PolymarketGateway 用作库时:buyFok、sellFak 和 tokenBalance 的最后一个参数 v2 是可选的。
true 表示通过 ExchangeV3 交易 Polymarket V2 头寸;省略该参数或设为 false 则使用 CTF 路径,因此在 V2 之前编写的代码仍可照常用于 CTF 代币。若未传入 true 却使用 V2 头寸 ID,或无论参数值为何都使用组合 ID,都会在签名或发送任何内容之前被拒绝(tokenBalance 会抛出异常)。Exchange 接口也带有相同的可选参数。
代币 ID 必须是规范的十进制字符串——不能是十六进制数,不能带符号、空格或前导零:每个网关方法都会在查询或 SDK 获取该值之前拒绝其他格式,机器人也会跳过此类成交(skipped_invalid_token_id)。
资源
- Polymarket 聪明钱排行榜 — 根据 Polygon 链上数据评估盈利能力较强的 Polymarket 交易者,并提供胜率置信区间
- Polymarket 跟单指南 — 哪些钱包值得跟随,以及如何及时获取它们的成交信息
- 如何向 Polymarket 聪明钱学习 — 解读交易者的记录:置信区间、挂单方与吃单方、市场专长
- PMWallets API 文档 — WebSocket 和 webhook 成交推送、成交回放、交易历史导出
- 实测成交推送延迟 — 区块到推送的 p50 / p95 延迟,实时发布
- Polymarket 钱包跟踪方式对比 — 官方排行榜、免费跟踪器、SQL 仪表盘
- 常见问题 · 中文站
指南
- 如何设置 Polymarket 跟单机器人 — 使用专用账户、选择 Polymarket 接受订单的地区,并先进行模拟运行
- Polymarket 跟单风险 — 你的订单提交前价格已变动、与他人争抢同一订单簿、跟随挂单方、手续费、错过平仓时机
- 在投入资金前回测跟单 — 结合交易者的成交历史与你的实际延迟、滑点和手续费
- Polymarket 订单类型:GTC、GTD、FOK 和 FAK — 以及机器人应使用哪种类型
- 如何识别做市商 — 以及为什么不该跟随他们
- 运气还是实力? — 排除表现最好的市场,再重新审视
- Polymarket 胜率 — 为什么没有样本量,100% 毫无意义
- 按类别划分的 Polymarket 排行榜 — 体育、加密货币、政治、电竞等类别,按链上 PnL 排名
- Polymarket 最活跃市场 — 过去 30 天交易量最高的 1,000 个市场,以及这些市场交易者的表现
- 所有指南 · llms.txt
代理
PMWallets API、WebSocket 和 Polymarket CLOB 均支持 HTTPS_PROXY / HTTP_PROXY / NO_PROXY。
免责声明
当 mode: live 时,本软件会使用真实资金下达真实订单。复制的订单并非交易者本人的订单:价格可能已经变动,需支付手续费,且流动性由多方共享。过往结果无法预测未来表现。PMWallets 提供的是交易者过往行为的数据,并非建议。使用风险自负;请参阅 LICENSE(MIT)。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。