Polymarket Bot Tutorial · 32장 중 25장
Polymarket의 sports market bots: NFL 주간 경기, NBA tag (745) microstructure, soccer (Premier League, Bundesliga, Champions League), tennis (864) - liquidity, edge sources, code patterns.
이 장에서 다루는 내용
NFL, NBA, Soccer, Tennis는 카테고리별로 Polymarket에서 가장 큰 sports volume을 차지합니다. 각 종목은 data availability, cadence, edge profile이 다릅니다. 이 장에서는 리그별 bot pattern과 필터링할 tag ID를 다룹니다.
- NFL: weekly cadence, peak liquidity Sunday
- NBA (tag 745): in-game microstructure
- Soccer: international vs club leagues
- Tennis (tag 864): tournament cadence
- 지속되는 edge sources
- Live data: ESPN, official APIs
- Sample bot: pre-game line catcher
NFL: weekly cadence, peak liquidity Sunday
NFL은 Polymarket에서 가장 뚜렷한 weekly rhythm을 보이는 sports입니다. 시장은 이전 주 경기 다음 날인 화요일에 열리고, Wednesday-Friday에 line shopping이 진행되며, betting volume은 토요일-일요일에 정점에 도달합니다. Resolution은 보통 이른 경기의 경우 일요일 밤, 늦은 경기는 월요일 밤에 이뤄집니다.
Bot pattern: 개장 line이 잡히는 화요일-수요일에는 line-catcher, 일요일 peak volume에는 in-play. 각 시간대마다 다른 bot을 사용합니다. Monday Night Football 시장은 다른 경기보다 volume이 얕은 경우가 많으므로, 소액 진입에서도 slippage risk가 더 높다는 점에 유의하세요.
volume peak는 Super Bowl입니다: 경기 주간에 모든 SB market을 합쳐 $50M+가 거래됩니다. 그 주의 $100 bot은 시장에 사실상 무시할 만한 noise에 불과하며, 그 규모에서는 시장이 효율적입니다.
NBA (tag 745): in-game microstructure
NBA는 Polymarket에서 가장 고빈도인 sports입니다. regular season 동안 주당 25-30경기, playoffs에서는 5-15경기가 열립니다. Tag ID 745는 NBA-only 이벤트를 필터링합니다.
NBA에서 in-game microstructure가 작동하는 이유는 다음과 같습니다. (1) ESPN이 scoreboard를 약 10초마다 갱신하고, (2) 경기가 2.5시간 동안 연속적으로 진행되며, (3) 주요 경기의 Polymarket book이 4쿼터까지도 깊이를 유지하기 때문입니다.
작동하는 전략: 게임의 WS book + ESPN feed를 구독하고, 10-15초 안에 imbalance + score event에 반응합니다. 작동하지 않는 전략: pre-game line catching(충분히 효율적이라 retail이 크게 포착하지 못함), late-game certainty arbitrage(0.99-trap 영역).
Soccer: international vs club leagues
Soccer는 Polymarket에서 대략 세 가지 tier로 나뉩니다.
- Top European leagues (EPL tag 739, La Liga, Bundesliga, Serie A)-moderate volume, big match에서는 deep book. Bot strategy는 NBA와 유사합니다.
- Champions League / Europa League (UCL tag 2186)-knockout stage에서 peak volume. Round of 16 이후 book이 가장 깊습니다.
- International / smaller leagues (Saudi Pro League, MLS, J-League)-얕은 book, 큰 spread. 일반적으로 bot 대상이 아닙니다.
Soccer는 득점이 이산적이라는 점(0-1 goals가 큰 이벤트) 때문에 NBA의 연속적인 흐름과 다릅니다. Soccer의 bot pattern은 goal이 나오기 전에 올바른 쪽에 서 있고, goal이 터진 뒤에는 빠르게 빠져나오는 것입니다.
Tennis (tag 864): tournament cadence
Tennis tag 864. ATP와 WTA 투어는 1년 중 11개월 동안 진행되며, Grand Slams는 1월(Australian Open), 5-6월(French Open), 7월(Wimbledon), 8-9월(US Open)에 열립니다. volume은 이 네 주와 Masters 1000 series에 집중됩니다.
Tennis는 어떤 sport보다도 in-play price ladder가 가장 깔끔합니다(15장). 경기 중 가격은 set과 break 상태에 따라 예측 가능한 곡선을 따릅니다. tennis-specific price ladder model을 가진 bot은 실시간으로 mispricing을 감지할 수 있습니다.
조용한 구간: Grand Slam 사이, ATP 250 / ATP 500 tournament만 열리는 주에는 book이 매우 얕습니다. 이 기간에는 bot을 잠시 멈추거나 다른 sport로 전환하세요.
지속되는 edge sources
네 가지 sports 전반에서 시간이 지나도 유지되는 edge는 다음과 같습니다.
- Pre-game line shop을 sharper venue의 수치(Pinnacle, Betfair)와 비교하는 것. Polymarket이 sharp book과 3c 이상 어긋나면 Polymarket에 반대 방향으로 베팅하세요.
- In-play overreaction을 단일 play(interception, injury, momentum shift)에 대해 노리는 것. play 이후 30-60초 기다렸다가 market이 과하게 반응했으면 반대로 들어가세요.
- Late-game heavy favorites at 0.85-0.92를 risk-managed sizing으로 다루는 것. 0.85 아래는 실제 risk, 0.92 위는 0.99 trap입니다.
지속되지 않는 edge: 가격에 대한 순수 technical analysis, Twitter에서 sentiment scraping, 캘린더 기반 seasonal effect.
Live data: ESPN, official APIs
네 가지 sports에 대한 data source matrix입니다.
| Sport | Primary | Backup | Update cadence |
|---|---|---|---|
| NFL | ESPN scoreboard | NFL.com feed | ~10s during play |
| NBA | ESPN scoreboard | stats.nba.com | ~10s during play |
| Soccer (EPL/UCL) | ESPN scoreboard | SofaScore | ~15-30s |
| Tennis (ATP/WTA) | ESPN scoreboard | tennis.com live | ~30s (point-level) |
ESPN은 네 종목 모두에서 무료이며 신뢰할 수 있습니다. 10초 미만 업데이트가 필요하다면 전문 feed(StatsPerform, GeniusSports)를 구입하세요. 다만 소매 사용자에게는 미세한 latency 개선이 비용을 정당화하지 못하는 경우가 많습니다.
Sample bot: pre-game line catcher
참고용: pre-game line-catcher pseudocode.
def line_catcher():
# Find games starting in the next 2-12 hours
events = gamma_events(tag_id=745, hours_ahead=12)
for ev in events:
for m in ev["markets"]:
polymarket_prob = float(json.loads(m["outcomePrices"])[0])
sharp_prob = fetch_pinnacle_implied(ev["slug"]) # 3rd-party feed
if sharp_prob - polymarket_prob > 0.04:
# Polymarket has the YES side cheap vs sharp
tok = json.loads(m["clobTokenIds"])[0]
place_fok(tok, "BUY", polymarket_prob + 0.01, size=10)
elif polymarket_prob - sharp_prob > 0.04:
# Polymarket has the NO side cheap vs sharp
tok = json.loads(m["clobTokenIds"])[1]
place_fok(tok, "BUY", 1 - polymarket_prob + 0.01, size=10)
Caveats: Pinnacle / Betfair APIs는 계정이 필요하며 무료가 아닙니다. sharp reference가 없으면 line-catching은 의견 대 의견 비교로 전락하며, 이는 bot territory가 아닙니다.





