Skip to content

betting_combat.rounds.live.upcoming

Dataset 1 feature rows for an UPCOMING card, before any of its fights has a result.

The training build (features.RoundDataset.build) keeps only fights with a result (it needs the targets) and fits the clock every year from scratch. A card about to be traded has no results, so this assembles the same feature columns with the training code itself:

UfcTables + UpcomingCard ─► with_upcoming ─► RawData ─► build_upcoming(raw, fights, clock)
  • the card’s bouts join the UFCStats tables as result-less rows (with_upcoming): every as-of feature (fighter history, matchup, context, odds) is computed from strictly earlier dates exactly as in training;
  • the style records (StyleSimilarity) count the card’s bouts as result-less records on their date (pending): a training row reads its pair’s record through a row of its own date, which only exists once the bout is recorded; without it an upcoming bout would miss the previous card’s fights;
  • Group 5 (the clock) comes from the year’s LOCKED models (features.ClockYear, fitted on the fights before 1 January with seed = the year), as the training cache has them;
  • one row per scheduled round start (round_idx 0 .. R-1): which rounds happen is not known.

Nothing here reads a result: the rows carry no y_* column and no live-market (group 6) column. tests/parity/test_rounds_live.py rebuilds the 2026-09-26 card this way from inputs with its results removed and compares it with the training rows.

Classes

UpcomingCard

One card before it starts, as the data layer supplies it.

event UFCStats’ event name (ufcstats_ufc_event_details.EVENT) event_url its UFCStats URL (.../event-details/<event_id>) date the card’s date (UFCStats’ date, the US date of the card) location ‘City, State, Country’ as UFCStats writes it bouts one row per bout in UFCStats’ card order (main event first): fight_url (.../fight-details/<fight_id>), name_1 / name_2 (UFCStats’ order), weight_class (UFCStats’ text, e.g. ‘Lightweight Bout’, “Women’s Strawweight Bout”, ‘UFC Lightweight Title Bout’), rounds (3 or 5) kalshi the Kalshi card-start quotes in fights_kalshi form (date, fighter_a, fighter_b, card_prob_a, card_quote_ok): the pre-fight price p_mkt_a where no sportsbook line exists (card_quote) segments Wikipedia’s card segments in card_segments form (date, fighter_1, fighter_2, segment), or None excluded the bouts the loader refused (services.rounds_upcoming): event_ticker (the Kalshi fight, None for a Wikipedia bout without one), bout (the names), reason; the engine must not trade any of them. None: not known

Functions

build_upcoming

build_upcoming(raw: RawData, fight_ids: list[str], clock: ClockYear) -> pd.DataFrame

Dataset 1’s feature columns (keys, context, both profiles, matchup, odds, the clock) for every scheduled round start of the upcoming bouts fight_ids (in raw, without results), in the training table’s column order without targets and live markets.

clock: the card year’s locked Group 5 models.

card_quote

card_quote(bid_a: float, ask_a: float, bid_b: float, ask_b: float) -> tuple[float, bool]

(card_prob_a, card_quote_ok) from the two winner books, the research’s card-start rule (ufc/pull.py): each side’s mid, normalised across the two books; a quote at the extremes (a result already known) or with a side missing is not ok.

upcoming_ids

upcoming_ids(card: UpcomingCard) -> list[str]

The card’s UFCStats fight ids, in card order.

with_upcoming

with_upcoming(tables: UfcTables, card: UpcomingCard) -> UfcTables

tables with the card’s bouts added as result-less rows (and its quotes and segments). Refuses a card whose bouts are already in the tables, or tables holding any result on or after the card’s date: every input must predate the card.