betting_combat.rounds.backtest.fills
Fills from the trade tape: only what is knowable when the order goes out, plus the market’s
move while the order travels (research ufc/modeling/execution.py::tape_fills — the version
fixed 2026-09-29 — and ufc/modeling/capacity.py::_arrival / _poly).
arrival price the worse of the decision price and every print on our side between the decision (t, exclusive) and the order's arrival (t + latency, inclusive)filled if the arrival price is within the limit (decision price + cushion); paid at the arrival price; else missedsize cap a share of the dollars traded in that market in the window BEFORE the decision ([t - window, t)); nothing after the decision decides whether or how much we fillTapes. Kalshi: columns fight_id, market, ts, yes_price, dollars, taker (taker ‘yes’ / ‘no’
= the side that crossed). Polymarket: fight_id, kind, ts, yes_price, dollars, yes_dir
(+1 = a YES-buying print, -1 = YES-selling). ts and the events’ t_entry are tz-aware
timestamps on the same clock.
Parity notes (the numbers depend on these, so they are kept as the research had them):
tape_fillsputs each Kalshi tape in (ts, trade_id) order (trades.time_order; a tape withouttrade_id: stable by ts) before summing the window dollars;capacity.instrumentssums in the tape’s own row order (the trade tables are already in (fight_id, ts, trade_id) order, so the two agree).tape_fillsaccepts an arrival up to 1e-9 above the limit (float noise in cents);capacity.instrumentsand the Polymarket rule compare with no tolerance.
Functions
arrival_price
arrival_price(tape: pd.DataFrame | None, t: pd.Timestamp, side_buys_yes: bool, entry: float, latency_s: float, price_col: str = 'yes_price', dir_col: str | None = None) -> floatThe price the order meets on arrival (research capacity._arrival; the same rule
inlined in execution.tape_fills): the worse (higher, in our side’s terms) of entry
and every print on our side in (t, t + latency]. Kalshi prints are on our side when their
taker is our side; Polymarket prints (dir_col) when their direction is ours. A NO
price is 1 - the YES print.
kalshi_tapes
kalshi_tapes(trades: pd.DataFrame, sort_by_ts: bool) -> dict[tuple[str, str], pd.DataFrame]The Kalshi tape split by (fight_id, market), the key columns as strings (research:
astype(str) on fight_id, market, taker); trade_id kept when the tape has it.
sort_by_ts: tape_fills puts each tape in time order (trades.time_order: ties by
trade_id); capacity.instruments keeps the tape’s row order.
polymarket_instrument
polymarket_instrument(bet: Any, kalshi_entry: float, tape: pd.DataFrame | None, t: pd.Timestamp, side_buys_yes: bool, inst: str, config: BacktestConfig) -> dict[str, Any] | NoneOne Polymarket instrument row for a bet (research capacity._poly), or None.
Quote = the last print on our side in [t - window, t) (the tape’s row order); a quote
more than config.stale from Kalshi’s price for the same event (kalshi_entry) is
stale and skipped. Filled at the arrival price if within quote + cushion. Fee 0 unless
config.poly_fee_as_kalshi.
polymarket_tapes
polymarket_tapes(poly_trades: pd.DataFrame | None) -> dict[tuple[str, str], pd.DataFrame]The Polymarket tape split by (fight_id, kind), in the tape’s row order; {} if none.
rounds_tape_market
rounds_tape_market(market: str, round_idx: int) -> strThe Kalshi tape a round-system bet fills on: ‘ends this round’ at the start of round
round_idx + 1 is the rounds market ‘ends before round round_idx + 2’; everything else
fills on the distance market.
tape_fills
tape_fills(events: pd.DataFrame, trades: pd.DataFrame, config: BacktestConfig = BacktestConfig(), tape_market: Callable[[str, int], str] = rounds_tape_market) -> pd.DataFramePer event (index idx = the event’s index label): window_dollars (the market’s $
in the window before t) and, per (latency, cushion) in the config’s grid,
avail_{lat}_{cush} (1.0 filled / 0.0 missed) and vwap_{lat}_{cush} (the arrival
price paid, NaN if missed; one price, the name is the research’s).
events needs fight_id, round_idx, market, t_entry, entry, side; entry is the
decision price on the bet’s side (YES: the ask; NO: 1 - the bid).
window_dollars
window_dollars(tape: pd.DataFrame | None, t: pd.Timestamp, minutes: float) -> floatDollars traded on the tape in [t - minutes, t); 0 without a tape.