Polymarket Bot Tutorial · Chapter 25 of 32
Sports market bots on Polymarket: NFL weekly games, NBA tag (745) microstructure, soccer (Premier League, Bundesliga, Champions League), tennis (864) - liquidity, edge sources, code patterns.
What this chapter covers
NFL, NBA, Soccer, and Tennis are Polymarket's largest sports volumes by category. Each has its own data availability, cadence, and edge profile. This chapter covers the league-specific bot patterns and the tag IDs you'll filter on.
- NFL: weekly cadence, peak liquidity Sunday
- NBA (tag 745): in-game microstructure
- Soccer: international vs club leagues
- Tennis (tag 864): tournament cadence
- Edge sources that survive
- Live data: ESPN, official APIs
- Sample bot: pre-game line catcher
NFL: weekly cadence, peak liquidity Sunday
NFL has the strongest weekly rhythm of any Polymarket sport. Markets open Tuesday after the prior week's games, line-shop happens Wednesday-Friday, betting volume peaks Saturday-Sunday. Resolution typically Sunday night for early games, Monday night for the late one.
Bot pattern: line-catcher Tuesday-Wednesday when the opening line is set, in-play Sunday during peak volume. Different bots for each window. The Monday Night Football market often has thinner volume than other games - be aware it has higher slippage risk on small-size entries.
Volume peak is the Super Bowl: $50M+ traded across all SB markets the week of the game. Even a $100 bot in that week is irrelevant noise; the market is efficient at that scale.
NBA (tag 745): in-game microstructure
NBA is the highest-frequency sport on Polymarket - 25-30 games per week during the regular season, 5-15 in playoffs. Tag ID 745 filters to NBA-only events.
In-game microstructure works on NBA because: (1) ESPN updates scoreboards every ~10s, (2) games are 2.5 hours of continuous action, (3) Polymarket books for major games stay deep through the 4th quarter.
The strategy that works: subscribe to a game's WS book + ESPN feed, react to imbalance + score events in 10-15 seconds. Strategies that don't work: pre-game line catching (efficient enough that retail doesn't catch much), late-game certainty arbitrage (0.99-trap territory).
Soccer: international vs club leagues
Soccer breaks into three rough tiers on Polymarket.
- Top European leagues (EPL tag 739, La Liga, Bundesliga, Serie A) - moderate volume, deep books on big matches. Bot strategies similar to NBA.
- Champions League / Europa League (UCL tag 2186) - peak volume on knockout stages. Books are deepest on round-of-16 onward.
- International / smaller leagues (Saudi Pro League, MLS, J-League) - thin books, large spreads. Generally not bot territory.
Soccer's discrete scoring (0-1 goals are huge events) makes it different from NBA's continuous flow. The bot pattern for soccer is: be on the right side before a goal scores, exit fast after one fires.
Tennis (tag 864): tournament cadence
Tennis tag 864. ATP and WTA tours play 11 months of the year with the Grand Slams in Jan (Australian Open), May-Jun (French Open), Jul (Wimbledon), and Aug-Sep (US Open). Volume concentrates in those four weeks plus the Masters 1000 series.
Tennis has the cleanest in-play price ladders of any sport (chapter 15). Mid-match prices follow predictable curves keyed to set-and-break states. A bot with a tennis-specific price ladder model can detect mispricing in real time.
Quiet windows: between Grand Slams, weeks with only ATP 250 / ATP 500 tournaments, books are very thin. Pause the bot or shift to a different sport during these.
Edge sources that survive
Across all four sports, the edges that survive over time are:
- Pre-game line shop against a sharper venue's number (Pinnacle, Betfair). When Polymarket disagrees with a sharp book by > 3c, fade Polymarket.
- In-play overreaction to a single play (interception, injury, momentum shift). Wait 30-60 seconds after the play, fade if the market overshot.
- Late-game heavy favorites at 0.85-0.92 with risk-managed sizing. Below 0.85 = real risk; above 0.92 = the 0.99 trap.
Edges that don't survive: pure technical analysis on prices, sentiment scraping from Twitter, calendar-based seasonal effects.
Live data: ESPN, official APIs
Data source matrix for the four sports.
| 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 is free and reliable for all four. For sub-10s updates pay for a specialized feed (StatsPerform, GeniusSports) - but the marginal latency improvement rarely justifies the cost for retail.
Sample bot: pre-game line catcher
Reference: 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 require accounts; not free. Without a sharp reference, line-catching reduces to opinion vs opinion, which is not bot territory.





