Skip to content

betting_combat.rounds.backtest.book

The execution backtest’s book: events in time order as plain arrays, so one configuration (sizing rule, edge threshold, fight cap, volume share, latency, cushion) backtests in milliseconds (research ufc/modeling/execution.py::Book).

SIZING (stake before caps, in $; bankroll fixed, not compounded; Kelly = (p - cost) / (1 - cost) of bankroll, floored at 0, with p = our probability for the bet’s side and cost = entry + fee) flat_meta 1 % of bankroll if meta >= 0.5 meta_afml 2.5 % x AFML size (2 N(z) - 1 from the meta probability) kelly_0.10/0.25 0.10 / 0.25 x Kelly if meta >= 0.5 kelly_x_meta 0.25 x Kelly x AFML size kelly_meta_p 0.25 x Kelly with p = the meta probability flat_nometa 1 % of bankroll, every bet kelly_0.25_nometa 0.25 x Kelly, every bet

CAPS, per bet in decision order (stop.decision_order; first come, first served) skip a pre-fight event (round_idx 0) unless config.trade_round0 skip if edge < threshold, nothing wanted, not filled at this (latency, cushion) skip if the card’s SETTLED P&L <= -daily_stop x bankroll (stop.SettledStop) room = min(fight cap - staked on the fight, card cap - staked on the card); skip if <= 0 fight cap: a share of bankroll, or ‘conf’ = 5 % x this bet’s own AFML meta size dollars = min(wanted, room, volume share x the window’s $, max_bet x bankroll) contracts = dollars / price; skip under one contract; cost = contracts x (price + fee)

Classes

Book

events needs t_entry, t_end, fight_id, round_idx, side, event_id, market, edge, won, meta, p_side, cost; fills is tape_fills on the same events (indexed by the events’ index).

add_sizing

add_sizing(sizing: str, kelly: float) -> str

Register the want of the live engine’s sizing (rounds.live.decision.wanted, vectorised, in its order of operations): kelly x Kelly x the meta factor x bankroll, the factor the AFML size (‘kelly_x_meta’) or 1 when meta >= 0.5 else 0 (‘kelly_meta_filter’). Returns its rule name for run. At kelly 0.25 / 0.10 / 0.25 it is the grid’s ‘kelly_x_meta’ / ‘kelly_0.10’ / ‘kelly_0.25’ want exactly.

run

run(rule: str, edge: float, cap: str | float, vol: float, lat: int, cush: float) -> pd.DataFrame

The bets one configuration places, in decision order: event_id, market, cost, pnl.

Functions

book_fight_cap

book_fight_cap(cap: str | float) -> float | None

The Book’s fight cap as a share of bankroll; None for ‘conf’ (the per-bet cap).