Skip to content

betting_combat.services.rounds_frames

Strategy 4’s research frames rebuilt from the store: the round datasets, the fight clock, the market list, the minute panel (Set 4), the trade tables and the market windows (Set 3) — everything the weekly refit trains on and the forward check replays. Research build order (tests/fixtures/make_round_references.py: RoundDataset -> LiveSets -> trades -> Set3); every step is the ported library’s (rounds.features, rounds.market):

tables services.rounds_inputs.history_tables (the mirror, Wikipedia, MMADecisions,
the static files, fights_kalshi)
datasets RoundDataset(RawData(tables)).build(model_features=<cache or None>)
clock FightClock(distance minutes); fights = live_fights(fight_ids(build_fights(
fights_kalshi, winner markets, UFCStats), bouts), winner minutes, clock,
Dataset 1 keys, a_slot)
markets market_list(fights, the side series, distance)
set4 set4_minutes(fights, markets, every series' minutes, {}, a_slot)
trades trade_tables(fights, markets, tapes): the research-seeded tapes as pulled, the
production tapes cut to the design window (``design_trade_windows``)
set3 set3_main / set3_side on the trade tables and Set 4, keyed on Dataset 1;
side rows without a complete core dropped (``drop_unpriceable``)

Two research inputs are left out, neither a model input: Group 6 (the dataset’s kalshi_* / poly_* columns at each round break, evaluation only) and Polymarket’s price history (Set 4’s poly_win_a; strategy 4 trades Kalshi only).

Classes

Frames

Sources

The store’s inputs as the research read them from its files.

Functions

build_clock

build_clock(sources: Sources, raw: RawData, keys: pd.DataFrame, a_slot: Mapping[str, int]) -> tuple[pd.DataFrame, pd.DataFrame]

(fights, markets): the Kalshi fight clock of the dataset’s fights and their markets.

build_datasets

build_datasets(tables: UfcTables, model_features: pd.DataFrame | None = None) -> tuple[RawData, dict[str, pd.DataFrame]]

(RawData, RoundDataset.build) without Group 6. model_features: a Group 5 cache (rows it lacks are fitted; None fits every year, several minutes).

build_frames

build_frames(store: RoundsStore, tables: UfcTables, model_features: pd.DataFrame | None = None, clock_years: Sequence[int] = (), cached: bool = True, reuse: bool = True, now: Callable[[], dt.datetime] = lambda: dt.datetime.now(dt.UTC), guard: Callable[[Frames], None] | None = None) -> Frames

Every frame from the store (see the module doc), through the caches (services.rounds_cache): Group 5 from the cached years’ fits (each year fitted once), the market frames of every fight whose inputs did not change read back, the others built a few cards at a time. cached=False: the same computation, nothing read from or written to the caches. reuse=False (with cached): nothing read from the caches, every fight rebuilt and every year refitted, and all of it written to them (a full rebuild). model_features: a Group 5 table given whole (the research’s cache; the known-answer tests), instead of the clock cache. clock_years: years whose fit is wanted though no row is in them yet (the refit’s cutoff year). guard: run on the built frames BEFORE either cache is written; when it raises, nothing is written (the refit’s cutoff refusal).

build_market_sets

build_market_sets(sources: Sources, fights: pd.DataFrame, markets: pd.DataFrame, tapes: Mapping[str, list[list[Any]]], keys: pd.DataFrame, a_slot: Mapping[str, int]) -> dict[str, Any]

Set 4, the trade tables and Set 3 (main; side without the unpriceable rows).

last_trades_used

last_trades_used(store: RoundsStore, fights: pd.DataFrame, markets: pd.DataFrame, pulls: Sequence[Mapping[str, Any]]) -> pd.DataFrame

Per fight, the last trade its frames read (fight_id, event_date, last_trade_at): over its markets, the latest trade of each tape exactly as load_tapes serves it — a research-seeded tape as the research had it, any other cut to the design window. A fight none of whose markets has a trade there is absent.

load_sources

load_sources(store: RoundsStore, tables: UfcTables, minutes: Sequence[str] = (WINNER, DISTANCE)) -> Sources

Every series’ markets, and the minute candles of minutes (default: the winner and distance series, which the fight clock reads whole; the side series’ are read per fight), each cut to the research’s window (rounds_windows.minute_windows), beside tables.

load_tapes

load_tapes(store: RoundsStore, fights: pd.DataFrame, markets: pd.DataFrame) -> dict[str, list[list[Any]]]

Every market’s trade tape: a research-seeded tape as the research had it (its seeded trades, whatever a later pull added), a production tape cut to the research’s design window out of the market’s full raw trades.

side_minutes

side_minutes(store: RoundsStore, tickers: Sequence[str], windows: Mapping[str, Window | None] | None = None) -> list[dict[str, list[dict[str, Any]]]]

The side series’ candles of tickers (all_candles’ last argument), cut to the research’s windows (windows, else read for them).