Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/medicare-part-a-history.fixed.md
Original file line number Diff line number Diff line change
@@ -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.
32 changes: 32 additions & 0 deletions policyengine_us/parameters/gov/hhs/medicare/part_a/deductible.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Loading