Files
stack/tests/lead/test_express_benchmark.py
kert cb9976e160
All checks were successful
CI / lint (push) Successful in 44s
CI / notebooks-smoke (push) Successful in 1m33s
Deploy / changes (push) Successful in 14s
CI / test (push) Successful in 3m9s
Infra CI / zotero (push) Successful in 14s
Infra CI / notebooks (push) Successful in 55s
Infra CI / api (push) Successful in 1m9s
Infra CI / docs (push) Successful in 1m23s
Infra CI / llm (push) Successful in 1m1s
Infra CI / mc (push) Successful in 16s
Infra CI / bcda (push) Successful in 1m43s
Deploy / notebooks (push) Has been skipped
Deploy / zotero (push) Has been skipped
Deploy / docs (push) Has been skipped
Package Supply Chain / pkg-supply-chain (push) Successful in 1m30s
Deploy / api (push) Successful in 1m17s
Deploy / llm (push) Successful in 1m18s
Deploy / mc (push) Has been skipped
Deploy / bcda (push) Successful in 1m42s
Deploy / report (push) Successful in 1m36s
feat(lead): LEAD PY2027 financial methodology — settlement and benchmark engines
Ports the public CMS "LEAD Model PY 2027 Alignment and Financial
Methodology Paper" v1.2 (bib E4PEU3HV) as generic engines: parameters
come from the paper, everything CMS computes per ACO or per year comes
from the caller. No participant data, no organization-specific rules.

- lead.params: Table 5.2.1 discounts, 3% Quality Withhold, 2% retention
  incentive, Box 5.3.3 Stop-Loss bands, Tables 5.4.1/5.4.3 corridors, 2%
  sequestration, base-year weights, Table 3.5.1 ACPT guardrails,
  risk-score growth caps, REA/PSA shares and caps, voluntary guardrail
  and 500 minimum, Table 2.6.1 base-year alignment minimums.
- lead.settlement: Final Financial Settlement, Table 5.6.1 line by line
  (settle(SettlementInputs) -> SettlementLines).
- lead.stop_loss: Box 5.3.3 charge, banded payout, neutrality factor,
  application to PY expenditure.
- lead.monies_owed: Table 5.5.1 Total Monies Owed, APO reconciliation.
- lead.timing: run-out end, settlement-basis rule, settlement-stage inputs.
- lead.benchmark: §3 formulas — risk standardization, two-/three-way
  trend, base-year weights and sufficiency, voluntary guardrail,
  regional FFS, spending designation, REA, PSA, risk-score cap, hybrid
  alignment dollars, category blend.
- lead.express: the same as narwhals Exprs; express.settlement.settle
  settles a frame of scenarios on any backend.

Rounding: every dollar line rounds to the cent (half away from zero) as
it is produced; PBPMs, rates and factors never do. It is the only rule
under which Tables 3.3.3, 3.5.3.2, 3.5.4, 5.5.1 and 5.6.1 all reproduce
(3.5.4 line 24 sums cent-rounded cells; 3.3.3 carries unrounded PBPMs).
The Expr cents snaps its ÷100 with round(2): polars 2.0 divides a column
by a literal as a reciprocal multiply (k × 0.01), one ulp off k/100 for
~15% of values.

Missing inputs stay missing (None/null or a refused input model); the
only zeros are the paper's own (Professional "N/A" discount, no
Stop-Loss election, sequestration on losses, ineligible REA/PSA).

Paper inconsistencies recorded in tests: Table 5.5.1 line 2 is a cent
below Table 5.6.1 line 28 (.43 vs .44); Box 3.3.2 prints 1.104 then says
1.103; §3.5.1 prose widens the ACPT lower bound a year later than
Table 3.5.1 (the table is followed).

Tests: 283 in tests/lead — every published line to the cent, Expr
builders on polars and DuckDB, bit-for-bit scalar/frame parity over 160
scenarios; 100% of src/lead.
2026-10-27 14:11:10 -04:00

336 lines
11 KiB
Python

"""lead.express.benchmark: the §3 worked examples as frames on polars and
DuckDB, plus nulls for missing inputs."""
from __future__ import annotations
import narwhals as nw
import polars as pl
import pytest
from lead import benchmark as scalar
from lead.express import cents
from lead.express.benchmark import (
RISK_CAP_REFERENCE_MISSING,
benchmark_adjustment_cap,
benchmark_dollars,
capped_risk_score,
contributes_to_voluntary_benchmark,
county_market_share,
county_weight,
growth_rate,
month_weighted_mean,
performance_year_benchmark_pbpm,
regional_efficiency_adjustment,
regional_efficiency_eligible,
risk_growth_cap_status,
risk_standardized_pbpm,
three_way_blended_trend,
trended_weighted_pbpm,
two_way_blended_trend,
uncapped_regional_efficiency_adjustment,
voluntary_guardrail,
voluntary_guardrail_status,
)
from lead.money import cents as scalar_cents
from tests.lead.paper import (
REA_TABLES,
TABLE_3_3_3,
TABLE_3_5_4_CLAIMS,
TABLE_3_5_4_TOTALS,
TABLE_3_5_4_VOLUNTARY,
)
def test_box_3_3_2_as_a_county_frame(backend):
counties = {
"aligned": [20_000.0, 5_000.0],
"eligible": [100_000.0, 50_000.0],
"total": [25_000.0, 25_000.0],
}
rows = backend.select(
counties,
contribution=county_market_share("aligned", "eligible")
* county_weight("aligned", "total"),
)
weight = sum(r["contribution"] for r in rows)
assert weight == pytest.approx(0.18)
(trend,) = backend.select(
{
"nat_by3": [1_120.0],
"nat_by1": [1_000.0],
"reg_by3": [1_155.0],
"reg_by1": [1_050.0],
"w": [weight],
},
trend=two_way_blended_trend(
growth_rate("nat_by3", "nat_by1"), growth_rate("reg_by3", "reg_by1"), "w"
),
)
assert round(trend["trend"], 3) == 1.104
def test_growth_and_shares_are_null_without_positive_denominators(backend):
data = {"a": [0.0, 10.0, None], "b": [5.0, 0.0, 5.0]}
rows = backend.select(
data,
{"a": pl.Float64, "b": pl.Float64},
g=growth_rate("a", "b"),
s=county_market_share("a", "b"),
)
assert [(r["g"], r["s"]) for r in rows] == [(None, 0.0), (None, None), (None, None)]
def test_table_3_3_3_as_a_base_year_frame(backend):
years = ("BY1", "BY2", "BY3")
data = {
"year": list(years),
"paid": [TABLE_3_3_3[y][0] for y in years],
"months": [float(TABLE_3_3_3[y][1]) for y in years],
"risk": [TABLE_3_3_3[y][2] for y in years],
"trend": [TABLE_3_3_3[y][5] for y in years],
"weight": [TABLE_3_3_3[y][7] for y in years],
}
rs = risk_standardized_pbpm("paid", "months", "risk")
rows = backend.select(
data,
year=nw.col("year"),
line5=cents(rs),
line9=cents(trended_weighted_pbpm(rs, "trend", "weight")),
raw=trended_weighted_pbpm(rs, "trend", "weight"),
)
by_year = {r["year"]: r for r in rows}
for year in years:
assert by_year[year]["line5"] == TABLE_3_3_3[year][4]
assert by_year[year]["line9"] == TABLE_3_3_3[year][8]
assert (
scalar_cents(sum(r["raw"] for r in rows)) == TABLE_3_3_3["historical_benchmark"]
)
def test_rea_tables_as_a_category_frame(backend):
data = {
"category": list(REA_TABLES),
"regional": [float(v[0]) for v in REA_TABLES.values()],
"historical": [float(v[1]) for v in REA_TABLES.values()],
"uspcc": [float(v[4]) for v in REA_TABLES.values()],
"risk": [v[5] for v in REA_TABLES.values()],
"designation": ["Lower-spending"] * 3,
"option": ["Global"] * 3,
}
rea = regional_efficiency_adjustment(
"regional",
"historical",
eligible=regional_efficiency_eligible("designation", "option"),
uspcc_amount="uspcc",
py_average_risk_score="risk",
cap_rate=0.05,
)
rows = backend.select(
data,
uncapped=uncapped_regional_efficiency_adjustment("regional", "historical"),
cap=cents(benchmark_adjustment_cap("uspcc", "risk", 0.05)),
applied=cents(rea),
adjusted=cents(nw.col("historical") + rea),
)
for values, result in zip(REA_TABLES.values(), rows, strict=True):
assert (
result["uncapped"],
result["cap"],
result["applied"],
result["adjusted"],
) == (values[3], values[6], values[7], values[8])
def test_rea_nulls_and_zeros(backend):
data = {
"regional": [1_050.0, 1_050.0, 950.0, 1_050.0, None],
"historical": [1_000.0] * 5,
"uspcc": [None, 1_000.0, None, 1_000.0, 1_000.0],
"eligible": [True, None, True, False, True],
}
schema = {
"regional": pl.Float64,
"historical": pl.Float64,
"uspcc": pl.Float64,
"eligible": pl.Boolean,
}
rea = regional_efficiency_adjustment(
"regional",
"historical",
eligible="eligible",
uspcc_amount="uspcc",
py_average_risk_score=nw.lit(1.0),
cap_rate="cap_rate",
)
frame_rows = backend.select(
{**data, "cap_rate": [0.05] * 5}, {**schema, "cap_rate": pl.Float64}, rea=rea
)
# missing cap on a positive REA, unknown eligibility, at/above regional,
# ineligible, missing regional
assert [r["rea"] for r in frame_rows] == [None, None, 0.0, 0.0, None]
def test_three_way_trend_per_row_performance_year(backend):
data = {
"two_way": [1.05, 1.05, 1.05, 1.05],
"acpt": [1.07, 1.02, 1.07, 1.07],
"py": [2027, 2027, 2028, 2040],
}
rows = backend.select(data, t=three_way_blended_trend("two_way", "acpt", "py"))
expected = [
scalar.three_way_blended_trend(1.05, a, y).applied
for a, y in ((1.07, 2027), (1.02, 2027), (1.07, 2028))
]
assert [r["t"] for r in rows] == [*expected, None]
(literal,) = backend.select(
{"two_way": [1.05], "acpt": [1.07]},
t=three_way_blended_trend("two_way", "acpt", 2027),
)
assert literal["t"] == expected[0]
def test_capped_risk_score_and_status(backend):
data = {
"by3": [1.0, 1.0, 1.0, None, 1.0],
"py": [1.05, 0.90, 1.035, 1.2, 1.2],
"cat": ["A&D", "ESRD", "High Needs", "A&D", "Other"],
}
rows = backend.select(
data,
{"by3": pl.Float64, "py": pl.Float64, "cat": pl.String},
score=capped_risk_score("by3", "py", "cat"),
status=risk_growth_cap_status("by3", "py", "cat"),
)
expected = [
scalar.capped_risk_score(1.0, py, cat)
for py, cat in ((1.05, "A&D"), (0.90, "ESRD"), (1.035, "High Needs"))
]
assert [(r["score"], r["status"]) for r in rows[:3]] == expected
# No BY 3 reference or unknown category: no silent pass-through.
assert [(r["score"], r["status"]) for r in rows[3:]] == [
(None, RISK_CAP_REFERENCE_MISSING)
] * 2
def test_voluntary_guardrail_and_contribution(backend):
data = {
"vol": [1_150.0, 850.0, 1_050.0, 1_000.0],
"claims": [1_000.0, 1_000.0, 1_000.0, None],
}
rows = backend.select(
data,
{"vol": pl.Float64, "claims": pl.Float64},
b=voluntary_guardrail("vol", "claims"),
s=voluntary_guardrail_status("vol", "claims"),
)
expected = [
scalar.voluntary_guardrail(v, 1_000.0) for v in (1_150.0, 850.0, 1_050.0)
]
assert [(r["b"], r["s"]) for r in rows[:3]] == expected
assert (rows[3]["b"], rows[3]["s"]) == (None, None)
cats = {
"cat": ["A&D", "High Needs", "High Needs", "High Needs"],
"by3": ["A&D", "High Needs", "A&D", None],
}
flags = backend.select(
cats,
{"cat": pl.String, "by3": pl.String},
f=contributes_to_voluntary_benchmark("cat", "by3"),
)
assert [r["f"] for r in flags] == [True, True, False, False]
def test_table_3_5_4_as_a_frame(backend):
rows = []
for category, (
pbpm,
trend,
risk,
full,
hybrid,
factor,
_,
) in TABLE_3_5_4_CLAIMS.items():
rows.append(
{
"category": category,
"pbpm": pbpm,
"trend": trend,
"risk": risk,
"full": float(full),
"m2": float(hybrid),
"f2": factor,
"m3": 0.0,
"f3": 1.0,
"m4": 0.0,
"f4": 1.0,
}
)
for category, (
pbpm,
trend,
risk,
full,
months,
factors,
_,
) in TABLE_3_5_4_VOLUNTARY.items():
rows.append(
{
"category": category,
"pbpm": pbpm,
"trend": trend,
"risk": risk,
"full": float(full),
**{f"m{q}": float(m) for q, m in zip((2, 3, 4), months, strict=True)},
**{f"f{q}": f for q, f in zip((2, 3, 4), factors, strict=True)},
}
)
py_pbpm = performance_year_benchmark_pbpm("pbpm", nw.lit(0.0), "trend", "risk")
dollars = benchmark_dollars(
py_pbpm, "full", [("m2", "f2"), ("m3", "f3"), ("m4", "f4")]
)
cells = backend.select(rows, category=nw.col("category"), dollars=dollars)
expected = [v[-1] for v in TABLE_3_5_4_CLAIMS.values()] + [
v[-1] for v in TABLE_3_5_4_VOLUNTARY.values()
]
assert [c["dollars"] for c in cells] == expected
line24 = {}
for cell in cells:
line24[cell["category"]] = scalar.total_benchmark(
[line24.get(cell["category"], 0.0), cell["dollars"]]
)
assert line24 == {k: v for k, v in TABLE_3_5_4_TOTALS["24"].items() if k != "TOTAL"}
def test_benchmark_dollars_without_hybrid_months(backend):
(result,) = backend.select(
{"pbpm": [1_125.0], "months": [60_000.0]}, d=benchmark_dollars("pbpm", "months")
)
assert result["d"] == 67_500_000.0
def test_month_weighted_mean_in_a_group_by(backend):
data = {
"cat": ["A&D", "A&D", "A&D", "ESRD", "HN"],
"score": [1.0, 1.2, None, 0.9, 1.5],
"months": [10.0, 30.0, 50.0, 12.0, 0.0],
}
frame = nw.from_native(
backend.frame(
data, {"cat": pl.String, "score": pl.Float64, "months": pl.Float64}
)
)
out = (
frame.group_by("cat")
.agg(avg=month_weighted_mean("score", "months"))
.sort("cat")
)
rows = backend.rows(out.to_native())
assert [r["cat"] for r in rows] == ["A&D", "ESRD", "HN"]
assert rows[0]["avg"] == pytest.approx(
scalar.month_weighted_average([(1.0, 10), (1.2, 30), (None, 50)])
)
assert rows[1]["avg"] == pytest.approx(0.9)
assert rows[2]["avg"] is None