From 9bc56e4707f59c5cb53dd6f1cea50d3640665524 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 11 Oct 2026 17:39:41 -0400 Subject: [PATCH] Use not seasonally adjusted CPI-W for 2024 onward The CPI-W file matched BLS CWUR0000SA0 (not seasonally adjusted, the series SSA uses for cost-of-living adjustments) through December 2023. From January 2024 it held seasonally adjusted values: #6672 added January 2024-August 2025 and #9100 added September 2025-June 2026, citing CWSR0000SA0. Replace those 29 months with CWUR0000SA0 and re-anchor the CBO-derived projections on the not seasonally adjusted June 2026 CPI-W/CPI-U ratio (327.075 / 333.952). Add a test that the CPI-W July-September averages reproduce gov.ssa.uprating's actual values under 42 U.S.C. 415(i), which the seasonally adjusted months failed (2024Q3: 307.931 vs 308.729). Co-Authored-By: Claude Opus 5.5 --- changelog.d/fix-cpi-w-nsa.fixed.md | 1 + .../parameters/gov/bls/cpi/cpi_w.yaml | 146 +++++++++--------- .../gov/bls/test_cpi_monthly_actuals.py | 68 +++++++- 3 files changed, 141 insertions(+), 74 deletions(-) create mode 100644 changelog.d/fix-cpi-w-nsa.fixed.md diff --git a/changelog.d/fix-cpi-w-nsa.fixed.md b/changelog.d/fix-cpi-w-nsa.fixed.md new file mode 100644 index 00000000000..dc2ace685ab --- /dev/null +++ b/changelog.d/fix-cpi-w-nsa.fixed.md @@ -0,0 +1 @@ +Use the not seasonally adjusted CPI-W (BLS CWUR0000SA0, the series SSA uses for cost-of-living adjustments) for January 2024 through June 2026, where seasonally adjusted values had replaced it, and re-anchor the CPI-W projections on the not seasonally adjusted June 2026 ratio to CPI-U. diff --git a/policyengine_us/parameters/gov/bls/cpi/cpi_w.yaml b/policyengine_us/parameters/gov/bls/cpi/cpi_w.yaml index 027e7e7f278..70da83e8ba9 100644 --- a/policyengine_us/parameters/gov/bls/cpi/cpi_w.yaml +++ b/policyengine_us/parameters/gov/bls/cpi/cpi_w.yaml @@ -1,4 +1,4 @@ -description: The Bureau of Labor Statistics estimates this Consumer Price Index for Urban Wage Earners and Clerical Workers. +description: The Bureau of Labor Statistics estimates this Consumer Price Index for Urban Wage Earners and Clerical Workers (U.S. city average, all items, not seasonally adjusted). values: 1913-01-01: 9.9 1913-02-01: 9.8 @@ -1332,87 +1332,93 @@ values: 2023-10-01: 302.071 2023-11-01: 301.224 2023-12-01: 300.728 - 2024-01-01: 303.733 - 2024-02-01: 305.121 - 2024-03-01: 306.349 - 2024-04-01: 307.211 - 2024-05-01: 307.233 - 2024-06-01: 307.010 - 2024-07-01: 307.410 - 2024-08-01: 307.843 - 2024-09-01: 308.539 - 2024-10-01: 309.161 - 2024-11-01: 309.945 - 2024-12-01: 311.162 - 2025-01-01: 312.776 - 2025-02-01: 313.323 - 2025-03-01: 313.175 - 2025-04-01: 313.729 - 2025-05-01: 313.961 - 2025-06-01: 314.858 - 2025-07-01: 315.279 - 2025-08-01: 316.530 - 2025-09-01: 317.477 + 2024-01-01: 302.201 + 2024-02-01: 304.284 + 2024-03-01: 306.502 + 2024-04-01: 307.811 + 2024-05-01: 308.163 + 2024-06-01: 308.054 + 2024-07-01: 308.501 + 2024-08-01: 308.640 + 2024-09-01: 309.046 + 2024-10-01: 309.358 + 2024-11-01: 308.998 + 2024-12-01: 309.067 + 2025-01-01: 311.172 + 2025-02-01: 312.460 + 2025-03-01: 313.250 + 2025-04-01: 314.243 + 2025-05-01: 314.839 + 2025-06-01: 315.945 + 2025-07-01: 316.349 + 2025-08-01: 317.306 + 2025-09-01: 318.139 # October 2025 CPI was not published (BLS canceled the release); the # September value carries forward at October instants. - 2025-11-01: 318.419 - 2025-12-01: 319.139 - 2026-01-01: 319.434 - 2026-02-01: 320.266 - 2026-03-01: 323.698 - 2026-04-01: 325.892 - 2026-05-01: 327.694 - 2026-06-01: 325.641 + 2025-11-01: 317.414 + 2025-12-01: 317.014 + 2026-01-01: 317.942 + 2026-02-01: 319.422 + 2026-03-01: 323.500 + 2026-04-01: 326.541 + 2026-05-01: 328.829 + 2026-06-01: 327.075 # CBO projections from CBO Feb 2026 forecast for future periods. - # CPI-W derived from CBO CPI-U quarterly projections using ratio - # of last actual CPI-W (316.530, Aug 2025) to CPI-U (323.364, Aug 2025). - 2026-08-01: 325.939 # 2026Q3: 332.976 * 316.530 / 323.364 - 2026-11-01: 328.049 # 2026Q4: 335.132 * 316.530 / 323.364 - 2027-02-01: 330.086 # 2027Q1: 337.213 * 316.530 / 323.364 - 2027-05-01: 332.080 # 2027Q2: 339.250 * 316.530 / 323.364 - 2027-08-01: 334.068 # 2027Q3: 341.281 * 316.530 / 323.364 - 2027-11-01: 336.043 # 2027Q4: 343.298 * 316.530 / 323.364 - 2028-02-01: 338.007 # 2028Q1: 345.305 * 316.530 / 323.364 - 2028-05-01: 339.963 # 2028Q2: 347.303 * 316.530 / 323.364 - 2028-08-01: 341.909 # 2028Q3: 349.291 * 316.530 / 323.364 - 2028-11-01: 343.856 # 2028Q4: 351.280 * 316.530 / 323.364 - 2029-02-01: 345.803 # 2029Q1: 353.269 * 316.530 / 323.364 - 2029-05-01: 347.754 # 2029Q2: 355.262 * 316.530 / 323.364 - 2029-08-01: 349.710 # 2029Q3: 357.260 * 316.530 / 323.364 - 2029-11-01: 351.672 # 2029Q4: 359.265 * 316.530 / 323.364 - 2030-02-01: 353.644 # 2030Q1: 361.279 * 316.530 / 323.364 - 2030-05-01: 355.626 # 2030Q2: 363.304 * 316.530 / 323.364 - 2030-08-01: 357.619 # 2030Q3: 365.340 * 316.530 / 323.364 - 2030-11-01: 359.622 # 2030Q4: 367.386 * 316.530 / 323.364 - 2031-02-01: 361.636 # 2031Q1: 369.444 * 316.530 / 323.364 - 2031-05-01: 363.660 # 2031Q2: 371.512 * 316.530 / 323.364 - 2031-08-01: 365.695 # 2031Q3: 373.591 * 316.530 / 323.364 - 2031-11-01: 367.742 # 2031Q4: 375.682 * 316.530 / 323.364 - 2032-02-01: 369.800 # 2032Q1: 377.784 * 316.530 / 323.364 - 2032-05-01: 371.869 # 2032Q2: 379.898 * 316.530 / 323.364 - 2032-08-01: 373.950 # 2032Q3: 382.024 * 316.530 / 323.364 - 2032-11-01: 376.042 # 2032Q4: 384.161 * 316.530 / 323.364 - 2033-02-01: 378.146 # 2033Q1: 386.310 * 316.530 / 323.364 - 2033-05-01: 380.261 # 2033Q2: 388.471 * 316.530 / 323.364 - 2033-08-01: 382.388 # 2033Q3: 390.644 * 316.530 / 323.364 - 2033-11-01: 384.528 # 2033Q4: 392.830 * 316.530 / 323.364 - 2034-02-01: 386.678 # 2034Q1: 395.027 * 316.530 / 323.364 - 2034-05-01: 388.842 # 2034Q2: 397.237 * 316.530 / 323.364 - 2034-08-01: 391.018 # 2034Q3: 399.460 * 316.530 / 323.364 - 2034-11-01: 393.206 # 2034Q4: 401.695 * 316.530 / 323.364 - 2035-02-01: 395.406 # 2035Q1: 403.943 * 316.530 / 323.364 + # CPI-W derived from CBO CPI-U quarterly projections using the ratio of + # the last actual CPI-W (327.075, June 2026) to CPI-U (333.952, June 2026), + # both not seasonally adjusted (BLS CWUR0000SA0 and CUUR0000SA0). + 2026-08-01: 326.119 # 2026Q3: 332.976 * 327.075 / 333.952 + 2026-11-01: 328.231 # 2026Q4: 335.132 * 327.075 / 333.952 + 2027-02-01: 330.269 # 2027Q1: 337.213 * 327.075 / 333.952 + 2027-05-01: 332.264 # 2027Q2: 339.250 * 327.075 / 333.952 + 2027-08-01: 334.253 # 2027Q3: 341.281 * 327.075 / 333.952 + 2027-11-01: 336.229 # 2027Q4: 343.298 * 327.075 / 333.952 + 2028-02-01: 338.194 # 2028Q1: 345.305 * 327.075 / 333.952 + 2028-05-01: 340.151 # 2028Q2: 347.303 * 327.075 / 333.952 + 2028-08-01: 342.098 # 2028Q3: 349.291 * 327.075 / 333.952 + 2028-11-01: 344.046 # 2028Q4: 351.280 * 327.075 / 333.952 + 2029-02-01: 345.994 # 2029Q1: 353.269 * 327.075 / 333.952 + 2029-05-01: 347.946 # 2029Q2: 355.262 * 327.075 / 333.952 + 2029-08-01: 349.903 # 2029Q3: 357.260 * 327.075 / 333.952 + 2029-11-01: 351.867 # 2029Q4: 359.265 * 327.075 / 333.952 + 2030-02-01: 353.839 # 2030Q1: 361.279 * 327.075 / 333.952 + 2030-05-01: 355.823 # 2030Q2: 363.304 * 327.075 / 333.952 + 2030-08-01: 357.817 # 2030Q3: 365.340 * 327.075 / 333.952 + 2030-11-01: 359.821 # 2030Q4: 367.386 * 327.075 / 333.952 + 2031-02-01: 361.836 # 2031Q1: 369.444 * 327.075 / 333.952 + 2031-05-01: 363.862 # 2031Q2: 371.512 * 327.075 / 333.952 + 2031-08-01: 365.898 # 2031Q3: 373.591 * 327.075 / 333.952 + 2031-11-01: 367.946 # 2031Q4: 375.682 * 327.075 / 333.952 + 2032-02-01: 370.004 # 2032Q1: 377.784 * 327.075 / 333.952 + 2032-05-01: 372.075 # 2032Q2: 379.898 * 327.075 / 333.952 + 2032-08-01: 374.157 # 2032Q3: 382.024 * 327.075 / 333.952 + 2032-11-01: 376.250 # 2032Q4: 384.161 * 327.075 / 333.952 + 2033-02-01: 378.355 # 2033Q1: 386.310 * 327.075 / 333.952 + 2033-05-01: 380.471 # 2033Q2: 388.471 * 327.075 / 333.952 + 2033-08-01: 382.600 # 2033Q3: 390.644 * 327.075 / 333.952 + 2033-11-01: 384.741 # 2033Q4: 392.830 * 327.075 / 333.952 + 2034-02-01: 386.892 # 2034Q1: 395.027 * 327.075 / 333.952 + 2034-05-01: 389.057 # 2034Q2: 397.237 * 327.075 / 333.952 + 2034-08-01: 391.234 # 2034Q3: 399.460 * 327.075 / 333.952 + 2034-11-01: 393.423 # 2034Q4: 401.695 * 327.075 / 333.952 + 2035-02-01: 395.625 # 2035Q1: 403.943 * 327.075 / 333.952 # Values for 2036-2100 are set programmatically in uprating_extensions.py metadata: unit: currency-USD label: CPI-W economy: false reference: - - title: BLS | CPI-W, U.S. city average, all items, seasonally adjusted (CWSR0000SA0), monthly values through June 2026 - href: https://data.bls.gov/timeseries/CWSR0000SA0 + - title: BLS | CPI-W, U.S. city average, all items, not seasonally adjusted (CWUR0000SA0), monthly values + href: https://data.bls.gov/timeseries/CWUR0000SA0 + - title: SSA | CPI-W monthly values, the series behind the Social Security cost-of-living adjustment + href: https://www.ssa.gov/oact/STATS/cpiw.html + - title: BLS | CPI-U, U.S. city average, all items, not seasonally adjusted (CUUR0000SA0), June 2026 value for the projection ratio + href: https://data.bls.gov/timeseries/CUUR0000SA0 - title: CBO | Economic and Budget Projections | January 2025 # Quarterly: Row 51 href: https://www.cbo.gov/system/files/2025-01/51135-2025-01-Economic-Projections.xlsx - title: CBO | Economic Projections | February 2026 # CPI-W derived from CPI-U quarterly projections (Sheet: 1. Quarterly, Row 53) - # using ratio of last actual CPI-W to CPI-U (316.530 / 323.364) + # using the ratio of the last actual CPI-W to CPI-U, both not seasonally + # adjusted (327.075 / 333.952, June 2026) href: https://www.cbo.gov/system/files/2026-02/51135-2026-02-Economic-Projections.xlsx diff --git a/policyengine_us/tests/policy/baseline/gov/bls/test_cpi_monthly_actuals.py b/policyengine_us/tests/policy/baseline/gov/bls/test_cpi_monthly_actuals.py index 79292eb2d11..705c32e88ab 100644 --- a/policyengine_us/tests/policy/baseline/gov/bls/test_cpi_monthly_actuals.py +++ b/policyengine_us/tests/policy/baseline/gov/bls/test_cpi_monthly_actuals.py @@ -2,6 +2,10 @@ including the October 2025 gap (never published) and the replaced projection points (#9091).""" +from decimal import ROUND_HALF_UP, Decimal + +import yaml + from policyengine_us.system import system @@ -11,12 +15,14 @@ def _cpi(name): def test_cpi_w_monthly_actuals(): cpi_w = _cpi("cpi_w") - # June 2026 observed value (CWSR0000SA0). - assert cpi_w("2026-06-01") == 325.641 + # June 2026 observed value (CWUR0000SA0, not seasonally adjusted). + assert cpi_w("2026-06-01") == 327.075 # October 2025 was never published: September carries forward. - assert cpi_w("2025-10-01") == 317.477 + assert cpi_w("2025-10-01") == 318.139 # The observed February replaces the derived 2026Q1 projection point. - assert cpi_w("2026-02-01") == 320.266 + assert cpi_w("2026-02-01") == 319.422 + # The seasonally adjusted series (CWSR0000SA0) reads 303.623 here. + assert cpi_w("2024-01-01") == 302.201 def test_cpi_u_monthly_actuals(): @@ -32,3 +38,57 @@ def test_c_cpi_u_monthly_actuals(): assert c_cpi_u("2025-10-01") == 180.196 # The observed February replaces the annual projection point (183.1). assert c_cpi_u("2026-02-01") == 181.080 + + +def _listed_values(parameter): + """The dated values a parameter's YAML file lists, before the system + backdates the first one and extends the series.""" + with open(parameter.file_path) as file: + values = yaml.safe_load(file)["values"] + return {str(instant): value for instant, value in values.items()} + + +def _rounded_percent_increase(new, old): + """Percentage increase rounded to the nearest tenth, per 415(i)(1)(D).""" + percent = Decimal(repr(new)) / Decimal(repr(old)) * 100 - 100 + return percent.quantize(Decimal("0.1"), ROUND_HALF_UP) + + +def test_cpi_w_third_quarter_averages_reproduce_ssa_uprating(): + """CPI-W is one series: the not seasonally adjusted index SSA uses. + + gov.ssa.uprating holds the CPI-W third-quarter average (42 U.S.C. + 415(i)(1)(A)(i) and (G)) of the latest cost-of-living computation + quarter. A quarter whose CPI increase, rounded to the nearest tenth of a + percent (415(i)(1)(D)), is not above zero is not one (415(i)(1)(B)), so + the level carries forward. Each year whose July-September the CPI-W file + lists as monthly values must reproduce SSA's value to its three + published decimals. The seasonally adjusted values the file held for + 2024 failed this: they put the 2024Q3 average at 307.931, not 308.729. + """ + cpi_w = _listed_values(_cpi("cpi_w")) + ssa_uprating = _listed_values(system.parameters.gov.ssa.uprating) + checked = [] + prior_level = None + for instant in sorted(ssa_uprating): + year = int(instant[:4]) + months = [f"{year - 1}-{month:02d}-01" for month in (7, 8, 9)] + if not all(month in cpi_w for month in months): + # CBO-based projections from here on. + break + average = sum(cpi_w[month] for month in months) / 3 + level = ssa_uprating[instant] + if prior_level is None or _rounded_percent_increase(average, prior_level) > 0: + assert abs(level - average) < 0.0005 + 1e-9, ( + f"gov.ssa.uprating {year} is {level}, but the {year - 1} " + f"third-quarter CPI-W average is {average:.4f}." + ) + else: + assert level == prior_level, ( + f"No cost-of-living increase for {year}, so gov.ssa.uprating " + f"should stay at {prior_level}, not {level}." + ) + prior_level = level + checked.append(year) + # The 2022-2026 actuals, through the 2025Q3 average SSA used for 2026. + assert set(range(2022, 2027)) <= set(checked), checked