2026년 Polymarket Python SDK (그리고 py-clob-client에서 옮겨 가기)
코드가 아직 py_clob_client에서 ClobClient를 import한다면, 대체된 패키지 위에 만들어진 것입니다. AI 어시스턴트가 작성해 주는 Polymarket 코드도 대부분 마찬가지입니다. 현재 SDK와 옮겨 가는 방법을 소개합니다.
핵심 요약
Polymarket은 이제 통합 SDK를 제공합니다. Python은 polymarket-client, TypeScript는 @polymarket/client입니다. 이 SDK들은 py-clob-client, @polymarket/clob-client-v2, @polymarket/builder-relayer-client, @polymarket/builder-signing-sdk를 대체합니다. 통합 Rust SDK도 개발 중입니다.
이 변화가 일반적인 버전 업데이트보다 중요한 이유는 하나입니다. 인터넷에 있는 거의 모든 Polymarket 코드 예제가 이보다 오래되었습니다. 블로그 글, Stack Overflow 답변, GitHub 예제, 그리고 그런 자료로 학습했기 때문에 Polymarket 봇을 요청하면 AI 어시스턴트가 작성하는 코드도 마찬가지입니다. 존재하지 않는 import를 디버깅하고 있었다면 이것이 이유입니다.
실제로 바뀐 것
이전 방식은 Polymarket 서비스마다 클라이언트가 하나씩 있었습니다. 오더북은 CLOB 클라이언트를 import하고, 마켓 탐색은 원시 HTTP로 Gamma를 호출하고, 포지션은 Data API를 따로 호출하고, relayer 트랜잭션이 필요하면 builder-signing 패키지를 가져왔습니다. 네 가지 사고 모델, 네 가지 오류 형태, 네 가지 페이지네이션 방식이었습니다.
통합 SDK는 이를 모든 영역을 다루는 하나의 클라이언트로 합칩니다.
| 이전 클라이언트 | 통합 SDK | |
|---|---|---|
| 패키지 | 서비스마다 하나씩 여러 개 | 하나 |
| Polymarket 영역 | 서비스별 API | 하나의 클라이언트 인터페이스 |
| 데이터 모델 | 원시 JSON 딕셔너리 | 타입이 지정된 모델 |
| 페이지네이션 | API마다 다름 | 일관된 하나의 페이지네이터 |
| 인증 및 서명 | 클라이언트마다 직접 구현 | SDK 헬퍼 |
| 실시간 | 각 WebSocket에 따로 연결 | subscribe()가 피드를 병합 |
설치
pip install polymarket-client
# uv add polymarket-client
# poetry add polymarket-client패키지 이름과 import 이름이 다릅니다
설치는 polymarket-client로 하지만 import는 polymarket에서 합니다. 첫 줄부터 사람들이 걸려 넘어지는 부분이며, 한 번도 실행되지 않은 생성 코드를 알아보는 확실한 방법이기도 합니다. 코드 조각이 import polymarket_client를 한다면 아무도 실행해 보지 않은 것입니다.
네 가지 클라이언트: 신중하게 고르세요
| 클라이언트 | 공개 데이터 | 거래 | 실시간 | 용도 |
|---|---|---|---|---|
AsyncPublicClient | 예 | 아니요 | 예 | 봇, 데이터 수집기 |
AsyncSecureClient | 예 | 예 | 예 | 트레이딩 봇 |
PublicClient | 예 | 아니요 | 아니요 | 스크립트, 노트북 |
SecureClient | 예 | 예 | 아니요 | 거래하는 스크립트 |
실시간 기능은 비동기 전용입니다
PublicClient와 SecureClient는 subscribe()를 구현하지 않습니다. 오더북 업데이트를 스트리밍할 계획이라면(제대로 된 봇이라면 모두 그래야 합니다) 비동기 클라이언트 중 하나가 필요합니다. 초기에 동기 클라이언트를 골랐다가 나중에 이를 알게 되면 번거로운 리팩터링을 해야 합니다.
import asyncio
from polymarket import AsyncPublicClient
async def main() -> None:
async with AsyncPublicClient() as client:
pages = client.list_markets(closed=False)
first = await pages.first_page()
for market in first.items:
print(market.slug)
asyncio.run(main())공개 데이터에는 자격 증명이 필요 없으므로, 키를 도입하기 전에 가능한 모든 것을 AsyncPublicClient로 만들고 테스트하세요. 탐색, 파싱, 페이지네이션, 신호 생성, 백오프를 모두 아무런 위험 없이 검증할 수 있습니다.
페이지네이션
모든 목록 메서드에서 하나의 페이지네이터 인터페이스를 사용합니다. 페이지 경계가 중요한지에 따라 세 가지 방식으로 사용할 수 있습니다:
pages = client.list_markets(closed=False, page_size=10)
# 1. Page at a time — use this when you need to control pacing
# against the tight /markets rate limit (300 req / 10s).
async for page in pages:
for market in page.items:
...
# 2. Item at a time, boundaries ignored.
async for market in pages.iter_items():
...
# 3. Manual, resumable.
page = await pages.first_page()
if page.next_cursor:
nxt = await pages.from_cursor(page.next_cursor).first_page()next_cursor는 불투명하므로 그대로 저장하세요
커서를 파싱하거나, 디코딩하거나, 직접 만들지 마세요. 나중에 긴 스캔을 재개하려면 문자열을 그대로 저장하고, 처음부터 시작하려면 생략하세요. 직접 만든 커서는 인코딩이 바뀌기 전까지만 동작합니다.
타입이 지정된 모델
메서드는 딕셔너리가 아니라 최상위 패키지에서 내보내는 실제 타입을 반환합니다:
from polymarket import Event, Market, OrderBook, PriceHistoryPoint가장 화려하지 않은 개선이지만 아마 가장 가치 있는 개선입니다. 이전 클라이언트에서는 이름이 바뀌거나 빠진 필드가 런타임에 전략 루프 깊은 곳에서 KeyError로 나타났습니다. 흔히 프로덕션에서, 흔히 포지션을 보유한 상태에서였습니다. 타입 모델은 그 실패를 있어야 할 자리로 옮겨 줍니다.
실시간 구독
subscribe()는 여러 피드를 타입이 지정된 단일 이벤트 스트림으로 병합합니다. 여러 WebSocket 연결을 직접 관리하는 것보다 확실히 나아진 점입니다.
from polymarket.streams import MarketSpec, SportsSpec
async with await client.subscribe(
[MarketSpec(token_ids=[token_id]), SportsSpec()],
) as stream:
async for event in stream:
# MarketBookEvent | MarketPriceChangeEvent
# | MarketLastTradePriceEvent | MarketTickSizeChangeEvent
# | MarketBestBidAskEvent | NewMarketEvent
# | MarketResolvedEvent | SportsEvent
handle(event)SDK는 원래 직접 구현해야 했을 하트비트, 프레이밍, 재연결을 처리합니다. 원시 연결에서 10초마다 PING을 보내야 하는 요구 사항도 포함됩니다. 자세한 내용은 WebSocket 가이드에 있습니다.
주문 넣기
market = await client.get_market(slug="<market-slug>")
token_id = market.outcomes.yes.token_id
assert token_id is not None
response = await client.place_market_order(
token_id=token_id,
side="BUY",
amount="10", # pUSD to spend, not shares to buy
)
if not response.ok:
raise RuntimeError(response.message)
# Settlement is on-chain and asynchronous.
hashes = await client.wait_for_order_fill_settlement(response)
# Reconcile rather than assuming.
page = await client.list_positions(market=[market.condition_id]).first_page()
position = next((p for p in page.items if p.token_id == token_id), None)amount는 규모가 아니라 지출액입니다
place_market_order(amount="10")은 10주 매수가 아니라 최대 10 pUSD 지출을 뜻합니다. 0.20에 거래되는 계약이라면 약 50주입니다. 이를 잘못 읽으면 의도보다 다섯 배 큰 포지션을 쉽게 잡게 됩니다.
py-clob-client에서 마이그레이션하기
- 모든 Polymarket 호출을 목록으로 정리하세요. Gamma와 Data API에 대한 원시
requests호출도 포함됩니다. 이것들도 대상입니다. 통합 SDK가 다루며, 이들을 합치는 것이 이점의 대부분입니다. polymarket-client를 설치하고 이전 패키지를 제거하세요. 점진적으로 마이그레이션하려고 둘 다 설치해 두면 잘못된client심볼을 import하게 됩니다.- 클라이언트 생성 코드를 교체하세요.
AsyncSecureClient.create(...)하나가 이전의 서비스별 클라이언트와 별도의 자격 증명 처리를 대체합니다. - 딕셔너리 접근을 속성 접근으로 바꾸세요.
market["condition_id"]는market.condition_id가 됩니다. 지루한 작업이지만, 타입 검사기가 제값을 하기 시작하는 지점입니다. - 페이지네이션을 수동 offset이나 커서 루프 대신 페이지네이터 인터페이스로 다시 작성하세요.
- 직접 만든 WebSocket 코드를
subscribe()로 교체하고, 하트비트와 재연결 로직을 삭제하세요. - 읽기 전용 경로를 먼저 다시 실행하세요. 무엇이든 주문을 넣게 하기 전에 공개 클라이언트로 실행합니다.
TypeScript에는 서명자 어댑터가 있습니다
TypeScript SDK는 Viem, Privy, Ethers v5 어댑터를 제공하므로, CLOB 전용 서명을 구현하는 대신 기존 지갑 라이브러리를 연결하면 됩니다. 이전 builder-signing 패키지에 맞춰 맞춤 서명자를 유지보수하고 있었다면, 이제 그 코드를 삭제할 수 있습니다.
AI 어시스턴트가 이것을 틀리는 이유
많은 사람이 이 글에 오게 되는 경로이므로 직접 다룰 가치가 있습니다. LLM에게 Polymarket Python 코드를 요청하면 py_clob_client import, ClobClient(...) 생성, OrderArgs 객체가 아주 자주 나옵니다. 모델이 오작동하는 것이 아닙니다. 통합 SDK 이전의, 모델이 본 압도적 다수의 Polymarket 코드를 재현하고 있는 것입니다.
- import 줄을 먼저 확인하세요.
from polymarket import ...가 현재 방식이고,from py_clob_client...는 아닙니다. - 현재 문서를 컨텍스트에 붙여 넣으세요. Polymarket은
docs.polymarket.com/llms.txt에 기계가 읽을 수 있는 Markdown을 공개하며, 모든 페이지에.md버전이 있습니다. 모델과 논쟁하는 것보다 진짜 문서를 주는 편이 낫습니다. - 실행되지 않는 자신만만한 코드를 의심하세요. 생성된 코드는 이전 API와 새 API를 섞어 존재한 적 없는 무언가를 만드는 경우가 많습니다.
데이터 제공업체에도 같은 문제가 있습니다. 저희는 어시스턴트가 추측 없이 올바른 PolyTest 연동 코드를 작성할 수 있도록 llms.txt, llms-full.txt, OpenAPI 명세를 공개하고 AI 크롤러를 허용합니다. 일부 제공업체는 이런 크롤러를 차단하는데, 정당한 선택이지만 그러면 어시스턴트가 그들의 API 형태를 즉흥적으로 지어내게 됩니다.
SDK로도 여전히 할 수 없는 것
통합 SDK는 Polymarket API에 대한 훨씬 나은 인터페이스입니다. 하지만 그 API에 담긴 내용을 바꾸지는 않으며, 봇 개발자가 가장 원하는 것은 거기에 없습니다.
과거 오더북은 없습니다. client.get_market()은 결과가 확정된 마켓의 메타데이터를 반환하지만 오더북은 사라졌습니다. /book은 404를 반환하고, prices-history는 약 1분에 한 포인트만 보관합니다. 어떤 SDK 메서드, 플랜, 자격 증명으로도 오더북을 되살릴 수 없습니다.
백테스팅에는 마켓이 진행되는 동안 기록된 스냅샷이 필요합니다. PolyTest는 암호화폐 Up/Down 마켓에 대해 이를 제공합니다. 240M+개의 특정 시점 스냅샷, 한쪽당 8단계 깊이, 1초 미만 단위 타임스탬프, 결과가 확정된 마켓 보존. X-API-Key 헤더를 쓰는 평범한 REST API이므로 SDK와 같은 비동기 코드에 그대로 넣을 수 있습니다. 무료로 시작하거나, 전체 과정은 봇 만드는 방법을 읽어 보세요.
자주 묻는 질문
- 2026년 Polymarket 공식 Python SDK는 무엇인가요?
- 공식 Python SDK는 polymarket-client로, pip install polymarket-client로 설치하고 polymarket으로 import합니다. CLOB, Gamma, Data API와 실시간 스트림을 하나의 클라이언트 인터페이스로 다루는 통합 SDK이며 py-clob-client를 대체합니다. TypeScript 버전은 @polymarket/client이고, 통합 Rust SDK는 개발 중입니다.
- py-clob-client는 지원 중단되었나요?
- TypeScript 패키지 @polymarket/clob-client-v2, @polymarket/builder-relayer-client, @polymarket/builder-signing-sdk와 함께 통합 polymarket-client SDK로 대체되었습니다. Polymarket은 기존 연동을 옮기기 위한 마이그레이션 가이드를 공개합니다. 대부분의 튜토리얼과 AI 생성 코드는 통합 SDK보다 훨씬 이전에 나왔기 때문에 여전히 이전 패키지를 참조합니다.
- 트레이딩 봇에는 어떤 Polymarket Python 클라이언트를 써야 하나요?
- AsyncSecureClient를 사용하세요. 클라이언트는 네 가지입니다. 공개 데이터용 AsyncPublicClient와 PublicClient, 거래 및 계정 접근용 AsyncSecureClient와 SecureClient입니다. 실시간 구독은 비동기 전용이므로(동기 클라이언트는 subscribe()를 구현하지 않습니다) 오더북 업데이트를 스트리밍하는 봇에는 비동기 클라이언트가 필요합니다. 자격 증명을 도입하기 전에 AsyncPublicClient로 만들고 테스트하세요.
- Polymarket Python SDK에서 결과를 어떻게 페이지네이션하나요?
- 목록 메서드는 페이지네이터를 반환합니다. 페이지 단위로 제어하려면 페이지네이터를 직접 순회하고, 페이지 경계를 무시하고 개별 레코드를 순회하려면 iter_items()를 호출하고, 재개 가능한 수동 스캔에는 first_page()와 from_cursor()를 사용하세요. next_cursor 값은 불투명하므로 파싱하거나 직접 만들지 말고 그대로 저장하며, 첫 페이지부터 시작하려면 생략하세요.
- ChatGPT나 Claude가 동작하지 않는 Polymarket 코드를 생성하는 이유는 무엇인가요?
- 학습 데이터에 있는 Polymarket 코드의 압도적 다수가 통합 SDK 이전의 것이기 때문에, 모델은 py_clob_client import, ClobClient 생성, OrderArgs 객체를 만들어 내는 경향이 있습니다. 먼저 import 줄을 확인하세요. from polymarket import가 현재 방식이고, from py_clob_client는 아닙니다. Polymarket은 docs.polymarket.com/llms.txt에 기계가 읽을 수 있는 문서와 모든 페이지의 .md 버전을 공개하므로, 모델을 반복해서 고치는 것보다 현재 문서를 컨텍스트에 붙여 넣는 편이 효과적입니다.
- Polymarket SDK로 과거 오더북 데이터를 가져올 수 있나요?
- 아니요. SDK는 Polymarket API에 대한 인터페이스이므로 그 API가 갖고 있지 않은 데이터를 반환할 수 없습니다. 결과가 확정된 마켓의 메타데이터는 가져올 수 있지만, 오더북은 404를 반환하고 가격 기록은 약 1분에 한 포인트만 보관됩니다. 백테스팅에는 마켓이 진행되는 동안 서드파티가 기록한 특정 시점 스냅샷이 필요합니다.
Polymarket이 보관하지 않는 과거 데이터를 확보하세요
PolyTest는 Polymarket 암호화폐 Up/Down 마켓을 실시간으로 기록합니다. 8단계 오더북 깊이와 1초 미만 단위 타임스탬프를 갖춘 240M+개의 스냅샷을 제공하며, 결과가 확정된 마켓도 보존합니다. 3일 무료 체험으로 시작하세요.
더 읽어보기
Polymarket 트레이딩 봇 만드는 방법
대부분의 Polymarket 봇 튜토리얼은 더 이상 존재하지 않는 SDK를 기반으로 합니다. 이 글은 처음부터 끝까지 현재 기준의 방법을 다룹니다. 2026년에 무엇을 설치해야 하는지, 인증이 실제로 어떻게 동작하는지, 데이터 공백이 어디에 있는지, 그리고 첫 주에 봇을 죽이는 실패 유형까지.
Polymarket WebSocket: 끊기지 않는 실시간 데이터
오더북을 폴링하는 것은 아무 이득 없이 요청 한도를 소모하는 가장 흔한 방법입니다. 네 가지 스트림, 아무도 문서화하지 않은 구독 옵션, 그리고 봇이 무응답을 받고도 평온하다고 여기는 실패 유형을 설명합니다.
Polymarket API 지도: Gamma vs CLOB vs Data API
처음 시작하는 사람들은 같은 문제로 하루를 날립니다. Polymarket에는 API가 하나가 아니라 네 개 있고, 원하는 엔드포인트는 처음 시도한 API에 있는 경우가 드뭅니다. 이 글은 전체 지도입니다.