# /// script # requires-python = ">=3.12" # dependencies = [] # exclude-newer = "2026-08-08T00:00:00Z" # /// """Readable APBO, benefit-cost, OCI, and sensitivity lab for Harbor Light.""" from __future__ import annotations def money(amount: float) -> str: return f"({abs(amount):,.2f})" if amount < 0 else f"{amount:,.2f}" def show(title: str, rows: list[tuple[str, float]]) -> None: print(f"\n{title}\n{'-' * len(title)}") width = max(len(label) for label, _ in rows) for label, value in rows: print(f"{label:<{width}} {money(value):>18}") # The actuary supplies opening APBO after applying the plan's attribution method. opening_apbo = 7_500_000.00 service_cost = 500_000.00 interest_cost = 450_000.00 obligation_loss = 300_000.00 benefits_paid = 250_000.00 ending_apbo = ( opening_apbo + service_cost + interest_cost + obligation_loss - benefits_paid ) show( "Accumulated postretirement benefit obligation", [ ("Opening APBO", opening_apbo), ("Service cost", service_cost), ("Interest cost", interest_cost), ("Actuarial loss", obligation_loss), ("Benefits paid", -benefits_paid), ("Ending APBO", ending_apbo), ], ) opening_assets = 2_000_000.00 actual_return = 120_000.00 contribution = 400_000.00 ending_assets = opening_assets + actual_return + contribution - benefits_paid funded_status = ending_assets - ending_apbo show( "Plan assets and funded status", [ ("Opening plan assets", opening_assets), ("Actual return", actual_return), ("Employer contribution", contribution), ("Benefits paid", -benefits_paid), ("Ending plan assets", ending_assets), ("Ending funded status", funded_status), ], ) expected_return = 100_000.00 loss_amortization = 50_000.00 benefit_cost = service_cost + interest_cost - expected_return + loss_amortization asset_gain = actual_return - expected_return current_oci_loss = obligation_loss - asset_gain - loss_amortization opening_aoci_loss = 800_000.00 ending_aoci_loss = opening_aoci_loss + current_oci_loss opening_funded_status = opening_assets - opening_apbo liability_increase = -(funded_status - opening_funded_status) entry_difference = benefit_cost + current_oci_loss - contribution - liability_increase show( "Cost, OCI, and employer-entry control", [ ("Postretirement benefit cost", benefit_cost), ("Current OCI loss", current_oci_loss), ("Ending AOCI loss", ending_aoci_loss), ("Cash contribution", -contribution), ("Liability increase", -liability_increase), ("Entry difference", entry_difference), ], ) # Conditional actuarial outputs; this script does not choose the trend assumption. higher_trend_obligation = 9_200_000.00 lower_trend_obligation = 8_000_000.00 show( "Healthcare-trend sensitivity", [ ("Base APBO", ending_apbo), ("Higher-trend APBO", higher_trend_obligation), ("Higher-trend change", higher_trend_obligation - ending_apbo), ("Lower-trend APBO", lower_trend_obligation), ("Lower-trend change", lower_trend_obligation - ending_apbo), ], ) assert abs(ending_apbo - 8_500_000.00) < 0.01 assert abs(ending_assets - 2_270_000.00) < 0.01 assert abs(funded_status + 6_230_000.00) < 0.01 assert abs(entry_difference) < 0.01 print("\nBoundary: EPBO, attribution, APBO, and trend scenarios are actuarial inputs.") print("The script does not forecast claims or determine legal funding or benefit security.")