trading-polymarket trading-polymarket

这个技能提供了使用 Polymarket 的 CLOB(中央限价订单簿)通过官方 py_clob_client 库进行交易的完整指南和 API 参考,包括市场数据获取、订单操作、API 密钥管理等,适用于量化交易和算法交易。

算法交易 0 次安装 0 次浏览 更新于 3/5/2026

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 头寸端点获得。