Polymarket Bot Tutorial · 32개 중 15장

Polymarket의 sports microstructure bot: in-game edge, scoreline-driven mispricing, NBA tag (745)와 Tennis tag (864), live data sources, 그리고 고빈도 sports market을 위한 execution pattern.

이 장에서 다루는 내용

Sports market은 Polymarket에서 정치가 아닌 섹션 중 가장 꾸준히 활발한 영역입니다. 잘 작동하는 bot은 크게 두 가지로 나뉩니다. line이 설정된 뒤 한 번만 거래하는 pre-game line-catcher와, 경기 중 order book의 움직임에 반응하는 in-game microstructure bot입니다. 이 장에서는 각각에 적용되는 specific tag ID, data source, latency budget까지 함께 다룹니다.

Sports market은 Polymarket에서 정치가 아닌 섹션 중 가장 바쁜 영역입니다. 잘 작동하는 execution pattern은 live-score feed(ESPN, PandaScore)와 order-book microstructure signal을 결합합니다. 이 장에서는 특히 NFL, NBA, soccer, tennis에서 무엇이 작동하는지, 그리고 esports는 어떻게 다른지 다룹니다.

  • 왜 sports market은 tradeable한가
  • Pre-game vs in-game (서로 다른 bot)
  • 검증된 tag ID (745 NBA, 864 Tennis)
  • Data source: ESPN, official APIs, on-screen
  • In-game을 위한 latency budget
  • 0.99 / 0.01 trap
  • Code: games book에 subscribe하고 반응하기

왜 sports market은 tradeable한가

Sports market은 정의된 시간 범위(몇 시간에서 며칠) 안에 청산되고, public live data가 있으며, 경기 동안 지속적인 order flow를 끌어옵니다. 이 세 가지는 tradeable market에 모두 필요합니다. 정치 market에는 "defined timeframe"이 부족하고, weather market에는 "continuous flow"가 부족하며, 잘 알려지지 않은 tournament에는 "public live data"가 부족합니다.

Sports market의 trader 구성도 election market보다 더 다양합니다. 일반 sports bettor는 감정적으로 price를 매기고, informed trader는 경기 진행에 따라 fair value로 교정합니다. 이 둘 사이의 gap이 bot edge입니다.

Volume 분포는 고르지 않습니다. NFL Sunday에는 Polymarket sports market 전반에 걸쳐 수억 달러가 움직이지만, 화요일 밤 Saudi Pro League 경기는 5만 달러도 되지 않을 수 있습니다. 실제로 action이 있는 곳에 맞춰 strategy 규모를 정해야 합니다.

Pre-game vs in-game (서로 다른 bot)

근본적으로 서로 다른 두 가지 bot design이 있습니다.

Pre-game line-catcher: 방금 열린 market을 스캔하고, 모델이나 더 sharp한 venue의 숫자에 비해 잘못 price된 line을 찾아 FOK buy를 넣습니다. in-play까지, 때로는 resolution까지 보유합니다. Speed: 초가 아니라 분 단위. Edge: model + line-shopping.

In-game microstructure: live game의 order book WebSocket에 subscribe하고, imbalance signal + score event에 몇 초 안에 반응합니다. Speed: 분이 아니라 초 단위. Edge: latency + order flow 읽기.

두 방식은 거의 code를 공유하지 않습니다. risk profile도 다르고, data source도 다르고, exit strategy도 다릅니다. 둘 다 하려는 bot은 결국 둘 다 제대로 못합니다. 하나를 고르세요.

검증된 tag ID (745 NBA, 864 Tennis)

주요 sports category에 대해 2026년 5월 기준 production tag ID가 검증되었습니다. 이를 사용해 /events 호출을 효율적으로 필터링하세요.

Sport / LeagueTag IDTag slugNotes
NBA745nba10월~6월 최고 volume
NFL450nfl9월~2월 일요일/월요일 피크
Tennis (all)864tennis연중 운영, tournament cadence
Soccer (general)1059soccer아래 sub-tag와 함께 사용
EPL739epl
UCL2186uefa-champions-league
Esports (all)702esportsLoL+CS2+Valorant+Dota
MLB1245mlb4월~10월 피크
NHL823nhl10월~6월 피크

tag ID는 연도에 걸쳐 안정적입니다. 새로운 tag(Saudi Pro League, IPL)는 추가되지만, 기존 tag는 번호가 바뀌지 않습니다.

Data source: ESPN, official APIs, on-screen

전통적인 sports의 경우 무료 ESPN scoreboard API가 필요한 모든 것을 제공합니다: score, period/clock, win-probability, 때로는 shot location까지. key는 필요 없고 IP 수준에서만 rate limit이 있습니다. Endpoint pattern: https://site.api.espn.com/apis/site/v2/sports/<sport>/<league>/scoreboard.

Esports에는 ESPN coverage가 없습니다. 선택지는 다음과 같습니다: PandaScore($30-60/mo, 업계 표준), HLTV(CS2 전용, scrape 가능, API 없음), Liquipedia(커뮤니티 유지, scrape 가능, update cadence가 더 느림).

On-screen feed(TV stream을 구매하고 OCR로 scorebug를 읽는 방식)는 가능하지만 운영 부담이 큽니다. 실시간으로 API가 제공되지 않는 종목에서 3초 미만 update가 필요한 strategy가 있을 때만 권장합니다.

In-game latency budget

In-game reactive bot의 end-to-end latency budget입니다.

  • Score event 발생: t=0
  • Source feed에 반영: t+3-15초 (ESPN: 약 10초; PandaScore: 약 3초)
  • Bot이 feed를 읽음: t+10-16초
  • Bot이 action 결정: +50ms
  • FOK order 제출: +200-500ms
  • CLOB에서 체결: +300-1000ms (network + matching)

합계: 11-17초. 가장 빠른 professional firm은 premium feed 유료 구독과 co-located VPS를 통해 end-to-end 3-5초를 달성합니다. 표준 host와 무료 ESPN을 사용하는 retail bot은 더 느린 구간에 있습니다.

5초 미만이 필요한 strategy는 retail에게는 현실적이지 않습니다. 10-17초 창에서 작동하는 strategy는 다음과 같습니다: score 이후 line-catching, overreaction fading, late-game certainty play.

0.99 / 0.01 trap

가장 흔한 in-play sports bot 실패는 종료 1분 전 heavy favorite를 0.99에 사서 손쉽게 +1¢를 기대하는 것입니다. 실패하는 이유는 세 가지입니다.

첫째, underdog의 1% implied probability가 0은 아닙니다. 늦은 역전은 무시할 수 없는 빈도로 발생합니다. 99.5% 승리가 200번 반복되면, 풀 포지션 크기 기준으로 한 번은 손실이 납니다.

둘째, 0.99/0.01의 spread는 주당 99센트를 내고, 성공 시 1센트를 벌며, 드문 역전 시 99센트를 잃는 구조입니다. risk-reward가 매우 나쁩니다.

셋째, GTC sell을 0.999에 넣는 bot은 거의 체결되지 않습니다. 그 가격에는 buyer가 없습니다. 포지션은 resolution까지 이어집니다. 이기면 1센트를 벌고, 역전이 일어나면 99센트를 잃습니다.

이 trap은 수학을 제대로 돌리지 않은 builder가 실제 돈을 잃는 사례입니다. redemption-arbitrage profile에 맞게 설계된 strategy가 아니라면 0.95 이상의 price market에는 들어가지 마세요.

Code: games book에 subscribe하고 반응하기

Reference: 특정 NBA 경기의 WebSocket에 subscribe하고, book update를 기록하며, imbalance signal에서 FOK를 실행합니다.

import websocket, json
THRESHOLD = 0.5  # imbalance level to trigger

def on_message(ws, message):
    msg = json.loads(message)
    if msg.get("event_type") != "book": return
    bids = msg.get("bids", [])
    asks = msg.get("asks", [])
    bid_depth = sum(float(b["price"]) * float(b["size"]) for b in bids[:5])
    ask_depth = sum(float(a["price"]) * float(a["size"]) for a in asks[:5])
    total = bid_depth + ask_depth
    if total < 100: return  # too illiquid
    imb = (bid_depth - ask_depth) / total
    if abs(imb) > THRESHOLD:
        print(f"signal imb={imb:.2f} bid={bid_depth:.0f} ask={ask_depth:.0f}")
        # fire FOK here

ws = websocket.WebSocketApp(
    "wss://ws-subscriptions-clob.polymarket.com/ws/market",
    on_open=lambda ws: ws.send(json.dumps({"type":"Market","markets":["<CONDITION_ID>"]})),
    on_message=on_message
)
ws.run_forever()

production 추가 사항: 발동 사이의 cooldown, token별 inventory cap, stale book(30초 동안 메시지 없음)일 때 kill.

자주 묻는 질문

Polymarket에서 가장 활발한 sports tag는 무엇인가요?
NBA(tag_id 745), Tennis(tag_id 864), 그리고 soccer(competition에 따라 다름)가 시즌 동안 24시간 volume을 선도합니다. NFL은 정규 시즌과 playoffs 동안 매주 급등합니다. 우리는 production에서 NBA와 Tennis tag ID를 검증했습니다. 다른 tag는 의존하기 전에 gamma /tags endpoint로 확인해야 합니다.
In-game sports market에서 bot으로 수익을 낼 수 있나요?
가능성은 있지만 어렵습니다. edge는 분명 존재합니다(live scoreline이 30-90초 동안 자주 잘못 price됨). 하지만 다른 bot도 보고 있습니다. 우리가 본 가장 좋은 결과는 빠른 live-score data source와 단순한 rule("상대가 득점했는데 market이 아직 안 움직임, buy")를 결합했을 때 나왔습니다. data source 없는 pure stat-arb는 더 빠른 경쟁자에게 집니다.
Live sports data는 어디서 얻나요?
ESPN.com에는 live score를 반환하는 unofficial JSON endpoint가 있습니다. 많은 strategy에 충분히 좋습니다. Official API(NBA Stats API, NFL public endpoint)는 더 신뢰할 수 있지만 더 느립니다. Beat reporter의 Twitter account는 text를 제공하지만 LLM parsing이 필요합니다. 어느 것도 HFT-grade는 아니며, 모두 retail에겐 "충분히 빠른" 수준입니다.
0.99 / 0.01 trap이란 무엇인가요?
Sports market이 99센트 YES(매우 높은 승률)일 때는 남은 상승 여력이 거의 없고, 1센트 움직임이 수개월치 기대수익을 날릴 수 있습니다. 많은 bot이 마지막 1센트를 쫓아 0.99에서 매수했다가, 예상치 못한 이벤트로 price가 0.85까지 떨어질 때 크게 손해를 봅니다. hard rule: 기대값 계산이 완벽하게 입증되지 않는 한 약 0.95 이상에서는 매수하지 마세요.
Polymarket sports는 traditional sportsbook과 어떻게 비교되나요?
spread에는 house edge가 없습니다(FanDuel/DraftKings의 약 5-10% vig 대비). 하지만 liquidity가 더 얕고 spread가 더 넓을 수 있습니다. Polymarket은 traditional book이 underprice하는 이벤트에 강합니다 - 국제 tournament, esports, niche market. 주류 NFL/NBA에서는 traditional book이 더 liquid하지만 vig 비용이 더 듭니다.
제 bot이 여러 sports market을 동시에 거래할 수 있나요?
네, 그리고 그래야 합니다. Sports microstructure는 5-20개 동시 경기로 구성된 portfolio에서 가장 잘 작동합니다. 경기당 position cap(예: 50 USD), portfolio cap(예: 500 USD), 그리고 경기 간 비상관 exposure를 두세요. 한 경기만 집중하면 variance만 커집니다.