跳到主要内容

Polymarket

Polymarket 成立于 2020 年,是全球最大的去中心化预测市场平台,允许交易者通过使用加密货币买卖二元期权合约来对世界事件的结果进行投机。

NautilusTrader 提供了对 Polymarket 的接入(venue integration),可通过 Polymarket 的中央限价撮合簿(Central Limit Order Book,CLOB)API 获取市场数据和执行交易。 该集成基于 官方的 Python CLOB 客户端库,以便更方便地与 Polymarket 平台交互。

NautilusTrader 支持多种 Polymarket 的签名类型以用于订单签名,从而适配不同的钱包配置。 该集成确保交易者可以在不同钱包类型之间安全且高效地执行订单,同时 NautilusTrader 抽象化了签名与订单准备的复杂性,提供无缝执行体验。

安装

安装带有 Polymarket 支持的 NautilusTrader:

pip install --upgrade "nautilus_trader[polymarket]"

从源码构建并包含所有可选项(包括 Polymarket):

uv sync --all-extras

示例

可在此处查看实盘示例脚本:examples/live/polymarket

二元期权(Binary options)

Binary option(二元期权)是一类金融衍生品合约,交易者对某个“是/否”命题的结果进行押注。 若预测正确,交易者会获得固定的支付(payout);否则将一无所获。

在 Polymarket 上交易的所有资产均以 USDC.e (PoS) 报价和结算,更多信息请参见下文 USDC.e (PoS)

Polymarket 文档

Polymarket 为不同用户提供了详尽的资源:

概览

本指南假定交易者希望同时接入实时市场数据流和下单执行功能。 Polymarket 适配器包含多个组件,可根据用例单独或组合使用:

  • PolymarketWebSocketClient:底层 WebSocket API 连接(基于用 Rust 编写的 Nautilus WebSocketClient)。
  • PolymarketInstrumentProvider:用于解析与加载 BinaryOption 类型 instrument 的功能。
  • PolymarketDataClient:市场数据管理器。
  • PolymarketExecutionClient:交易执行网关。
  • PolymarketLiveDataClientFactory:Polymarket 数据客户端的工厂(由交易节点构建器使用)。
  • PolymarketLiveExecClientFactory:Polymarket 执行客户端的工厂(由交易节点构建器使用)。
备注

大多数用户只需为 live trading node 定义配置(如下),通常不需要直接与这些底层组件交互。

USDC.e (PoS)

USDC.e 是将以太坊(Ethereum)上的 USDC 桥接到 Polygon 网络的代币,运行在 Polygon 的 Proof of Stake (PoS) 链上。 这使得在 Polygon 上的交易更快且成本更低,同时仍由以太坊上的 USDC 提供支持。

该代币在 Polygon 链上的合约地址为 0x2791bca1f2de4661ed88a30c99a7a9449aa84174。 更多信息请参见这篇 博客

钱包与账户

要通过 NautilusTrader 与 Polymarket 交互,你需要一个兼容 Polygon 的钱包(例如 MetaMask)。

签名类型

Polymarket 支持多种用于订单签名与验证的签名类型:

Signature TypeWallet TypeDescriptionUse Case
0EOA (Externally Owned Account)使用私钥直接控制的钱包所产生的标准 EIP712 签名。默认。 直接连接的钱包(如 MetaMask、硬件钱包等)。
1Email/Magic Wallet Proxy基于智能合约的邮箱账户(Magic Link)钱包代理。仅与该邮箱关联的地址可执行函数。适用于与 Email/Magic 账户关联的 Polymarket Proxy。需要 funder 地址。
2Browser Wallet Proxy为浏览器钱包定制的 Gnosis Safe(1-of-1 multisig)变体。适用于浏览器钱包的 Polymarket Proxy,支持 UI 验证。需要 funder 地址。
备注

详情请参见 Polymarket 文档中的 Proxy wallet,了解签名类型和代理钱包架构的更多细节。

NautilusTrader 默认使用签名类型 0(EOA),但可以通过配置参数 signature_type 切换为任意受支持的签名类型。

当通过环境变量配置时,每个交易实例支持单个钱包地址;也可以为多个钱包创建多个 PolymarketExecutionClient 实例。

备注

确保你的钱包中有 USDC.e 余额,否则在提交订单时会遇到 “not enough balance / allowance” 的 API 错误。

为 Polymarket 合约设置 allowance

在开始交易之前,你需要为 Polymarket 的智能合约为你的钱包设置相应的 allowance(授权)。 可通过运行项目中提供的脚本来完成,脚本路径为 /adapters/polymarket/scripts/set_allowances.py

该脚本改编自 @poly-rodr 在 gist 上的实现:https://gist.github.com/poly-rodr/44313920481de58d5a3f6d1f8226bd5e

备注

对于每个你打算在 Polymarket 上交易的 EOA 钱包,该脚本只需运行 一次

该脚本会自动完成为 Polymarket 合约批准所需的操作,包括为 USDC 代币和 Conditional Token Framework (CTF) 合约设置授权,允许 Polymarket CLOB 交易所与资金交互。

在运行脚本之前,请确保满足以下先决条件:

  • 安装 web3 Python 包:pip install --upgrade web3==7.12.1
  • 拥有一个已注入部分 MATIC(用于支付 gas 费用)的 Polygon 兼容钱包。
  • 在 shell 中设置如下环境变量:
    • POLYGON_PRIVATE_KEY:你的 Polygon 兼容钱包的私钥。
    • POLYGON_PUBLIC_KEY:你的 Polygon 兼容钱包的公钥(public key)。

满足以上条件后,脚本将:

  • 为 Polymarket USDC 代币合约批准最大可用额度(使用 MAX_INT)。
  • 为 CTF 合约设置批准,允许其代表你管理 Conditional Tokens。
备注

你也可以在脚本中调整批准额度,而不使用 MAX_INT,以 USDC.e 的小数单位(fractional units)指定具体数额;但该方式未经充分测试。

请确保在运行脚本前正确地将私钥与公钥存入环境变量中。下面是一个在终端中设置环境变量的示例:

export POLYGON_PRIVATE_KEY="YOUR_PRIVATE_KEY"
export POLYGON_PUBLIC_KEY="YOUR_PUBLIC_KEY"

运行脚本:

python nautilus_trader/adapters/polymarket/scripts/set_allowances.py

脚本功能概览

该脚本会执行下列操作:

  • 通过 RPC URL(例如 https://polygon-rpc.com/)连接到 Polygon 网络。
  • 对批准 Polymarket 合约的最大 USDC 授权发起签名并发送交易。
  • 为 CTF 合约设置批准,以便其代为管理条件代币(Conditional Tokens)。
  • 为特定地址(如 Polymarket CLOB Exchange 与 Neg Risk Adapter)重复批准流程。

这些步骤允许 Polymarket 在执行交易时与您的资金进行交互,从而保证与 CLOB Exchange 的集成顺畅。

API 密钥

要在 Polymarket 上交易,你需要生成 API 凭证。按以下步骤操作:

  1. 确保已设置下列环境变量:

    • POLYMARKET_PK:用于签名交易的私钥。
    • POLYMARKET_FUNDER:在 Polygon 网络上用于资助 Polymarket 交易的钱包地址(公钥)。
  2. 运行脚本以生成 API 密钥:

    python nautilus_trader/adapters/polymarket/scripts/create_api_key.py

脚本将生成并打印 API 凭证,请保存到以下环境变量中:

  • POLYMARKET_API_KEY
  • POLYMARKET_API_SECRET
  • POLYMARKET_PASSPHRASE

这些凭证可用于配置下列 Polymarket 客户端:

  • PolymarketDataClientConfig
  • PolymarketExecClientConfig

配置

在为 NautilusTrader 配置 Polymarket 时,务必正确设置必要参数,尤其是私钥相关字段。

关键参数

  • private_key:用于签名订单的钱包私钥。其含义依赖于 signature_type 配置。如果配置中没有明确提供,将自动从环境变量 POLYMARKET_PK 中获取。
  • funder:用于为交易提供资金的 USDC.e 钱包地址。如果未提供,将从 POLYMARKET_FUNDER 环境变量读取。
  • API 凭证:与 Polymarket CLOB 交互需要以下凭证:
    • api_key:若未提供,则从环境变量 POLYMARKET_API_KEY 获取。
    • api_secret:若未提供,则从环境变量 POLYMARKET_API_SECRET 获取。
    • passphrase:若未提供,则从环境变量 POLYMARKET_PASSPHRASE 获取。
提示

建议使用环境变量来管理这些凭证。

订单能力(Orders capability)

Polymarket 作为预测市场,其支持的订单类型与指令集较传统交易所更为有限。

订单类型

Order TypeBinary OptionsNotes
MARKETBUY orders require quote quantity, SELL orders require base quantity.
LIMIT
STOP_MARKET-Not supported by Polymarket.
STOP_LIMIT-Not supported by Polymarket.
MARKET_IF_TOUCHED-Not supported by Polymarket.
LIMIT_IF_TOUCHED-Not supported by Polymarket.
TRAILING_STOP_MARKET-Not supported by Polymarket.

数量含义(Quantity semantics)

Polymarket 根据订单类型和买卖方向对数量的含义进行不同解释:

  • Limit 订单将 quantity 视为条件代币(conditional tokens,即 base 单位)的数量。
  • Market SELL(市价卖单)也使用 base 单位数量。
  • Market BUY(市价买单)则把 quantity 解释为以 USDC.e 计价的 quote 名义金额(notional)。

因此,如果用 base 单位提交一个市价买单,实际成交量可能远超预期。

注意

当提交市价 BUY 单时,请设置 quote_quantity=True(或预先计算好以 quote 计价的金额), 并在执行引擎中将 convert_quote_qty_to_base=False,以确保 quote 金额不被引擎转换,从而原样发送到适配器。 Polymarket 的执行客户端会拒绝以 base 单位提交的市价买单,以防止意外成交。

NautilusTrader 现在会将市价单直接转发到 Polymarket 的原生 market-order 终端点,因而你为 BUY 指定的 quote 金额会被直接执行(不再使用合成的最大价格限制)。

from nautilus_trader.execution.config import ExecEngineConfig
from nautilus_trader.execution.engine import ExecutionEngine

# Temporary: disable automatic conversion until the behaviour is fully removed in a future release
config = ExecEngineConfig(convert_quote_qty_to_base=False)
engine = ExecutionEngine(msgbus=msgbus, cache=cache, clock=clock, config=config)

# Correct: Market BUY with quote quantity (spend $10 USDC)
order = strategy.order_factory.market(
instrument_id=instrument_id,
order_side=OrderSide.BUY,
quantity=instrument.make_qty(10.0),
quote_quantity=True, # Interpret as USDC.e notional
)
strategy.submit_order(order)

执行指令(Execution instructions)

InstructionBinary OptionsNotes
post_only-Not supported by Polymarket.
reduce_only-Not supported by Polymarket.

有效时间(Time-in-force)选项

Time in forceBinary OptionsNotes
GTCGood Till Canceled.
GTDGood Till Date.
FOKFill or Kill.
IOCImmediate or Cancel (maps to FAK).
备注

FAK (Fill and Kill) 是 Polymarket 对 Immediate or Cancel (IOC) 语义的称呼。

高级订单特性

FeatureBinary OptionsNotes
Order Modification-Cancellation functionality only.
Bracket/OCO Orders-Not supported by Polymarket.
Iceberg Orders-Not supported by Polymarket.

批量操作

OperationBinary OptionsNotes
Batch Submit-Not supported by Polymarket.
Batch Modify-Not supported by Polymarket.
Batch Cancel-Not supported by Polymarket.

仓位管理

FeatureBinary OptionsNotes
Query positionsContract balance-based positions.
Position mode-Binary outcome positions only.
Leverage control-No leverage available.
Margin mode-No margin trading.

订单查询

FeatureBinary OptionsNotes
Query open ordersActive orders only.
Query order historyLimited historical data.
Order status updatesReal-time order state changes.
Trade historyExecution and fill reports.

或有订单(Contingent orders)

FeatureBinary OptionsNotes
Order lists-Not supported by Polymarket.
OCO orders-Not supported by Polymarket.
Bracket orders-Not supported by Polymarket.
Conditional orders-Not supported by Polymarket.

精度限制(Precision limits)

Polymarket 根据 tick size 与订单类型执行不同的精度约束。

Binary Option instruments 通常支持最多 6 位小数(在 0.0001 tick size 情况下),但 市价单有更严格的精度要求

  • FOK(Fill-or-Kill)市价单:

    • 卖单(Sell orders):maker 金额限制为 2 位小数
    • taker 金额:限制为 4 位小数
    • size × price 的乘积不得超过 2 位小数
  • 普通 GTC 订单: 根据市场 tick size,精度更为宽松。

Tick size 精度层级

Tick SizePrice DecimalsSize DecimalsAmount Decimals
0.1123
0.01224
0.001325
0.0001426
备注
  • Tick size 精度层级定义见 py-clob-clientROUNDING_CONFIG
  • FOK 市价单精度限制(maker 金额 2 位小数)基于 API 返回的错误信息,详见 issue #121
  • 在极端或单边市场条件下,tick size 可能会动态变化。

交易(Trades)

Polymarket 上的交易可能具有以下状态:

  • MATCHED:交易已被撮合并由 operator 发送到 executor 服务,executor 将交易作为链上交易提交到 Exchange 合约。
  • MINED:交易已被观察到被打包进区块,但没有达成最终性阈值。
  • CONFIRMED:交易已达到较强概率上的最终性并成功完成。
  • RETRYING:交易(因 revert 或 reorg)失败,operator 正在重试/重新提交交易。
  • FAILED:交易失败且不再重试。

当交易首次被撮合后,后续的交易状态更新将通过 WebSocket 接收。 NautilusTrader 会将初始成交信息记录在 OrderFilled 事件的 info 字段中, 并把后续的交易事件以 JSON 形式保存在缓存中(使用自定义键)以便保留这些信息。

对账(Reconciliation)

Polymarket API 在查询时返回所有 active(未完成)订单,或通过 Polymarket 订单 ID(venue_order_id)返回指定订单。 针对 Polymarket 的执行对账流程如下:

  • 为 Polymarket 报告的所有有未完成订单的 instruments 生成订单报告(order reports)。
  • 从 Polymarket 报告的合约余额中生成仓位报告(仅针对缓存中可用的 instruments)。
  • 将这些报告与 Nautilus 的执行状态进行比较。
  • 生成缺失的订单,以使 Nautilus 的执行状态与 Polymarket 报告的仓位保持一致。

注意:Polymarket 不会直接提供已不再活跃(no longer active)的订单数据。

注意

一个可选的执行客户端配置 generate_order_history_from_trades 目前仍在开发中, 暂不建议在生产环境中使用。

WebSockets

PolymarketWebSocketClient 构建于高性能的 Nautilus WebSocketClient 基类之上,该基类使用 Rust 编写。

数据(Data)

主数据 WebSocket 在初始连接序列期间处理所有 market 频道的订阅,直到达到 ws_connection_delay_secs。 对于任何额外的订阅,针对每个新 instrument(资产)会创建一个新的 PolymarketWebSocketClient

执行(Execution)

主执行 WebSocket 在初始连接序列期间基于缓存中可用的 Polymarket instruments 管理所有 user 频道的订阅。 当对额外的 instruments 发出交易指令时,会为每个新增的 instrument 创建独立的 PolymarketWebSocketClient

备注

Polymarket 不支持在订阅后取消订阅频道流(unsubscribe)。

限制与注意事项

目前已知的限制与注意事项包括:

  • 通过 Polymarket 的 Python 客户端进行订单签名较慢,约需一秒钟左右。
  • 不支持 post-only 订单。
  • 不支持 reduce-only 订单。

配置

Data client configuration options

OptionDefaultDescription
venuePOLYMARKETVenue identifier registered for the data client.
private_keyNoneWallet private key; sourced from POLYMARKET_PK when omitted.
signature_type0Signature scheme (0 = EOA, 1 = email proxy, 2 = browser wallet proxy).
funderNoneUSDC.e funding wallet; sourced from POLYMARKET_FUNDER when omitted.
api_keyNoneAPI key; sourced from POLYMARKET_API_KEY when omitted.
api_secretNoneAPI secret; sourced from POLYMARKET_API_SECRET when omitted.
passphraseNoneAPI passphrase; sourced from POLYMARKET_PASSPHRASE when omitted.
base_url_httpNoneOverride for the REST base URL.
base_url_wsNoneOverride for the WebSocket base URL.
ws_connection_initial_delay_secs5Delay (seconds) before the first WebSocket connection to buffer subscriptions.
ws_connection_delay_secs0.1Delay (seconds) between subsequent WebSocket connection attempts.
update_instruments_interval_mins60Interval (minutes) between instrument catalogue refreshes.
compute_effective_deltasFalseCompute effective order book deltas for bandwidth savings.
drop_quotes_missing_sideTrueDrop quotes with missing bid/ask prices instead of substituting boundary values.

Execution client configuration options

OptionDefaultDescription
venuePOLYMARKETVenue identifier registered for the execution client.
private_keyNoneWallet private key; sourced from POLYMARKET_PK when omitted.
signature_type0Signature scheme (0 = EOA, 1 = email proxy, 2 = browser wallet proxy).
funderNoneUSDC.e funding wallet; sourced from POLYMARKET_FUNDER when omitted.
api_keyNoneAPI key; sourced from POLYMARKET_API_KEY when omitted.
api_secretNoneAPI secret; sourced from POLYMARKET_API_SECRET when omitted.
passphraseNoneAPI passphrase; sourced from POLYMARKET_PASSPHRASE when omitted.
base_url_httpNoneOverride for the REST base URL.
base_url_wsNoneOverride for the WebSocket base URL.
max_retriesNoneMaximum retry attempts for submit/cancel requests.
retry_delay_initial_msNoneInitial delay (milliseconds) between retries.
retry_delay_max_msNoneMaximum delay (milliseconds) between retries.
generate_order_history_from_tradesFalseGenerate synthetic order history from trade reports when True (experimental).
log_raw_ws_messagesFalseLog raw WebSocket payloads at INFO level when True.
信息

For additional features or to contribute to the Polymarket adapter, please see our contributing guide.