Skip to content

betting_combat.services.rounds_dashboards

Rows for strategy 4’s diagnostics tables (store.rounds_dashboards; contract: ROUND_SYSTEM_FLOW.md §9), shaped from what each writer already holds. Pure: no IO.

card run decision_rows (one row per decision x market, from the decision's legs),
card_limits_row (the money settings the card runs under)
weekly refit layer_scores, auc, calibration_rows, importance_rows, fold_rows,
path_row, uniqueness_summary
forward job forward_rows (live vs research replay, bet by bet)
health job csw_cusum (the same statistic as the view ``rounds_edge_cusum``)

Functions

auc

auc(y: Any, p: Any) -> float

The area under the ROC curve (Mann-Whitney; ties count half).

brier

brier(y: Any, p: Any) -> float

calibration_rows

calibration_rows(version: int, source: str, model: str, y: Any, p: Any, n_bins: int = 10) -> list[dict[str, Any]]

Equal-width reliability bins over [0, 1] (bin i holds i/n <= p < (i+1)/n; p = 1 in the last); every bin is a row, an empty one with n = 0.

card_limits_row

card_limits_row(s: Settings | None, card_id: str, card_date: dt.date, session_id: str, mode: Literal['paper', 'live', 'shadow'], as_of: dt.datetime, card_name: str | None = None, portfolio: Any | None = None, live_cash_cap_usd: float | None = None, ids: Mapping[str, str] = IDS) -> dict[str, Any]

The money controls a card runs under, written whenever they or the mode change — ALWAYS, also with no card cap, no stop loss or no sizing bankroll (the dashboards resolve every decision’s mode from these rows).

s: the decision’s settings (settings_of: the controls in dollars; None without a sizing bankroll). portfolio: the portfolio row, for the controls as set (card_risk / card_risk_type, stop_loss / stop_loss_type); its dollars must equal s’s. live_cash_cap_usd: live, the Kalshi cash capping the sends. The first draft’s columns are written as mirrors (card_budget_usd = cash_limit_usd = card_risk_usd with card_loss_pct 1, daily_stop_usd = stop_loss_usd), NULL with them.

csw_cusum

csw_cusum(x: Iterable[float], b_alpha: float = B_ALPHA) -> list[dict[str, Any]]

The one-sided Chu-Stinchcombe-White CUSUM (AFML 17.3.2) with a FIXED start (the first residual given: the start of monitoring), exactly as the view rounds_edge_cusum computes it within one segment: y_t = x_1 + … + x_t, sigma_t^2 = mean of x_i^2 up to t, S_t = -y_t / (sigma_t sqrt t), c_t = sqrt(b_alpha + ln t), stat_ratio = S_t / c_t, alarm = stat_ratio > 1, alarmed = any alarm so far. (A start that moves with t — the max over n — false-alarms on a calibrated model most of the time over a few hundred bets.)

decision_rows

decision_rows(record: DecisionRecord, round_idx: int, session_id: str, mode: Literal['paper', 'live'], fight: str | None = None, card_name: str | None = None, pair_draw_share: float = DRAW_SHARE, ids: Mapping[str, str] = IDS) -> list[dict[str, Any]]

One row per candidate bet of a rounds decision (its legs); a decision without candidates (no model, stale feed, …) has none — decision_log holds it.

fold_rows

fold_rows(version: int, target: str, kept: Sequence[Sequence[str]]) -> list[dict[str, Any]]

kept[fold]: the features forward selection kept in that outer fold, in the order it chose them.

forward_rows

forward_rows(live: Mapping[tuple[str, int, str], Mapping[str, Any]], replay: Mapping[tuple[str, int, str], Mapping[str, Any]], card_id: str, card_date: dt.date, mode: Literal['paper', 'live', 'shadow'], checked_at: dt.datetime, model_version: int | None, fights: Mapping[str, str] | None = None, tol: float = 1e-09, ids: Mapping[str, str] = IDS) -> list[dict[str, Any]]

Every bet of a card, keyed (fight_id, round_idx, market), as the live run made it and as the research code replays it, for the live run’s mode. Each side’s dict: side, p_side, edge, meta, entry, intended, contracts, avg_price (and live: decision_id). A mismatch is any decision field in COMPARED differing (numbers by more than tol); fills are not compared (the replay’s are tape-simulated — the Performance dashboard sets them side by side).

importance_rows

importance_rows(version: int, model: str, method: str, importance: Mapping[str, float], sd: Mapping[str, float] | None = None) -> list[dict[str, Any]]

Ranked importances: 1 = the largest; ties broken by the feature’s name.

layer_scores

layer_scores(prefix: Literal['l1', 'l2'], y: Any, p: Any, p_market: Any) -> dict[str, float]

{prefix}_logloss, _brier and the market’s on the same rows.

log_loss

log_loss(y: Any, p: Any) -> float

order_prices

order_prices(leg: Mapping[str, Any]) -> dict[str, float] | None

Each order the bet sent -> the price its market showed AT THE DECISION: the engine’s bought[].orders[].shown (pair legs included). The record is made before the paper run re-reads the book a second later, so this is never the re-read price.

path_row

path_row(version: int, path: int, card_pnl: Sequence[float], bets: int) -> dict[str, Any]

One CPCV path of the chosen setting: its per-card P&L -> total and Sharpe per card (mean / sample sd; None under two cards or with no spread).

sent_prices

sent_prices(leg: Mapping[str, Any]) -> dict[str, float] | None

Each order sent -> the book’s price when it was repriced and sent (sent_price; its limit is that + the cushion). Dropped orders have none.

uniqueness_summary

uniqueness_summary(weights: Any) -> dict[str, float]

The meta model’s sample weights (average uniqueness, AFML ch. 4) in six numbers.