第 27 章,共 33 章

简短版本

Polymarket 提供 三个公开 APICLOB(交易)、Gamma(市场发现)和 Data(分析)。官方 Python SDK 是 py-clob-client 0.34.6。认证使用 API key + ECDSA 签名,订单通过 Polygon 代理钱包使用 EIP-712 进行签名。速率限制将你限制在每个 key 约 60 个订单/分钟。新开发者最大的坑是 Gamma 和 CLOB 之间的 condition_id → token_id 映射问题 - 先把这个解决,其他事情就会顺理成章。Polymarket 上每月大约有 4000 万美元/月 的流动性奖励和机器人捕获的价差被赚走,几乎全部由 API 用户获得。

你将学到:这三个 API 如何协同工作,如何安装和配置 py-clob-client,如何使用你的代理钱包进行认证,如何获取市场和订单簿,如何下单和取消订单,如何通过 WebSocket 流式接收实时价格更新,精确的速率限制以及如何优雅地退避,以及一个你可以扩展的生产就绪机器人架构。
前置条件:一个已注资的 Polymarket 账户,且至少完成过一笔手动交易,Python 3.8+(或 Node.js),以及对 HTTP、JSON 和异步代码的基本了解。如果你还没有手动交易过,请先阅读 首次交易,然后再接入机器人。
01
第一章

第1部分: 三个 API

Polymarket 将职责清晰地拆分到三个不同的服务中。针对每项任务使用正确的 API,能让你的机器人保持快速、简单,并且不超出速率限制。

APIBase URL用途是否需要认证
CLOB APIclob.polymarket.com下单、撤单并跟踪订单。读取订单簿。查询仓位。是(交易需要)
Gamma APIgamma-api.polymarket.com浏览市场,获取元数据、图片、结果价格、成交量、到期时间、标签。否(公开)
Data APIdata-api.polymarket.com历史交易、仓位快照、用户分析、排行榜数据。否(公开)

典型的机器人循环会使用 Gamma 来寻找市场,使用 CLOB 来获取订单簿并执行交易,使用 Data 在离线环境中回测策略表现。可以把 Gamma 看作“目录”,把 CLOB 看作“交易所”,把 Data 看作“仓库”。

专业提示: Gamma 和 Data 不需要认证。你现在就可以用 curl 或浏览器来探索它们 - 无需账户。这是在你生成 API 密钥之前进行原型验证的绝佳方式。
02
第二章

第 2 部分:身份验证与代理钱包模型

Polymarket 不会用你的主钱包私钥为交易签名。相反,它使用一个类似 Gnosis Safe 的代理钱包:你的主钱包授权一个代理,代理在 Polygon 上执行所有交易。你的 API 机器人与该代理通信。

你需要什么

  • API key - 在 Polymarket 设置 → 开发者中生成
  • Private key - 你的交易钱包的密钥(不是你的主 MetaMask 助记词)
  • Funder address - 你的代理钱包地址(在 设置 → 钱包 中显示)
  • Chain ID - 137(Polygon 主网)
  • Signature type - 1(POLY_PROXY,面向零售用户的标准类型)
不可妥协的安全要求:绝不要将你的私钥提交到 git。使用环境变量(.env)或密钥管理器。绝不要把密钥粘贴到 Discord、GitHub issues 或 ChatGPT 中。假定任何接触过你剪贴板的密钥都已经被泄露。如果有疑虑,请轮换密钥。
03
第三章

第 3 部分:安装 py-clob-client

官方 Python SDK 是从零到第一笔订单最快的方式。我们将使用 0.34.6 版本,这是截至 2026 年 4 月的当前版本。

# 先创建虚拟环境
python3 -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows

# 安装 SDK
pip install py-clob-client==0.34.6 requests websocket-client python-dotenv

基础客户端配置

import os
from dotenv import load_dotenv
from py_clob_client.client import ClobClient
from py_clob_client.constants import POLYGON

load_dotenv()

client = ClobClient(
 host="https://clob.polymarket.com",
 key=os.environ["POLY_PRIVATE_KEY"],
 chain_id=POLYGON, # 137
 signature_type=1, # POLY_PROXY
 funder=os.environ["POLY_FUNDER"],
)

# 仅需一次:派生并缓存 API 凭证
client.set_api_creds(client.create_or_derive_api_creds())

create_or_derive_api_creds() 调用会使用你的私钥对消息签名,并将其换取 API 密钥、密钥和密码短语。首次运行后,请将这些信息缓存到你的 .env 中,这样每次启动时就不必都去调用派生端点。

示例 - 最小化 .env:
POLY_PRIVATE_KEY=0xabc...
POLY_FUNDER=0xdef...
POLY_API_KEY=...
POLY_SECRET=...
POLY_PASSPHRASE=...
04
第四章

第 4 部分:通过 Gamma 发现市场

在你开始交易之前,需要先找到值得交易的市场。Gamma 会返回包含 Polymarket UI 展示的一切内容的 JSON:问题、结果、价格、24 小时成交量、到期时间、标签和图片。

import requests

resp = requests.get(
 "https://gamma-api.polymarket.com/markets",
 params={
 "active": "true",
 "closed": "false",
 "tag_slug": "politics",
 "limit": 20,
 "order": "volume24hr",
 "ascending": "false",
 },
 timeout=10,
)
resp.raise_for_status()
markets = resp.json()

for m in markets:
 print(f"{m['slug']:50} Yes ${float(m['outcomePrices'][0]):.3f} Vol24h ${m.get('volume24hr', 0):,.0f}")

有用的 Gamma 查询参数

参数作用
tag_slug按类别筛选(政治、体育、加密货币、文化等)
active=true仅显示当前接受交易的市场
closed=false隐藏已结算市场
order=volume24hr按近期成交量排序(流动性信号)
end_date_minISO 日期 - 跳过过快结算的市场
limit每页最多 500 条(分页时使用 offset
05
第五章

第 5 部分:condition_id → token_id 映射

这是 Polymarket 机器人开发中的头号痛点。Gamma 会返回一个 condition_id(每个市场一个)。CLOB 交易使用 token_id(每个结果一个)。你总是需要两者。

错误做法:condition_id 传给需要 token_id 的 CLOB 端点。你会收到一个晦涩的 "invalid token" 错误。一定要先映射,再交易。
# Each Gamma market object contains 'clobTokenIds' - a JSON string array
import json

market = markets[0]
token_ids = json.loads(market['clobTokenIds']) # ['7410...', '1120...']
yes_token = token_ids[0] # First outcome
no_token = token_ids[1] # Second outcome

# Alternative: ask CLOB directly using condition_id
info = client.get_market(condition_id=market['conditionId'])
yes_token = info['tokens'][0]['token_id']

结果顺序陷阱

Gamma 的 outcomes 数组和 clobTokenIds 数组在索引上是一一对应的。务必先读取结果标签,而不要假设索引 0 就是 "Yes." 在多结果市场(NegRisk、奥斯卡、选举)中,索引 0 可能是 "Kamala Harris" 或 "Taylor Swift" - 顺序是确定的,但取决于具体市场。

06
第六章

第 6 部分: 读取订单簿

book = client.get_order_book(token_id=yes_token)

best_bid = float(book.bids[0].price) if book.bids else None
best_ask = float(book.asks[0].price) if book.asks else None
mid = (best_bid + best_ask) / 2 if best_bid and best_ask else None
spread = best_ask - best_bid if best_bid and best_ask else None

print(f"Bid {best_bid} Ask {best_ask} Mid {mid:.4f} Spread {spread:.4f}")

订单簿以排序后的数组返回(bids 递减,asks 递增)。每一档都有 pricesize。要估算更大订单的滑点,沿着订单簿逐档遍历并累加名义金额,直到消耗完你的目标数量。

07
第七章

第 7 部分: 下单

限价单 (GTC - 默认)

from py_clob_client.clob_types import OrderArgs, OrderType

args = OrderArgs(
 token_id=yes_token,
 price=0.45,
 size=100, # 股数,不是美元。100 股 @ $0.45 = 最高成本 $45。
 side="BUY",
)
signed_order = client.create_order(args)
response = client.post_order(signed_order, OrderType.GTC)
print(response)

create_order 调用会用你的私钥签署一条 EIP-712 结构化消息。post_order 会将其提交到 CLOB。你永远不会在网络中传输原始私钥 - 只会传输已签名的订单。

订单类型

类型代码行为何时使用
Good Till CancelledGTC挂在订单簿上,直到成交或你取消默认。大多数做市和限价策略。
Good Till DateGTD在指定时间戳自动取消事件驱动: "在美联储发布前 5 分钟取消"
Fill or KillFOK必须立即全部成交,否则完全取消套利腿部分成交会破坏交易时使用
Fill and KillFAK按限价能成交多少就成交多少,其余取消激进吃单 - 行为类似带价格上限的市价单

取消

# 单个订单
client.cancel(order_id="0xabc...")

# 取消特定市场上的所有订单
client.cancel_market_orders(market=market['conditionId'])

# 终极选项: 取消全部
client.cancel_all()
08
第八章

第 8 部分:WebSocket 流式传输

每秒轮询 Gamma 是一种浪费,而且你很快就会碰到速率限制。WebSocket 数据流会以亚秒级延迟实时推送订单簿和交易更新。

import json, websocket

WS_URL = "wss://ws-subscriptions-clob.polymarket.com/ws/market"

def on_open(ws):
 ws.send(json.dumps({
 "type": "market",
 "assets_ids": [yes_token, no_token],
 }))

def on_message(ws, message):
 event = json.loads(message)
 if event.get("event_type") == "price_change":
 print(f"{event['market']} {event['side']} {event['price']} size={event['size']}")

ws = websocket.WebSocketApp(
 WS_URL,
 on_open=on_open,
 on_message=on_message,
)
ws.run_forever(ping_interval=20)

共有两个数据流:/market 数据流(公开订单簿 + 交易)和 /user 数据流(你自己的订单和成交事件,需认证)。生产环境中的机器人通常会同时连接这两个数据流,在断开连接时自动重连,并将 WebSocket 视为当前簿状态的事实来源。

心跳和重连:每 20 秒发送一次 ping。如果你漏掉了两个 pong,就重连。重连时,务必先通过 REST 重新获取订单簿,然后再重新订阅 - 否则你的本地订单簿会偏离现实。
09
第九章

第9部分:速率限制与退避

端点类别限制突发
下单(CLOB)每个 API key 约 60 次/分钟约 10 次/秒
撤单约 120 次/分钟约 20 次/秒
市场数据读取(CLOB 订单簿)约 300 次/分钟更高,视情况而定
Gamma API较宽松;注意 429-
WebSocket 消息入站实际上没有限制-

当你遇到 HTTP 429 时,服务器会返回一个 Retry-After 标头。请实现带抖动的指数退避

import random, time

def post_with_backoff(fn, *args, max_retries=6):
 for attempt in range(max_retries):
 try:
 return fn(*args)
 except Exception as e:
 if "429" in str(e):
 sleep = (2 ** attempt) + random.random()
 time.sleep(min(sleep, 30))
 continue
 raise
 raise RuntimeError("Too many retries")
10
第十章

第 10 部分:参考机器人架构

每个稳健的 Polymarket 机器人都具有相同的六个组件。将每个组件作为独立模块构建;保持它们松耦合。

组件职责使用的 API
扫描器定时任务:抓取符合你条件的市场(标签、交易量、距到期天数)Gamma
价格引擎通过 WebSocket 维护实时本地订单簿CLOB WS
信号生成器纯函数:订单簿状态 + 元数据 -> 目标持仓- (内存中)
订单管理器对比当前订单与目标,最小化地提交/取消CLOB REST
风险管理器执行单市场上限、每日亏损限额、熔断器- (内存中 + 数据库)
日志与账本持久化每个决策、成交、取消。用于税务报表和调试。SQLite / Postgres
可靠性优先:在优化 P&L 盈亏 之前,先确保你的机器人能在周日凌晨 3 点无人值守地干净重启。这意味着幂等的下单流程(使用客户端订单 ID)、持久化状态,以及针对任何未处理异常的自动告警(Telegram、Discord、PagerDuty)。

第 11 部分:常见故障模式

  • 过时的 WebSocket 数据 - 跟踪每个资产的最后一条消息时间;如果某个活跃市场超过 30 秒没有更新,则强制进行 REST 刷新。
  • Nonce 冲突 - py-clob-client 会替你处理订单 nonce,但如果你自己实现签名器,就要在每笔订单上递增 nonce。
  • 余额不足 - 下单前始终检查 pUSD 余额;订单簿可能显示你的订单,但撮合会拒绝它。
  • 市场暂停或进入结算 - 交易前检查 market.active && !market.closed。Gamma 在结算附近的更新会比 CLOB 慢几秒。
  • NegRisk 适配器不匹配 - 多结果市场通过单独的 NegRisk 适配器路由。SDK 会处理它,但要确认你的订单去了正确的场所。
测试网限制:Polymarket 在 2026 年不运营公开测试网。"纸面交易" 指的是在低流动性市场上放置很小的真实订单(1 美元到 5 美元)。为你调试的第一周预留几美元预算 - 这会在以后为你省下数百美元。

第 12 部分:通过 API 获取流动性奖励

Polymarket 每月发放约 500 万美元的一般流动性奖励,以及每月 500 万美元以上的体育专项奖励(见 流动性奖励)。绝大部分奖励流向 API 驱动的做市商,他们能够在成千上万的市场中维持紧密的双边报价。

奖励公式会奖励接近中间价的订单、订单规模以及挂单时长。一个最小化的做市循环:

  1. 读取目标市场的订单簿
  2. 计算公平的中间价(例如,买卖双方前 3 档的 VWAP)
  3. mid - spread_target/2 挂出买单,在 mid + spread_target/2 挂出卖单
  4. 每次 WebSocket 更新时,如果你的报价偏离目标超过一个 tick,就重新定价
  5. 如果订单簿变薄或有新闻突发,就取消并退出

第 13 部分:投入生产

  • 托管:欧洲或美国东部一台每月 6 美元的 VPS(Hetzner、DigitalOcean)对大多数机器人都足够。如果你需要低于 10 毫秒的延迟,就与 Polygon RPC 共置。
  • RPC:使用 Alchemy、Infura 或 QuickNode 获取可靠的 Polygon RPC。免费套餐在你每分钟下单数百笔之前都够用。
  • 监控:使用 Prometheus + Grafana 做指标监控;用 Telegram 机器人做告警。记录你发送的每个订单 ID 和收到的每次成交。
  • 备份:每分钟持久化状态。如果 VPS 在成交中途宕机,你希望能在几秒内恢复,而不是手工对账。
  • 税务:你的日志器也是你的审计轨迹 - 见 税务指南

第 14 部分 - Polymarket API 已验证的专业建议

来自实盘机器人运营者的十二条生产习惯。
  1. 在第一次 derive 调用后缓存 API 凭证 - create_or_derive_api_creds() 有速率限制而且很慢。将 apiKey/secret/passphrase 存入 .env 并在启动时加载。
  2. 如果你先连接了浏览器钱包,就使用 signature_type=2 (GNOSIS_SAFE),signature_type=1 (POLY_PROXY) 只用于 Magic-link 邮箱账户。不匹配的类型会返回 401 "invalid api key."
  3. funder 设置为你的 Polymarket 代理钱包地址,而不是你的 EOA。签名密钥在 EOA 中;资金在代理钱包中。把它们混淆是第一大认证 bug。
  4. 按标签而不是按位置索引结果 - 使用 clobTokenIds[outcomes.index("Yes")],不要用 clobTokenIds[0]。NegRisk 和 Oscar 市场的顺序是任意的。
  5. 在签名前同步你的时钟 - POLY_TIMESTAMP 必须处于很窄的时间窗口内。廉价 VPS 上的 NTP 漂移会悄无声息地破坏认证。运行 chrony 或 systemd-timesyncd。
  6. 在每次 WebSocket 重连后重新获取 REST 订单簿,然后再重新订阅。WebSocket 只提供增量;如果你在重连期间漏掉一个增量,你的本地订单簿就会与现实偏离,并且会报出亏损报价。
  7. 每秒绝不要突发超过 10 笔订单 - /order 端点的限流为 500/10s 突发和 3,000/10min 持续。客户端添加令牌桶限流器;Cloudflare 会排队而不是丢弃,所以盲目重试会放大积压。
  8. 在关闭时使用 cancel_market_orders(market=conditionId),不要用 cancel_all()。按市场范围取消是幂等的,如果机器人只在某个市场的循环中途崩溃,会更安全。
  9. 按资产跟踪 heartbeatMs - 添加一个 watchdog,对任何在活跃市场上 30 秒没有更新的市场强制刷新。过时的 WS 数据流是虚假优势最常见的来源。
  10. 在发送之前记录订单 ID,而不是之后。幂等性要求客户端拥有该 ID,这样崩溃恢复时可以重新发送而不会重复成交。
  11. 使用 HeartBeats API(2026 年 1 月及以后) 实现断线自动取消。将 heartbeat 间隔设置为 5 秒;如果服务器漏掉两次 heartbeat,它会取消你所有挂单中的订单。
  12. 在薄市场上用 1 美元订单进行纸面交易 持续 48 小时后再扩量。Polymarket 没有测试网;小额真实订单是验证认证、签名、成交处理和取消流程的唯一可靠方式。

情境 -> 操作速查表

情境操作原因
首次调用时返回 401 "invalid api key"检查 signature_type 是否与钱包来源匹配,以及 funder 是否为代理地址类型 1 与 2 不匹配占 401 错误的 80%;其余是把 EOA 当作 funder
订单因 "insufficient balance" 被拒绝每次下单前查询 /balance-allowance 并在本地预留CLOB 在你提交的瞬间就会锁定抵押品;两个并发订单可能会重复预留
/order 端点出现 429 限流使用抖动退避:2^attempt + random(),上限 30 秒Cloudflare 会限流而不是直接拒绝;天真重试会放大积压
WebSocket 在交易中途断开通过 REST 快照订单簿,协调本地状态,然后重新订阅间隙中的增量会丢失;快照会重新同步价格层级
订单已提交但没有成交确认在 5 秒内查询 /data/order/{id};如果仍在等待,就继续等;如果未找到,就替换罕见但可恢复;默认策略是“先检查状态,再行动”
市场在你活跃报价期间结算在结算事件触发时取消该 conditionId 下所有未成交订单结算后的订单可能因适配器怪异行为而作为僵尸成交残留
运行做市机器人以中间价 2 美分以内的距离报价,且每边规模 100+ 股奖励公式权重是紧度 + 规模 + 挂单时长;紧 + 大 + 持续获胜
在多结果市场上运行套利机器人每条腿使用 FOK,不要用 GTCA 腿部分成交而 B 腿全量成交 = 未对冲敞口和即时亏损
第一次构建机器人先做扫描器,再做价格引擎,然后做信号 - 绝不要先做信号没有干净订单簿状态的信号只是相关性陷阱;先把管道跑通
生产机器人在凌晨 3 点崩溃配好 systemd 自动重启 + Telegram 告警 + 持久化状态任何无人值守的机器人都会崩溃;唯一的问题是它能否干净重启
实操示例:用于流动性奖励的最小做市循环。

目标。 在一个中等交易量的政治市场上赚取流动性奖励,该市场价格大约为 Yes 0.48 / No 0.52,价差为 2 美分。该市场的每日奖励池约为 40 美元。

设置。 WebSocket 订阅两个 token_id。缓存上一次看到的中间价。定义 spread_target = 0.02,每边 size = 200 股,reprice_threshold = 0.005(5 个 tick)。

循环。 每次 WS 订单簿更新时:计算新的中间价 = 买卖双方前 3 档的 VWAP。如果 |当前报价 - 目标中间价| > reprice_threshold,则取消现有两笔订单,在 mid-0.01 挂买单并在 mid+0.01 挂卖单。将重新定价频率限制为每边每 2 秒一次。

风险。 每边最大库存 = 1,000 股。如果库存 > 500,则该边价差每 100 股扩大 0.005。熔断器:如果中间价在 60 秒内移动超过 0.05,则取消所有订单并暂停 5 分钟。

结果(真实 7 天运行)。 总计成交约 14,000 股,覆盖 680 笔订单,支付了 0 美元吃单费(挂单侧),获得 31.40 美元流动性返利,净方向性 P&L 盈亏 为 -4.10 美元(少量库存损失)。7 天净收益 +27.30 美元,基于 500 美元营运资本约为每月 8%。在单台 VPS 上可同时扩展到 30-50 个市场。

关键要点

那些在 Polymarket 上持续盈利的交易者把 polymarket api guide 当作一个系统,而不是凭感觉行事。记住上面的数字 - 它们决定了 7.6% 的盈利钱包与其他钱包之间的差别。

接下来是什么?

  • 工具与资源 - 补充 API 的第三方仪表板、分析工具和数据馈送
  • 高级策略 - 适合机器人使用的多腿套利和类期权结构
  • 流动性奖励 - 赚取做市返利的精确公式
  • 订单簿指南 - 在你开始编写对接代码之前,更深入地理解如何阅读订单簿
  • 术语表 - 本指南中每个术语的通俗定义