betting_combat.rounds.market.breaks
Group 6 of the round dataset: Kalshi and Polymarket prices at each round start.
Ported from the research (ufc/dataset/markets.py: KalshiBreaks, _swap,
poly_breaks; the fights KalshiBreaks.method_prices takes from ufc/joint.py
contexts). Rows are (fight_id, round_idx) like the dataset’s, A-framed. The row time for
round_idx r is the last completed minute at start + 6r minutes (the end of the break); for
round_idx 0 the minute before the start. A fight’s rows stop at the first row time missing
from its minute frame (no cut at the winner market’s snap, which is only known afterwards; the
dataset keeps the rounds that started).
kalshi_timing how the clock was anchored (finish_anchor / bell_anchor / break_template)kalshi_p_a A's win probability: the mean of A's mid and 1 - B's midkalshi_bid_a / kalshi_ask_a / kalshi_spread_a A's winner bookkalshi_vol5 winner contracts traded in the 5 minutes to the row timekalshi_p_dec the distance market's mid (2026 on)kalshi_mov_* method-of-victory mids, A-framed (2026 on)poly_p_a Polymarket's price for A (a print within 5 minutes)Functions
kalshi_breaks
kalshi_breaks(fights: pd.DataFrame, winner_minutes: Mapping[str, list[dict[str, Any]]], clock: FightClock, a_slot: Mapping[str, int], extra: Mapping[str, Mapping[str, pd.DataFrame]]) -> tuple[pd.DataFrame, dict[str, pd.Timestamp]]Kalshi’s prices at each round start (research KalshiBreaks.build).
Returns the rows (:data:KALSHI_COLUMNS; a fight Kalshi listed twice appears twice, the
caller keeps the first) and fight_id -> start (a fight listed twice keeps its LAST
listing’s start, as the research’s starts).
Args:
fights: :func:~.listing.fight_ids rows.
winner_minutes: the winner markets’ 1-minute candles by ticker.
clock: the fight clock.
a_slot: fight_id -> the UFCStats slot (1 or 2) of fighter A; a fight missing from it is
framed as if fighter A were slot 2.
extra: :func:method_prices.
method_prices
method_prices(fights: pd.DataFrame, winner_minutes: Mapping[str, list[dict[str, Any]]], side_minutes: Mapping[str, list[dict[str, Any]]], mov: Iterable[Mapping[str, Any]], mof: Iterable[Mapping[str, Any]], rounds_: Iterable[Mapping[str, Any]], vic: Iterable[Mapping[str, Any]], distance: Iterable[Mapping[str, Any]], clock: FightClock) -> dict[str, dict[str, pd.DataFrame]]event_ticker -> {name: minute frame} for the distance and the six method-of-victory
markets (Kalshi-A-framed names), for the fights the joint model priced: 2026 cards whose
six MOV minute frames all cover the minute 3 minutes before the start (research
KalshiBreaks.method_prices over joint.contexts; the joint model’s finish curves,
which filter nothing, are not built).
Args:
fights: :func:~.timing.build_fights rows.
winner_minutes: the winner markets’ 1-minute candles by ticker.
side_minutes: the side and distance markets’ candles by ticker, merged in the
research’s order (KXUFCMOV, KXUFCMOF, KXUFCROUNDS, KXUFCVICROUND, distance).
mov, mof, rounds_, vic: the KXUFCMOV, KXUFCMOF, KXUFCROUNDS, KXUFCVICROUND markets.
distance: the KXUFCDISTANCE markets.
clock: the fight clock.
poly_breaks
poly_breaks(kalshi_rows: pd.DataFrame, starts: Mapping[str, pd.Timestamp], history: Mapping[str, Any], a_slot: Mapping[str, int]) -> pd.DataFramePolymarket’s price for A at the Kalshi rows’ minutes (research poly_breaks): the
last print at or before the row time, if within 5 minutes.
Args:
kalshi_rows: :func:kalshi_breaks rows (fight_id, round_idx).
starts: :func:kalshi_breaks starts.
history: Polymarket price histories by fight_id (polymarket_ufc.json’s
history; a fight missing or None has no price).
a_slot: fight_id -> the UFCStats slot (1 or 2) of fighter A.
row_time
row_time(start: pd.Timestamp, round_idx: int) -> pd.TimestampThe row’s minute: the minute before the start (round_idx 0), else the end of the break
before round round_idx + 1.
swap_mov
swap_mov(name: str) -> strmov_a_ko <-> mov_b_ko when Kalshi’s fighter A is our B.