Skip to content

Optional live-tennis match-state as a data source for tennis event markets (data-feed, not a venue) #13

Description

@bensynapse

Disclosure: I run the Live Tennis API — judge this on the merits. No affiliation with PolyClaw; this is a data-source suggestion, not a request.

Where this fits in PolyClaw today

PolyClaw's whole loop is driven off market price and market question text:

  • Browsescripts/markets.pyGammaClient.get_trending_markets / search_markets returns each Market with yes_price, no_price, and volume.
  • Positionsscripts/positions.py tracks entry price vs current price for P&L. It knows the price moved; it doesn't know why.
  • Hedgescripts/hedge.py runs IMPLICATION_PROMPT over the trending set and derives covering portfolios from logically-necessary implications (the contrapositive/direct covers in derive_covers_from_implications), tiered by coverage.

For tennis event markets (match-winner, set-winner, "reach N games", etc.) there's a signal PolyClaw currently has no input for: the live state of the underlying match. A market can move — or become resolvable — because a break point was converted, a set closed, or a player retired, well before that's fully reflected in price. Right now the agent can only infer that indirectly from no_price/yes_price.

The suggestion — a read-only enrichment, not an execution path

Add an optional live-match-state lookup for tennis markets. It is strictly a data feed: it does not browse, price, sign, or execute anything. PolyClaw keeps its exact Gamma + CLOB split/execute path untouched. The feed only answers "what is the underlying match doing right now" for a market you already found:

  • score — sets / games / points / who is serving
  • break-point flag — three-valued: TRUE / FALSE / UNDEF (receiver at AD or 40 vs server on 0/15/30; never flagged inside a tiebreak; UNDEF when points are null)
  • terminal statuscompleted / retirement / walkover — the states that determine how a tennis market resolves

Concretely, this slots in two natural places:

  1. Position tracking — alongside price-based P&L in scripts/positions.py, surface the live match state for a tennis position, so a retirement/walkover/completed terminal flag is visible next to the number rather than inferred from a price jump.
  2. Hedge context — the hedge scan covers between, say, a match-winner market and a set-winner market are logically related; live score/terminal-state is the ground truth that tells you whether that logical cover is still live.

Player-name matching keys off the market question (same text markets.py already carries), so it stays a thin, side-car lookup.

What it is

  • Free tier (live scores + match-state + players with ranking/Elo + fixtures), 30/min · 100/day, no card: https://livetennisapi.com/subscribe/free
  • Base https://api.livetennisapi.com/api/public/v1, X-API-Key header, {data:[...]}players.p1.name/p2.name, status, a score object (sets/games/points/server), id.
  • Coverage runs ATP/WTA/Challenger/ITF/juniors — strongest on deep draws where generic feeds thin out, which is where in-play tennis markets are least efficient.
  • MIT observe-only reference toolkit (no keys, no trading): https://github.com/livetennisapi/polymarket-tennis
  • Also on the official MCP Registry as io.github.livetennisapi/livetennisapi-mcp if you'd rather wire it as an MCP tool than a subprocess.

If this is interesting I'm happy to open a small PR adding an optional tennis-state lookup that reads a market's question and returns the state block — behind its own flag, no change to the split/CLOB path, no new required env var. Equally fine if it's out of scope; wanted to offer the feed since the browse→positions→hedge loop is otherwise blind to what the actual match is doing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions