Polymarket 交易 - 完整 API 参考
通过官方 py_clob_client 库访问 Polymarket 的 CLOB(中央限价订单簿)的完整权限。
60+ 方法文档化。这是完整的参考。
必需的环境变量
PRIVATE_KEY=0x... # 用于签名的以太坊私钥
POLY_FUNDER_ADDRESS=0x... # 你在 Polygon 上的钱包地址
POLY_API_KEY=... # 来自 Polymarket API
POLY_API_SECRET=... # Base64 编码的秘密
POLY_API_PASSPHRASE=... # API 密码
安装
pip install py-clob-client requests
认证级别
| 级别 | 要求 | 能力 |
|---|---|---|
| L0 | 无 | 只读:订单簿、价格、市场 |
| L1 | 私钥 | 创建并签名订单(不发布) |
| L2 | 私钥 + API 凭证 | 全面交易:发布订单、取消、查询 |
签名类型
| 类型 | 使用案例 |
|---|---|
0 |
标准 EOA(MetaMask、硬件钱包) |
1 |
Magic/email 钱包(委托签名) |
2 |
代理钱包(Gnosis Safe、浏览器代理) |
ClobClient - 完整 API(60+ 方法)
初始化
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import (
OrderArgs, MarketOrderArgs, ApiCreds, OrderType,
BookParams, TradeParams, OpenOrderParams, BalanceAllowanceParams,
AssetType, OrderScoringParams, OrdersScoringParams, DropNotificationParams
)
from py_clob_client.order_builder.constants import BUY, SELL
from py_clob_client.constants import POLYGON # 137
# 2级认证(全面交易权限)
client = ClobClient(
host="https://clob.polymarket.com",
key=os.getenv("PRIVATE_KEY"), # 用于签名的私钥
chain_id=POLYGON, # 137 为主网,80002 为 Amoy 测试网
funder=os.getenv("POLY_FUNDER_ADDRESS"), # 钱包地址(代理钱包)
signature_type=2 # 0=EOA, 1=MagicLink, 2=Proxy
)
# 设置认证端点的 API 凭证
client.set_api_creds(ApiCreds(
api_key=os.getenv("POLY_API_KEY"),
api_secret=os.getenv("POLY_API_SECRET"),
api_passphrase=os.getenv("POLY_API_PASSPHRASE")
))
健康与配置
client.get_ok() # 检查服务器是否在线
client.get_server_time() # 获取服务器时间戳
client.get_address() # 你的签名者的公共地址
client.get_collateral_address() # USDC 合约地址
client.get_conditional_address() # CTF 合约地址
client.get_exchange_address() # 交易所合约(默认 neg_risk=False)
市场数据 - 单一代币
# 获取价格和价差
client.get_midpoint(token_id) # 中间市场价格
client.get_price(token_id, side="BUY") # 最佳价格
client.get_spread(token_id) # 当前价差
client.get_last_trade_price(token_id) # 最后一笔交易价格
# 获取完整订单簿
orderbook = client.get_order_book(token_id)
# 返回:OrderBookSummary 包含出价、要价、最小价格变动、负风险、时间戳、哈希
市场数据 - 批量(多个代币)
params = [
BookParams(token_id="TOKEN1", side="BUY"),
BookParams(token_id="TOKEN2", side="SELL")
]
client.get_midpoints(params) # 多个中间点
client.get_prices(params) # 多个价格
client.get_spreads(params) # 多个价差
client.get_order_books(params) # 多个订单簿
client.get_last_trades_prices(params) # 多个最后价格
市场元数据
client.get_tick_size(token_id) # 返回:"0.1", "0.01", "0.001", 或 "0.0001"
client.get_neg_risk(token_id) # 返回:True/False(负风险市场)
client.get_fee_rate_bps(token_id) # 返回:费率以基点为单位(0 或 1000)
订单类型
from py_clob_client.clob_types import OrderType
OrderType.GTC # 直至取消 - 直到被填满/取消前一直开放
OrderType.FOK # 立即全部成交或取消 - 立即完全成交或取消
OrderType.GTD # 直至日期 - 在时间戳前有效(最少 60 秒)
OrderType.FAK # 部分成交后取消 - 尽可能成交,取消剩余部分
何时使用每种订单类型
| 类型 | 使用案例 | 示例 |
|---|---|---|
| GTC | 进入 - 等待成交 | 在 0.45 处购买,等待下跌 |
| FOK | 退出 - 需要立即成交 | 立即卖出整个位置 |
| GTD | 限时订单 | 报价在 5 分钟后过期 |
| FAK | 部分成交 OK | 现在尽可能多地成交 |
OrderArgs - 限价订单
OrderArgs(
token_id: str, # 代币 ID(结果交易)
price: float, # 价格 0.01-0.99
size: float, # 股份数量
side: str, # "BUY" 或 "SELL"(或使用 BUY/SELL 常量)
fee_rate_bps: int = 0, # 可选:费率以基点为单位(0 或检查市场)
nonce: int = 0, # 可选:用于取消的唯一随机数
expiration: int = 0, # 可选:到期时间戳(0 = GTC,使用时间戳为 GTD)
taker: str = ZERO_ADDRESS # 可选:特定接受者(ZERO_ADDRESS = 任何人)
)
MarketOrderArgs - 市价订单
MarketOrderArgs(
token_id: str, # 代币 ID
amount: float, # 总 USDC 金额花费(购买)或股份(销售)
side: str, # "BUY" 或 "SELL"
price: float = 0, # 可选:最差可接受价格(滑点保护)
fee_rate_bps: int = 0, # 可选:费率
nonce: int = 0, # 可选:随机数
taker: str = ZERO_ADDRESS, # 可选:接受者地址
order_type: OrderType = FOK # 可选:FOK(默认)或 FAK
)
完整订单示例
from py_clob_client.order_builder.constants import BUY, SELL
# 1. 限价买入(GTC) - 直到被填满
order = client.create_and_post_order(
OrderArgs(token_id=TOKEN_ID, price=0.45, size=100.0, side=BUY)
)
# 2. 限价卖出(GTC)
order = client.create_and_post_order(
OrderArgs(token_id=TOKEN_ID, price=0.55, size=50.0, side=SELL)
)
# 3. 市价买入 - 以当前价格花费 100 美元 USDC(FOK)
signed = client.create_market_order(
MarketOrderArgs(token_id=TOKEN_ID, amount=100.0, side=BUY)
)
result = client.post_order(signed, orderType=OrderType.FOK)
# 4. 市价卖出 - 立即卖出所有股份(FOK)
signed = client.create_market_order(
MarketOrderArgs(token_id=TOKEN_ID, amount=my_shares, side=SELL)
)
result = client.post_order(signed, orderType=OrderType.FOK)
# 5. POST-ONLY 制造者订单(避免接受者费用,赚取回扣)
signed = client.create_order(
OrderArgs(token_id=TOKEN_ID, price=0.44, size=100.0, side=BUY)
)
result = client.post_order(signed, orderType=OrderType.GTC, post_only=True)
# 如果订单会跨越价差,它会被 REJECTED 而不是接受
# 6. 直至日期(GTD) - 在时间戳后过期
import time
expiry = int(time.time()) + 300 # 5 分钟后
signed = client.create_order(
OrderArgs(token_id=TOKEN_ID, price=0.50, size=100.0, side=BUY, expiration=expiry)
)
result = client.post_order(signed, orderType=OrderType.GTD)
# 7. 部分成交后取消(FAK) - 尽可能成交,取消剩余部分
signed = client.create_market_order(
MarketOrderArgs(token_id=TOKEN_ID, amount=1000.0, side=BUY)
)
result = client.post_order(signed, orderType=OrderType.FAK)
订单操作
创建和发布订单
# 简单:创建和发布在一个调用中(推荐)
result = client.create_and_post_order(
OrderArgs(
token_id="123456789012345678901234567890",
price=0.45,
size=10.0,
side="BUY"
)
)
# 返回:{"orderID": "...", "status": "...", ...}
# 高级:分别创建和发布
order = client.create_order(OrderArgs(...)) # 返回 SignedOrder
result = client.post_order(order, orderType=OrderType.GTC, post_only=False)
# 市价订单(自动计算价格)
result = client.create_market_order(
MarketOrderArgs(
token_id="...",
amount=100.0, # 花费 100 美元 USDC
side="BUY"
)
)
# 市价订单前计算预期成交价格
price = client.calculate_market_price(
token_id="...",
side="BUY",
amount=100.0,
order_type=OrderType.FOK
)
取消订单
client.cancel(order_id="ORDER_ID") # 取消特定订单
client.cancel_orders(["ID1", "ID2", "ID3"]) # 取消多个
client.cancel_all() # 取消全部开放订单
client.cancel_market_orders( # 按市场/资产取消
market="CONDITION_ID",
asset_id="TOKEN_ID"
)
查询订单
# 获取所有开放订单
orders = client.get_orders(
params=OpenOrderParams(
id="ORDER_ID", # 可选:特定订单
market="COND_ID", # 可选:按市场过滤
asset_id="TOKEN" # 可选:按代币过滤
),
next_cursor="MA==" # 用于分页
)
# 获取特定订单
order = client.get_order(order_id="ORDER_ID")
交易历史
trades = client.get_trades(
params=TradeParams(
id="TRADE_ID", # 可选:特定交易
maker_address="0x...", # 可选:按制造商过滤
market="CONDITION_ID", # 可选:按市场过滤
asset_id="TOKEN_ID", # 可选:按代币过滤
before="2024-01-01", # 可选:日期之前
after="2023-01-01" # 可选:日期之后
),
next_cursor="MA=="
)
余额与授权
# 检查余额和授权
balance = client.get_balance_allowance(
params=BalanceAllowanceParams(
asset_type=AssetType.COLLATERAL, # USDC 余额
# 或 AssetType.CONDITIONAL # 代币余额
token_id="TOKEN_ID" # 对于条件性代币
)
)
# 更新/刷新授权缓存
client.update_balance_allowance(params=...)
市场发现
从 CLOB 获取市场
# 所有活跃市场
markets = client.get_markets(next_cursor="MA==")
simplified = client.get_simplified_markets()
# 特定市场
market = client.get_market(condition_id="CONDITION_ID")
# 市场交易事件
events = client.get_market_trades_events(condition_id="CONDITION_ID")
# 抽样/特色市场
client.get_sampling_markets()
client.get_sampling_simplified_markets()
从 Gamma API 获取市场(更多细节)
import requests
def search_markets(query: str, limit: int = 10):
"""按关键词搜索 Polymarket 市场"""
url = "https://gamma-api.polymarket.com/markets"
params = {
"_q": query,
"active": "true",
"closed": "false",
"_limit": limit
}
r = requests.get(url, params=params)
return r.json()
# 获取市场详情
markets = search_markets("bitcoin")
for m in markets:
print(f"问题:{m['question']}")
print(f"条件 ID:{m['condition_id']}")
print(f"成交量:${m.get('volume', 0):,.2f}")
for token in m.get('tokens', []):
print(f" {token['outcome']}:{token['token_id']}")
print(f" 价格:{float(token['price']):.2f}")
链上操作
检查代币余额(头寸大小)
import requests
CTF_CONTRACT = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"
RPC_URL = "https://polygon-rpc.com/"
def get_token_balance(wallet: str, token_id: str) -> float:
"""获取特定结果代币的余额(股份)"""
token_int = int(token_id)
# ERC-1155 balanceOf(address,uint256)
data = f"0x00fdd58e000000000000000000000000{wallet[2:].lower()}{token_int:064x}"
r = requests.post(RPC_URL, json={
"jsonrpc": "2.0",
"method": "eth_call",
"params": [{"to": CTF_CONTRACT, "data": data}, "latest"],
"id": 1
})
result = r.json().get("result", "0x0")
balance = int(result, 16) / 1e6 # 从原始转换为股份
return balance
# 使用方法
balance = get_token_balance(
wallet="0x7c2211103e7Fbb257Ac6fa59f972cfd8bc9D4795",
token_id="12345678901234567890"
)
print(f"头寸:{balance} 股份")
检查 USDC 余额
USDC_CONTRACT = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
def get_usdc_balance(wallet: str) -> float:
"""在 Polygon 上获取 USDC 余额"""
# ERC-20 balanceOf(address)
data = f"0x70a08231000000000000000000000000{wallet[2:].lower()}"
r = requests.post(RPC_URL, json={
"jsonrpc": "2.0",
"method": "eth_call",
"params": [{"to": USDC_CONTRACT, "data": data}, "latest"],
"id": 1
})
result = r.json().get("result", "0x0")
return int(result, 16) / 1e6 # USDC 有 6 位小数
API 密钥管理
# 创建新的 API 密钥
creds = client.create_api_key(nonce=0)
# 导出现有的 API 密钥(如果你丢失了凭证但有私钥)
creds = client.derive_api_key(nonce=0)
# 创建或导出(尝试两者)
creds = client.create_or_derive_api_creds(nonce=0)
# 获取你所有的 API 密钥
keys = client.get_api_keys()
# 删除当前 API 密钥
client.delete_api_key()
# 只读 API 密钥(仅用于监控)
readonly = client.create_readonly_api_key()
client.get_readonly_api_keys()
client.delete_readonly_api_key(key="...")
client.validate_readonly_api_key(address="0x...", key="...")
高级功能
订单心跳(保持订单活跃)
# 开始心跳 - 如果在 10 秒内未发送,所有订单将被取消
heartbeat_id = client.post_heartbeat(heartbeat_id=None)
# 继续发送心跳
while trading:
client.post_heartbeat(heartbeat_id=heartbeat_id)
time.sleep(5)
订单评分
# 检查订单是否评分(赚取奖励)
is_scoring = client.is_order_scoring(
params=OrderScoringParams(order_id="...")
)
# 检查多个订单
scores = client.are_orders_scoring(
params=OrdersScoringParams(order_ids=["ID1", "ID2"])
)
通知
notifications = client.get_notifications()
client.drop_notifications(params=DropNotificationParams(...))
费用结构
重要:大多数 Polymarket 市场的费用为零(0% 制造商,0% 接受者)。
15 分钟加密货币市场(例外)
只有 15 分钟 BTC/ETH/SOL/XRP 价格预测市场有费用:
fee = shares × 0.25 × (price × (1 - price))²
| 进入价格 | 费用 %(每边) |
|---|---|
| 0.50 | ~1.56% |
| 0.60 或 0.40 | ~1.44% |
| 0.70 或 0.30 | ~1.10% |
| 0.80 或 0.20 | ~0.64% |
| 0.90 或 0.10 | ~0.20% |
接受者 = 跨越价差 = 支付费用 制造商 = 提供流动性 = 无费用 + 赚取回扣
要成为制造商:发布不会立即成交的订单(在价差内)。
小数精度规则
| 订单方 | 价格小数 | 大小小数 |
|---|---|---|
| 购买 | 2 | 4 |
| 销售 | 2 | 2 |
最小订单大小: 每边 1 美元
完整交易示例
#!/usr/bin/env python3
"""
生产就绪的 Polymarket 交易脚本
"""
import os
import time
import requests
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, ApiCreds, OrderType
# 初始化
client = ClobClient(
"https://clob.polymarket.com",
key=os.getenv("PRIVATE_KEY"),
chain_id=137,
funder=os.getenv("POLY_FUNDER_ADDRESS"),
signature_type=2
)
client.set_api_creds(ApiCreds(
api_key=os.getenv("POLY_API_KEY"),
api_secret=os.getenv("POLY_API_SECRET"),
api_passphrase=os.getenv("POLY_API_PASSPHRASE")
))
TOKEN_ID = "YOUR_TOKEN_ID"
WALLET = os.getenv("POLY_FUNDER_ADDRESS")
CTF = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045"
def get_balance(token_id):
"""获取头寸大小"""
token_int = int(token_id)
data = f"0x00fdd58e000000000000000000000000{WALLET[2:].lower()}{token_int:064x}"
r = requests.post("https://polygon-rpc.com/", json={
"jsonrpc": "2.0", "method": "eth_call",
"params": [{"to": CTF, "data": data}, "latest"], "id": 1
})
return int(r.json().get("result", "0x0"), 16) / 1e6
def get_orderbook(token_id):
"""获取当前买价/卖价"""
book = client.get_order_book(token_id)
return {
"best_bid": float(book.bids[0].price) if book.bids else 0,
"best_ask": float(book.asks[0].price) if book.asks else 1
}
# 检查头寸
position = get_balance(TOKEN_ID)
print(f"当前头寸:{position} 股份")
# 获取市场
book = get_orderbook(TOKEN_ID)
print(f"买价:{book['best_bid']:.2f}, 卖价:{book['best_ask']:.2f}")
# 下买单(制造商 - 在价差内)
buy_price = book['best_bid'] + 0.01 # 比买价高 1 分
if buy_price < book['best_ask']: # 确保我们是制造商
result = client.create_and_post_order(OrderArgs(
token_id=TOKEN_ID,
price=buy_price,
size=10.0,
side="BUY"
))
print(f"买单已下:{result}")
# 卖出所有头寸
if position > 0:
result = client.create_and_post_order(OrderArgs(
token_id=TOKEN_ID,
price=0.01, # 最低价格 = 立即成交
size=position,
side="SELL"
))
print(f"已卖出头寸:{result}")
错误处理
from py_clob_client.exceptions import PolyApiException
try:
result = client.create_and_post_order(OrderArgs(...))
except PolyApiException as e:
print(f"API 错误:{e}")
except Exception as e:
print(f"错误:{e}")
常见错误:
- “insufficient balance” - USDC/代币不足
- “invalid price” - 价格超出 0.01-0.99 或错误的小数位
- “order too small” - 低于最小订单大小
- “market closed” - 市场不接受订单
CLI 命令(/poly)
直接从 Claude Code 访问 Polymarket 交易:
市场数据
/poly search <query> # 搜索市场
/poly market <condition-id> # 市场详情
/poly book <token-id> # 查看订单簿
交易
/poly buy <token-id> <size> <price> # 购买股份(限价)
/poly sell <token-id> <size> <price> # 出售股份(限价)
/poly orders # 开放订单
/poly cancel <order-id> # 取消订单
/poly cancel all # 取消所有订单
/poly trades [limit] # 最近交易历史
/poly balance # USDC + 头寸
高级订单
/poly twap <buy|sell> <token> <total> <price> [slices] [interval-sec]
/poly bracket <token> <size> <tp> <sl> # TP + SL 括号
/poly trigger buy <token> <size> <price> # 价格下跌时购买
注意: TWAP 和括号订单会保存在数据库中,并且在重启后会自动恢复。
自动兑换(已解决的头寸)
/poly redeem # 一次性兑换所有已解决的头寸
/poly redeem start # 开始自动轮询(默认:每 60 秒)
/poly redeem stop # 停止自动轮询
/poly redeem status # 检查自动兑换者状态
/poly redeem pending # 列出待兑换的头寸
/poly redeem <conditionId> <tokenId> # 兑换特定头寸
环境变量:
POLY_REDEEM_INTERVAL_MS- 轮询间隔以毫秒为单位(默认:60000 = 1 分钟)
实时成交(WebSocket)
/poly fills # 连接成交 WebSocket
/poly fills status # 显示连接 + 最近成交
/poly fills stop # 断开成交 WebSocket 连接
/poly fills clear # 清除跟踪的成交
订单心跳
/poly heartbeat # 开始心跳(保持订单活跃)
/poly heartbeat status # 检查心跳状态
/poly heartbeat stop # 停止心跳(订单将在 10 秒内被取消)
账户与结算
/poly settlements # 查看已解决市场的待定结算
/poly allowance # 检查 USDC 授权状态
/poly orderbooks <token1> [token2] ... # 批量获取订单簿
完整的 ClobClient 方法参考
健康与配置(L0 - 无需认证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
get_ok() |
- | dict | 健康检查 |
get_server_time() |
- | dict | 服务器时间戳 |
get_address() |
- | str | 你的签名地址 |
get_collateral_address() |
- | str | USDC 合约 |
get_conditional_address() |
- | str | CTF 合约 |
get_exchange_address(neg_risk) |
bool | str | 交易所合约 |
市场数据(L0 - 无需认证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
get_midpoint(token_id) |
str | dict | 中间价格 |
get_midpoints(params) |
list[BookParams] | dict | 多个中间价格 |
get_price(token_id, side) |
str, str | dict | 最佳价格 |
get_prices(params) |
list[BookParams] | dict | 多个价格 |
get_spread(token_id) |
str | dict | 买卖价差 |
get_spreads(params) |
list[BookParams] | dict | 多个价差 |
get_order_book(token_id) |
str | OrderBookSummary | 完整订单簿 |
get_order_books(params) |
list[BookParams] | list | 多个订单簿 |
get_last_trade_price(token_id) |
str | dict | 最后一笔交易 |
get_last_trades_prices(params) |
list[BookParams] | dict | 多个最后交易 |
get_tick_size(token_id) |
str | TickSize | “0.1”/“0.01”/“0.001”/“0.0001” |
get_neg_risk(token_id) |
str | bool | 是否为负风险市场 |
get_fee_rate_bps(token_id) |
str | int | 以基点为单位的费用 |
市场发现(L0 - 无需认证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
get_markets(next_cursor) |
str | dict | 分页市场 |
get_simplified_markets(next_cursor) |
str | dict | 简化市场 |
get_sampling_markets(next_cursor) |
str | dict | 特色市场 |
get_market(condition_id) |
str | dict | 单一市场 |
get_market_trades_events(condition_id) |
str | dict | 交易事件 |
订单创建(L1 - 需要私钥)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
create_order(order_args, options) |
OrderArgs, CreateOrderOptions | dict | 签名限价订单 |
create_market_order(order_args, options) |
MarketOrderArgs, CreateOrderOptions | dict | 签名市价订单 |
calculate_market_price(token_id, side, amount, order_type) |
str, str, float, OrderType | float | 预期成交价格 |
订单发布(L2 - 需要 API 凭证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
post_order(order, orderType, post_only) |
SignedOrder, OrderType, bool | dict | 发布单个订单 |
post_orders(args) |
list[PostOrdersArgs] | dict | 发布批量订单 |
create_and_post_order(order_args, options) |
OrderArgs, PartialCreateOrderOptions | dict | 创建 + 发布(推荐) |
订单取消(L2 - 需要 API 凭证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
cancel(order_id) |
str | dict | 取消一个订单 |
cancel_orders(order_ids) |
list[str] | dict | 取消多个 |
cancel_all() |
- | dict | 取消全部订单 |
cancel_market_orders(market, asset_id) |
str, str | dict | 按市场取消 |
订单查询(L2 - 需要 API 凭证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
get_orders(params, next_cursor) |
OpenOrderParams, str | list | 获取开放订单 |
get_order(order_id) |
str | dict | 获取特定订单 |
get_trades(params, next_cursor) |
TradeParams, str | list | 交易历史 |
API 密钥管理(L2 - 需要 API 凭证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
create_api_key(nonce) |
int | ApiCreds | 创建新密钥 |
derive_api_key(nonce) |
int | ApiCreds | 导出现有密钥 |
create_or_derive_api_creds(nonce) |
int | ApiCreds | 创建或导出 |
set_api_creds(creds) |
ApiCreds | - | 设置凭证 |
get_api_keys() |
- | dict | 列出你的密钥 |
delete_api_key() |
- | dict | 删除当前密钥 |
create_readonly_api_key() |
- | ReadonlyApiKeyResponse | 只读密钥 |
get_readonly_api_keys() |
- | list[str] | 列出只读密钥 |
delete_readonly_api_key(key) |
str | bool | 删除只读密钥 |
余额与授权(L2 - 需要 API 凭证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
get_balance_allowance(params) |
BalanceAllowanceParams | dict | 检查余额 |
update_balance_allowance(params) |
BalanceAllowanceParams | dict | 刷新授权 |
高级功能(L2 - 需要 API 凭证)
| 方法 | 参数 | 返回 | 描述 |
|---|---|---|---|
post_heartbeat(heartbeat_id) |
str | dict | 保持订单活跃(10 秒超时) |
is_order_scoring(params) |
OrderScoringParams | dict | 检查是否赚取奖励 |
are_orders_scoring(params) |
OrdersScoringParams | dict | 检查多个订单 |
get_notifications() |
- | dict | 获取通知 |
drop_notifications(params) |
DropNotificationParams | dict | 删除通知 |
get_closed_only_mode() |
- | dict | 检查仅关闭状态 |
合约地址(Polygon 主网)
USDC = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" # 抵押品代币
CTF = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045" # 条件性代币(ERC-1155)
EXCHANGE = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E" # 常规交易所
NEG_RISK = "0xC5d563A36AE78145C45a50134d48A1215220f80a" # 负风险交易所(加密货币)
快速参考:常见模式
检查头寸 → 卖出全部
balance = get_token_balance(wallet, token_id)
if balance > 0:
client.create_and_post_order(OrderArgs(
token_id=token_id, price=0.01, size=balance, side="SELL"
))
制造商进入(无费用)
book = client.get_order_book(token_id)
best_bid = float(book.bids[0].price) if book.bids else 0
maker_price = best_bid + 0.01 # 比买价高 1 分
signed = client.create_order(OrderArgs(token_id=token_id, price=maker_price, size=100, side="BUY"))
client.post_order(signed, orderType=OrderType.GTC, post_only=True)
市价购买 50 美元
signed = client.create_market_order(MarketOrderArgs(token_id=token_id, amount=50.0, side="BUY"))
client.post_order(signed, orderType=OrderType.FOK)
取消全部
client.cancel_all()
WebSocket 频道(实时更新)
Polymarket 提供 WebSocket 频道以获取实时更新。不需要 RPC - 一切通过 CLOB 处理。
WebSocket URL
MARKET_WS = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
USER_WS = "wss://ws-subscriptions-clob.polymarket.com/ws/user"
市场频道(公共 - 无需认证)
订阅任何市场的订单簿更新、价格变动、交易。
import websocket
import json
def on_message(ws, message):
data = json.loads(message)
event_type = data.get("event_type")
if event_type == "book":
# 完整订单簿快照(订阅后 + 交易后)
print(f"订单簿更新:{data['bids']}, {data['asks']}")
elif event_type == "price_change":
# 订单放置/取消影响价格水平
print(f"价格变动:{data}")
elif event_type == "last_trade_price":
# 交易执行
print(f"交易:{data['price']} x {data['size']}")
elif event_type == "tick_size_change":
# 价格极端(>0.96 或 <0.04)
print(f"最小价格变动:{data['old_tick_size']} -> {data['new_tick_size']}")
def on_open(ws):
# 订阅特定代币
ws.send(json.dumps({
"type": "subscribe",
"channel": "market",
"assets_ids": [TOKEN_ID] # 代币 ID 列表
}))
ws = websocket.WebSocketApp(
"wss://ws-subscriptions-clob.polymarket.com/ws/market",
on_message=on_message,
on_open=on_open
)
ws.run_forever()
用户频道(认证 - 用于成交)
订阅你的订单更新、成交、交易。这是你获得成交通知的方式。
import websocket
import json
import hmac
import hashlib
import time
import base64
API_KEY = os.getenv("POLY_API_KEY")
API_SECRET = os.getenv("POLY_API_SECRET")
API_PASSPHRASE = os.getenv("POLY_API_PASSPHRASE")
def get_auth_headers():
"""为 WebSocket 生成 HMAC 认证"""
timestamp = str(int(time.time()))
message = f"GET
{timestamp}
/ws/user"
signature = hmac.new(
base64.b64decode(API_SECRET),
message.encode(),
hashlib.sha256
).digest()
return {
"POLY-ADDRESS": WALLET_ADDRESS,
"POLY-SIGNATURE": base64.b64encode(signature).decode(),
"POLY-TIMESTAMP": timestamp,
"POLY-API-KEY": API_KEY,
"POLY-PASSPHRASE": API_PASSPHRASE
}
def on_message(ws, message):
data = json.loads(message)
event_type = data.get("event_type")
if event_type == "trade":
# 你的成交 - 订单匹配!
status = data.get("status") # MATCHED, MINED, CONFIRMED, FAILED
print(f"成交:{data['side']} {data['size']} @ {data['price']}")
print(f" 状态:{status}")
print(f" 成交 ID:{data['id']}")
print(f" 市场:{data['market']}")
if status == "CONFIRMED":
print(" ✓ 交易在链上确认!")
elif status == "FAILED":
print(" ✗ 交易失败 - 检查日志")
elif event_type == "order":
order_type = data.get("type") # PLACEMENT, UPDATE, CANCELLATION
print(f"订单 {order_type}: {data['side']} {data['original_size']} @ {data['price']}")
print(f" 成交:{data.get('size_matched', 0)}")
if order_type == "CANCELLATION":
print(" 订单已取消")
def on_open(ws):
# 用认证订阅
ws.send(json.dumps({
"type": "subscribe",
"channel": "user",
"auth": get_auth_headers(),
# 可选:过滤到特定市场
# "markets": [CONDITION_ID]
}))
ws = websocket.WebSocketApp(
"wss://ws-subscriptions-clob.polymarket.com/ws/user",
on_message=on_message,
on_open=on_open
)
ws.run_forever()
消息类型总结
市场频道:
| 事件 | 触发器 | 关键字段 |
|---|---|---|
book |
订阅,交易影响订单簿 | 出价,要价,时间戳 |
price_change |
订单放置/取消 | 价格,大小,方向 |
last_trade_price |
交易执行 | 价格,大小,方向 |
tick_size_change |
价格极端(>0.96 或 <0.04) | 旧最小价格变动,新最小价格变动 |
用户频道:
| 事件 | 触发器 | 关键字段 |
|---|---|---|
trade |
你的订单成交 | 状态,方向,大小,价格,市场 |
order |
订单放置/更新/取消 | 类型(放置/更新/取消),成交大小 |
成交状态流程
MATCHED → MINED → CONFIRMED(成功)
→ RETRYING → CONFIRMED/FAILED
保持连接
每 10 秒发送一次 PING 以保持连接活跃:
import threading
def send_ping():
while True:
ws.send(json.dumps({"type": "ping"}))
time.sleep(10)
threading.Thread(target=send_ping, daemon=True).start()
实时数据客户端(替代方案)
Polymarket 还提供了 @polymarket/real-time-data-client 用于 TypeScript:
import { RealTimeDataClient } from "@polymarket/real-time-data-client";
const client = new RealTimeDataClient({
onMessage: (msg) => console.log(msg),
onConnect: (c) => {
// 用认证订阅用户成交
c.subscribe({
subscriptions: [{
topic: "clob_user",
type: "*",
clob_auth: {
key: API_KEY,
secret: API_SECRET,
passphrase: API_PASSPHRASE
}
}]
});
}
});
client.connect();
不需要 RPC - CLOB 处理一切
| 操作 | 方法 |
|---|---|
| 获取头寸 | GET /data/positions?user={address} 通过 Gamma API |
| 获取余额 | client.get_balance_allowance() |
| 下订单 | client.create_and_post_order() |
| 获取成交 | 用户 WebSocket 频道 |
| 获取价格 | client.get_order_book() 或市场 WebSocket |
| 取消订单 | client.cancel() |
你可能需要使用 RPC 来独立检查链上代币余额,但即使是这个也可以通过 Gamma API 头寸端点获得。