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) -> strRegister 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.DataFrameThe bets one configuration places, in decision order: event_id, market, cost, pnl.
Functions
book_fight_cap
book_fight_cap(cap: str | float) -> float | NoneThe Book’s fight cap as a share of bankroll; None for ‘conf’ (the per-bet cap).