Polymarket
Founded in 2020, Polymarket is the world’s largest decentralized prediction market platform, enabling traders to speculate on the outcomes of world events by buying and selling binary option contracts using cryptocurrency.
NautilusTrader provides a venue integration for 数据 and 执行 via Polymarket's Central Limit Order Book (CLOB) API. The integration leverages the official Python CLOB client library to facilitate interaction with the Polymarket platform.
NautilusTrader is designed to work with Polymarket's signature type 0, supporting EIP712 signatures from externally owned accounts (EOA). This integration ensures that traders can execute 订单 securely and efficiently, using the most common on-chain signature method, while NautilusTrader abstracts the complexity of signing and preparing 订单 for seamless 执行.
安装
To install NautilusTrader with Polymarket 支持:
pip install --upgrade "nautilus_trader[polymarket]"
To build from source with all extras (including Polymarket):
uv sync --all-extras
示例
You can find live example scripts here.
Binary options
A binary option is a type of financial exotic option contract in which traders bet on the outcome of a yes-or-no proposition. If the prediction is correct, the trader receives a fixed payout; otherwise, they receive nothing.
All assets traded on Polymarket are quoted and settled in USDC.e (PoS), see below for more information.
Polymarket 文档
Polymarket offers comprehensive resources for different audiences:
- Polymarket Learn: Educational content and guides for users to understand the platform and how to engage with it.
- Polymarket CLOB API: Technical documentation for developers interacting with the Polymarket CLOB API.
概览
This 指南 assumes a trader is setting up for both live market 数据 feeds, and trade 执行. The Polymarket integration adapter includes multiple components, which can be used together or separately depending on the use case.
PolymarketWebSocketClient
: Low-level WebSocket API connectivity (built on top of the NautilusWebSocketClient
written in Rust).PolymarketInstrumentProvider
: Instrument parsing and loading functionality forBinaryOption
instruments.PolymarketDataClient
: A market data feed manager.PolymarketExecutionClient
: A trade execution gateway.PolymarketLiveDataClientFactory
: Factory for Polymarket data clients (used by the trading node builder).PolymarketLiveExecClientFactory
: Factory for Polymarket execution clients (used by the trading node builder).
Most users will simply define a 配置 for a 实时交易 节点 (as below), and won't need to necessarily work with these lower level components directly.
USDC.e (PoS)
USDC.e is a bridged 版本 of USDC from Ethereum to the Polygon 网络, operating on Polygon's Proof of Stake (PoS) chain. This enables faster, more cost-efficient transactions on Polygon while maintaining backing by USDC on Ethereum.
The contract address is 0x2791bca1f2de4661ed88a30c99a7a9449aa84174 on the Polygon blockchain. More information can be found in this blog.
Wallets and accounts
To interact with Polymarket via NautilusTrader, you’ll need a Polygon-compatible wallet (such as MetaMask). The integration uses Externally Owned Account (EOA) signature types compatible with EIP712, meaning the wallet is directly owned by the trader/user. This contrasts with the signature types used for Polymarket-administered wallets (such as those accessed via their user 接口).
A single wallet address is supported per trader instance when using 环境 variables,
or multiple wallets could be configured with multiple PolymarketExecutionClient
instances.
Ensure your wallet is funded with USDC.e, otherwise you will encounter the "not enough balance / allowance" API error when submitting 订单.
Setting allowances for Polymarket contracts
Before you can start trading, you need to ensure that your wallet has allowances set for Polymarket's smart contracts.
You can do this by running the provided script located at /适配器/Polymarket/scripts/set_allowances.py
.
This script is adapted from a gist created by @poly-rodr.
You only need to run this script once per EOA wallet that you intend to use for trading on Polymarket.
This script automates the process of approving the necessary allowances for the Polymarket contracts. It sets approvals for the USDC token and Conditional Token 框架 (CTF) contract to allow the Polymarket CLOB Exchange to interact with your funds.
Before running the script, ensure the following prerequisites are met:
- Install the web3 Python package:
pip install --upgrade web3==5.28
. - Have a Polygon-compatible wallet funded with some MATIC (used for gas fees).
- Set the following 环境 variables in your shell:
POLYGON_PRIVATE_KEY
: Your private key for the Polygon-compatible wallet.POLYGON_PUBLIC_KEY
: Your public key for the Polygon-compatible wallet.
Once you have these in place, the script will:
- Approve the maximum possible amount of USDC (using the
MAX_INT
value) for the Polymarket USDC token contract. - Set the approval for the CTF contract, allowing it to interact with your account for trading purposes.
You can also adjust the approval amount in the script instead of using MAX_INT
,
with the amount specified in fractional units of USDC.e, though this has not been tested.
Ensure that your private key and public key are correctly stored in the 环境 variables before running the script. Here's an example of how to set the variables in your terminal session:
export POLYGON_PRIVATE_KEY="YOUR_PRIVATE_KEY"
export POLYGON_PUBLIC_KEY="YOUR_PUBLIC_KEY"
Run the script using:
python nautilus_trader/adapters/polymarket/scripts/set_allowances.py
Script breakdown
The script performs the following actions:
- Connects to the Polygon network via an RPC URL (https://polygon-rpc.com/).
- Signs and sends a transaction to approve the maximum USDC allowance for Polymarket contracts.
- Sets approval for the CTF contract to manage Conditional Tokens on your behalf.
- Repeats the approval process for specific addresses like the Polymarket CLOB Exchange and Neg Risk Adapter.
This allows Polymarket to interact with your funds when executing trades and ensures smooth integration with the CLOB Exchange.
API keys
To trade with Polymarket using an EOA wallet, follow these steps to generate your API keys:
- Ensure the following 环境 variables are set:
POLYMARKET_PK
: Your private key for signing transactions.POLYMARKET_FUNDER
: The wallet address (public key) on the Polygon network used for funding trades on Polymarket.
-
Run the script using:
Python nautilus_trader/适配器/Polymarket/scripts/create_api_key.py
The script will generate and print API credentials, which you should save to the following 环境 variables:
POLYMARKET_API_KEY
POLYMARKET_API_SECRET
POLYMARKET_PASSPHRASE
These can then be used for Polymarket 客户端 configurations:
PolymarketDataClientConfig
PolymarketExecClientConfig
配置
When setting up NautilusTrader to work with Polymarket, it’s crucial to properly configure the necessary parameters, particularly the private key.
Key parameters
private_key
: This is the private key for your external EOA wallet (not the Polymarket wallet accessed through their GUI). This private key allows the system to sign and send transactions on behalf of the external account interacting with Polymarket. If not explicitly provided in the configuration, it will automatically source thePOLYMARKET_PK
environment variable.funder
: This refers to the USDC.e wallet address used for funding trades. If not provided, will source thePOLYMARKET_FUNDER
environment variable.- API credentials: You will need to provide the following API credentials to interact with the Polymarket CLOB:
api_key
: If not provided, will source thePOLYMARKET_API_KEY
environment variable.api_secret
: If not provided, will source thePOLYMARKET_API_SECRET
environment variable.passphrase
: If not provided, will source thePOLYMARKET_PASSPHRASE
environment variable.
We recommend using 环境 variables to manage your credentials.
Capability Matrix
Polymarket operates as a prediction market with limited order complexity compared to traditional exchanges.
Order types
Order Type | Binary Options | Notes |
---|---|---|
MARKET | ✓ | Executed as marketable limit order. |
LIMIT | ✓ | |
STOP_MARKET | - | Not supported. |
STOP_LIMIT | - | Not supported. |
MARKET_IF_TOUCHED | - | Not supported. |
LIMIT_IF_TOUCHED | - | Not supported. |
TRAILING_STOP_MARKET | - | Not supported. |
执行 instructions
Instruction | Binary Options | Notes |
---|---|---|
post_only | - | Not supported. |
reduce_only | - | Not supported. |
Time-in-force options
Time in force | Binary Options | Notes |
---|---|---|
GTC | ✓ | Good Till Canceled. |
GTD | ✓ | Good Till Date. |
FOK | ✓ | Fill or Kill. |
IOC | ✓ | Immediate or Cancel (maps to FAK). |
Advanced order features
功能 | Binary Options | Notes |
---|---|---|
Order Modification | - | Cancellation functionality only. |
Bracket/OCO 订单 | - | Not supported. |
Iceberg 订单 | - | Not supported. |
Batch operations
Operation | Binary Options | Notes |
---|---|---|
Batch Submit | - | Not supported. |
Batch Modify | - | Not supported. |
Batch Cancel | - | Not supported. |
Position management
功能 | Binary Options | Notes |
---|---|---|
Query 头寸 | ✓ | Contract balance-based 头寸. |
Position mode | - | Binary outcome 头寸 only. |
Leverage control | - | No leverage available. |
Margin mode | - | No margin trading. |
Order querying
功能 | Binary Options | Notes |
---|---|---|
Query open 订单 | ✓ | Active 订单 only. |
Query order history | ✓ | Limited historical 数据. |
Order status updates | ✓ | 实时 order state changes. |
Trade history | ✓ | 执行 and fill 报告. |
Contingent 订单
功能 | Binary Options | Notes |
---|---|---|
Order lists | - | Not supported. |
OCO 订单 | - | Not supported. |
Bracket 订单 | - | Not supported. |
Conditional 订单 | - | Not supported. |
配置 options
The following 执行 客户端 配置 options are available:
Option | Default | Description |
---|---|---|
signature_type | 0 | Polymarket signature type (EOA). |
funder | None | Wallet address for funding USDC transactions. |
generate_order_history_from_trades | False | Experimental 功能 to generate order 报告 from trade history (not recommended). |
log_raw_ws_messages | False | If True , logs raw WebSocket messages (性能 penalty from pretty JSON formatting). |
Trades
Trades on Polymarket can have the following statuses:
MATCHED
: Trade has been matched and sent to the executor service by the operator, the executor service submits the trade as a transaction to the Exchange contract.MINED
: Trade is observed to be mined into the chain, and no finality threshold is established.CONFIRMED
: Trade has achieved strong probabilistic finality and was successful.RETRYING
: Trade transaction has failed (revert or reorg) and is being retried/resubmitted by the operator.FAILED
: Trade has failed and is not being retried.
Once a trade is initially matched, subsequent trade status updates will be received via the WebSocket.
NautilusTrader records the initial trade details in the info
field of the OrderFilled
event,
with additional trade events stored in the 缓存 as JSON under a custom key to retain this information.
Reconciliation
The Polymarket API returns either all active (open) 订单 or specific 订单 when queried by the
Polymarket order ID (venue_order_id
). The 执行 reconciliation procedure for Polymarkert is as follows:
- Generate order 报告 for all 金融工具 with active (open) 订单, as reported by Polymarket.
- Generate position 报告 from contract balances reported by Polymarket, per 金融工具 available in the 缓存.
- Compare these 报告 with Nautilus 执行 state.
- Generate missing 订单 to bring Nautilus 执行 state in line with 头寸 reported by Polymarket.
Note: Polymarket does not directly provide data for orders which are no longer active.
An optional 执行 客户端 配置, generate_order_history_from_trades
, is currently under 开发.
It is not recommended for 生产 use at this time.
WebSockets
The PolymarketWebSocketClient
is built on top of the 高性能 Nautilus WebSocketClient
base class, written in Rust.
数据
The main 数据 WebSocket handles all market
channel subscriptions received during the initial
connection sequence, up to ws_connection_delay_secs
. For any additional subscriptions, a new PolymarketWebSocketClient
is
created for each new instrument (asset).
执行
The main 执行 WebSocket manages all user
channel subscriptions based on the Polymarket 金融工具
available in the 缓存 during the initial connection sequence. When trading commands are issued for additional 金融工具,
a separate PolymarketWebSocketClient
is created for each new instrument (asset).
Polymarket does not 支持 unsubscribing from channel streams once subscribed.
Limitations and considerations
The following limitations and considerations are currently known:
- Order signing via the Polymarket Python 客户端 is slow, taking around one second.
- Post-only 订单 are not supported.
- Reduce-only 订单 are not supported.