diff --git a/changelog.d/medicare-part-a-history.fixed.md b/changelog.d/medicare-part-a-history.fixed.md new file mode 100644 index 00000000000..53a36b73b5b --- /dev/null +++ b/changelog.d/medicare-part-a-history.fixed.md @@ -0,0 +1 @@ +Add the 2015-2020 Medicare Part A premiums and the 2015-2023 and 2026 Part A inpatient hospital deductibles, which had used later years' amounts. diff --git a/policyengine_us/parameters/gov/hhs/medicare/part_a/deductible.yaml b/policyengine_us/parameters/gov/hhs/medicare/part_a/deductible.yaml index 89c12e5805c..8ab953a004b 100644 --- a/policyengine_us/parameters/gov/hhs/medicare/part_a/deductible.yaml +++ b/policyengine_us/parameters/gov/hhs/medicare/part_a/deductible.yaml @@ -4,10 +4,42 @@ metadata: period: year label: Medicare Part A deductible reference: + - title: 42 U.S.C. § 1395e(b)(1) + href: https://www.law.cornell.edu/uscode/text/42/1395e#b_1 + - title: CY 2015 Medicare inpatient hospital deductible and coinsurance amounts (79 FR 61309) + href: https://www.govinfo.gov/content/pkg/FR-2014-10-10/pdf/2014-24257.pdf#page=1 + - title: CY 2016 Medicare inpatient hospital deductible and coinsurance amounts (80 FR 70808) + href: https://www.govinfo.gov/content/pkg/FR-2015-11-16/pdf/2015-29207.pdf#page=1 + - title: CY 2017 Medicare inpatient hospital deductible and coinsurance amounts (81 FR 80060) + href: https://www.govinfo.gov/content/pkg/FR-2016-11-15/pdf/2016-27389.pdf#page=1 + - title: CY 2018 Medicare inpatient hospital deductible and coinsurance amounts (82 FR 55367) + href: https://www.govinfo.gov/content/pkg/FR-2017-11-21/pdf/2017-24913.pdf#page=1 + - title: CY 2019 Medicare inpatient hospital deductible and coinsurance amounts (83 FR 52459) + href: https://www.govinfo.gov/content/pkg/FR-2018-10-17/pdf/2018-22526.pdf#page=1 + - title: CY 2020 Medicare inpatient hospital deductible and coinsurance amounts (84 FR 61619) + href: https://www.govinfo.gov/content/pkg/FR-2019-11-13/pdf/2019-24441.pdf#page=1 + - title: CY 2021 Medicare inpatient hospital deductible and coinsurance amounts (85 FR 71916) + href: https://www.govinfo.gov/content/pkg/FR-2020-11-12/pdf/2020-25024.pdf#page=1 + - title: CY 2022 Medicare inpatient hospital deductible and coinsurance amounts (86 FR 64217) + href: https://www.govinfo.gov/content/pkg/FR-2021-11-17/pdf/2021-25051.pdf#page=1 + - title: CY 2023 Medicare inpatient hospital deductible and coinsurance amounts (87 FR 59094) + href: https://www.govinfo.gov/content/pkg/FR-2022-09-29/pdf/2022-21180.pdf#page=1 - title: 2024 Medicare Parts A & B Premiums and Deductibles href: https://www.cms.gov/newsroom/fact-sheets/2024-medicare-parts-b-premiums-and-deductibles - title: 2025 Medicare Parts A & B Premiums and Deductibles href: https://www.cms.gov/newsroom/fact-sheets/2025-medicare-parts-b-premiums-and-deductibles + - title: 2026 Medicare Parts A & B Premiums and Deductibles + href: https://www.cms.gov/newsroom/fact-sheets/2026-medicare-parts-b-premiums-deductibles values: + 2015-01-01: 1_260 + 2016-01-01: 1_288 + 2017-01-01: 1_316 + 2018-01-01: 1_340 + 2019-01-01: 1_364 + 2020-01-01: 1_408 + 2021-01-01: 1_484 + 2022-01-01: 1_556 + 2023-01-01: 1_600 2024-01-01: 1_632 2025-01-01: 1_676 + 2026-01-01: 1_736 diff --git a/policyengine_us/parameters/gov/hhs/medicare/part_a/full_premium.yaml b/policyengine_us/parameters/gov/hhs/medicare/part_a/full_premium.yaml index a681c0151e4..abed6e706aa 100644 --- a/policyengine_us/parameters/gov/hhs/medicare/part_a/full_premium.yaml +++ b/policyengine_us/parameters/gov/hhs/medicare/part_a/full_premium.yaml @@ -4,6 +4,20 @@ metadata: period: month label: Medicare Part A full premium reference: + - title: 42 U.S.C. § 1395i-2(d) + href: https://www.law.cornell.edu/uscode/text/42/1395i-2#d + - title: CY 2015 Medicare Part A premiums for the uninsured aged (79 FR 61312) + href: https://www.govinfo.gov/content/pkg/FR-2014-10-10/pdf/2014-24250.pdf#page=1 + - title: CY 2016 Medicare Part A premiums for the uninsured aged (80 FR 70805) + href: https://www.govinfo.gov/content/pkg/FR-2015-11-16/pdf/2015-29176.pdf#page=1 + - title: CY 2017 Medicare Part A premiums for the uninsured aged (81 FR 80071) + href: https://www.govinfo.gov/content/pkg/FR-2016-11-15/pdf/2016-27388.pdf#page=1 + - title: CY 2018 Medicare Part A premiums for the uninsured aged (82 FR 55365) + href: https://www.govinfo.gov/content/pkg/FR-2017-11-21/pdf/2017-24912.pdf#page=1 + - title: CY 2019 Medicare Part A premiums for the uninsured aged (83 FR 52455) + href: https://www.govinfo.gov/content/pkg/FR-2018-10-17/pdf/2018-22529.pdf#page=2 + - title: CY 2020 Medicare Part A premiums for the uninsured aged (84 FR 61622) + href: https://www.govinfo.gov/content/pkg/FR-2019-11-13/pdf/2019-24439.pdf#page=1 - title: 2021 Medicare Parts A & B Premiums and Deductibles href: https://www.cms.gov/newsroom/press-releases/2021-medicare-part-b-premiums-remain-steady - title: 2022 Medicare Parts A & B Premiums and Deductibles @@ -17,6 +31,12 @@ metadata: - title: 2026 Medicare Parts A & B Premiums and Deductibles href: https://www.cms.gov/newsroom/fact-sheets/2026-medicare-parts-b-premiums-deductibles values: + 2015-01-01: 407 + 2016-01-01: 411 + 2017-01-01: 413 + 2018-01-01: 422 + 2019-01-01: 437 + 2020-01-01: 458 2021-01-01: 471 2022-01-01: 499 2023-01-01: 506 diff --git a/policyengine_us/parameters/gov/hhs/medicare/part_a/reduced_premium.yaml b/policyengine_us/parameters/gov/hhs/medicare/part_a/reduced_premium.yaml index c124a354e27..c8f48027e52 100644 --- a/policyengine_us/parameters/gov/hhs/medicare/part_a/reduced_premium.yaml +++ b/policyengine_us/parameters/gov/hhs/medicare/part_a/reduced_premium.yaml @@ -4,6 +4,22 @@ metadata: period: month label: Medicare Part A reduced premium reference: + - title: 42 U.S.C. § 1395i-2(d) + href: https://www.law.cornell.edu/uscode/text/42/1395i-2#d + - title: CY 2015 Medicare Part A premiums for the uninsured aged (79 FR 61312) + href: https://www.govinfo.gov/content/pkg/FR-2014-10-10/pdf/2014-24250.pdf#page=1 + - title: CY 2016 Medicare Part A premiums for the uninsured aged (80 FR 70805) + href: https://www.govinfo.gov/content/pkg/FR-2015-11-16/pdf/2015-29176.pdf#page=1 + - title: CY 2017 Medicare Part A premiums for the uninsured aged (81 FR 80071) + href: https://www.govinfo.gov/content/pkg/FR-2016-11-15/pdf/2016-27388.pdf#page=1 + - title: CY 2018 Medicare Part A premiums for the uninsured aged (82 FR 55365) + href: https://www.govinfo.gov/content/pkg/FR-2017-11-21/pdf/2017-24912.pdf#page=1 + - title: CY 2019 Medicare Part A premiums for the uninsured aged (83 FR 52455) + href: https://www.govinfo.gov/content/pkg/FR-2018-10-17/pdf/2018-22529.pdf#page=2 + - title: CY 2020 Medicare Part A premiums for the uninsured aged (84 FR 61622) + href: https://www.govinfo.gov/content/pkg/FR-2019-11-13/pdf/2019-24439.pdf#page=1 + - title: CY 2021 Medicare Part A premiums for the uninsured aged (85 FR 71913) + href: https://www.govinfo.gov/content/pkg/FR-2020-11-12/pdf/2020-25028.pdf#page=1 - title: 2022 Medicare Parts A & B Premiums and Deductibles href: https://www.cms.gov/newsroom/fact-sheets/2022-medicare-parts-b-premiums-deductibles-2022-medicare-part-d-income-related-monthly-adjustment - title: 2023 Medicare Parts A & B Premiums and Deductibles @@ -15,6 +31,12 @@ metadata: - title: 2026 Medicare Parts A & B Premiums and Deductibles href: https://www.cms.gov/newsroom/fact-sheets/2026-medicare-parts-b-premiums-deductibles values: + 2015-01-01: 224 + 2016-01-01: 226 + 2017-01-01: 227 + 2018-01-01: 232 + 2019-01-01: 240 + 2020-01-01: 252 2021-01-01: 259 2022-01-01: 274 2023-01-01: 278 diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicare/eligibility/base_part_a_premium.yaml b/policyengine_us/tests/policy/baseline/gov/hhs/medicare/eligibility/base_part_a_premium.yaml index 27e9423d9c3..08f4a203c53 100644 --- a/policyengine_us/tests/policy/baseline/gov/hhs/medicare/eligibility/base_part_a_premium.yaml +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicare/eligibility/base_part_a_premium.yaml @@ -34,6 +34,116 @@ output: base_part_a_premium: 0 +# Amounts for 2015-2020 come from each year's Federal Register Part A premium +# notice. +- name: 2015 Part A reduced premium for 30-39 quarters. + period: 2015 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 35 + output: + base_part_a_premium: 2_688 # $224 * 12 months + +- name: 2015 Part A full premium for fewer than 30 quarters. + period: 2015 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 20 + output: + base_part_a_premium: 4_884 # $407 * 12 months + +- name: 2016 Part A reduced premium for 30-39 quarters. + period: 2016 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 35 + output: + base_part_a_premium: 2_712 # $226 * 12 months + +- name: 2016 Part A full premium for fewer than 30 quarters. + period: 2016 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 20 + output: + base_part_a_premium: 4_932 # $411 * 12 months + +- name: 2017 Part A reduced premium for 30-39 quarters. + period: 2017 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 35 + output: + base_part_a_premium: 2_724 # $227 * 12 months + +- name: 2017 Part A full premium for fewer than 30 quarters. + period: 2017 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 20 + output: + base_part_a_premium: 4_956 # $413 * 12 months + +- name: 2018 Part A reduced premium for 30-39 quarters. + period: 2018 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 35 + output: + base_part_a_premium: 2_784 # $232 * 12 months + +- name: 2018 Part A full premium for fewer than 30 quarters. + period: 2018 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 20 + output: + base_part_a_premium: 5_064 # $422 * 12 months + +- name: 2019 Part A reduced premium for 30-39 quarters. + period: 2019 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 35 + output: + base_part_a_premium: 2_880 # $240 * 12 months + +- name: 2019 Part A full premium for fewer than 30 quarters. + period: 2019 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 20 + output: + base_part_a_premium: 5_244 # $437 * 12 months + +- name: 2020 Part A reduced premium for 30-39 quarters. + period: 2020 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 35 + output: + base_part_a_premium: 3_024 # $252 * 12 months + +- name: 2020 Part A full premium for fewer than 30 quarters. + period: 2020 + input: + age: 65 + is_medicare_eligible: true + medicare_quarters_of_coverage: 20 + output: + base_part_a_premium: 5_496 # $458 * 12 months + - name: unit test 5 - reduced premium in 2022 period: 2022 input: diff --git a/policyengine_us/tests/policy/baseline/gov/hhs/medicare/test_part_a_cost_sharing_history.py b/policyengine_us/tests/policy/baseline/gov/hhs/medicare/test_part_a_cost_sharing_history.py new file mode 100644 index 00000000000..2cc95a22404 --- /dev/null +++ b/policyengine_us/tests/policy/baseline/gov/hhs/medicare/test_part_a_cost_sharing_history.py @@ -0,0 +1,77 @@ +"""Medicare Part A premiums and inpatient hospital deductible: an announced +amount for every modeled year, rounded as the statute requires. + +CMS announces each calendar year's Part A premiums and inpatient hospital +deductible in the Federal Register. CountryTaxBenefitSystem backdates each +parameter's earliest value to FIRST_MODELED_YEAR, so a file whose values start +after that year silently applies a later year's amount to earlier years. For +each of the three parameter files: + +- the values take effect on January 1 of every year from FIRST_MODELED_YEAR + through the last announced year, with no gaps. + +For every announced year: + +- the full premium is a whole number of dollars (42 U.S.C. 1395i-2(d)(2)); +- the reduced premium, for 30 to 39 quarters of coverage, is the full premium + reduced by 45 percent (1395i-2(d)(4)(A)) and rounded to the nearest dollar, + half up. CMS reduces the rounded full premium: for 2022 the unrounded rate of + $499.29 would give $275, but the notice (86 FR 64214) sets $274, which is + 55 percent of $499; +- the deductible is a multiple of $4 (42 U.S.C. 1395e(b)(1)). + +The parameter files are read directly, since the loaded parameters already +include the backdated values. The announced years are a small finite set, so +each test checks all of them. +""" + +from datetime import date +from pathlib import Path + +import pytest +import yaml + +import policyengine_us +from policyengine_us.tools.parameters import FIRST_MODELED_YEAR + +PART_A = Path(policyengine_us.__file__).parent / "parameters/gov/hhs/medicare/part_a" +FILES = ["full_premium", "reduced_premium", "deductible"] + + +def announced(name): + """{year: amount} for each value dated in the parameter file.""" + values = yaml.safe_load((PART_A / f"{name}.yaml").read_text())["values"] + assert all(instant == date(instant.year, 1, 1) for instant in values) + return {instant.year: amount for instant, amount in values.items()} + + +FULL = announced("full_premium") +REDUCED = announced("reduced_premium") +DEDUCTIBLE = announced("deductible") + + +@pytest.mark.parametrize("name", FILES) +def test_every_modeled_year_has_an_announced_amount(name): + years = announced(name) + missing = set(range(FIRST_MODELED_YEAR, max(years) + 1)) - set(years) + assert not missing, f"{name} backdates a later amount to {sorted(missing)}" + + +@pytest.mark.parametrize("year", sorted(FULL)) +def test_full_premium_is_whole_dollars(year): + assert float(FULL[year]).is_integer() + + +def test_premiums_are_announced_for_the_same_years(): + assert FULL.keys() == REDUCED.keys() + + +@pytest.mark.parametrize("year", sorted(REDUCED)) +def test_reduced_premium_is_45_percent_off_the_full_premium(year): + # 55 percent of the full premium in cents, rounded half up to the dollar. + assert REDUCED[year] == (55 * int(FULL[year]) + 50) // 100 + + +@pytest.mark.parametrize("year", sorted(DEDUCTIBLE)) +def test_deductible_is_a_multiple_of_4(year): + assert DEDUCTIBLE[year] % 4 == 0