Skip to content
Draft
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/added/8188.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add selected Marketplace plan categories and ACA cost-sharing reduction actuarial value variables.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this actuarial value for the highest ordinary silver cost-sharing reduction plan variation.
values:
2014-01-01: 0.94
metadata:
unit: /1
period: year
label: ACA CSR highest silver plan actuarial value
reference:
- title: 45 CFR § 156.420(a)(1)(ii) - Plan variations
href: https://www.law.cornell.edu/cfr/text/45/156.420#a_1_ii
10 changes: 10 additions & 0 deletions policyengine_us/parameters/gov/aca/csr/actuarial_value/lowest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this actuarial value for the lowest ordinary silver cost-sharing reduction plan variation.
values:
2014-01-01: 0.73
metadata:
unit: /1
period: year
label: ACA CSR lowest silver plan actuarial value
reference:
- title: 45 CFR § 156.420(a)(3)(ii) - Plan variations
href: https://www.law.cornell.edu/cfr/text/45/156.420#a_3_ii
10 changes: 10 additions & 0 deletions policyengine_us/parameters/gov/aca/csr/actuarial_value/middle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this actuarial value for the middle ordinary silver cost-sharing reduction plan variation.
values:
2014-01-01: 0.87
metadata:
unit: /1
period: year
label: ACA CSR middle silver plan actuarial value
reference:
- title: 45 CFR § 156.420(a)(2)(ii) - Plan variations
href: https://www.law.cornell.edu/cfr/text/45/156.420#a_2_ii
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this maximum household income threshold for the highest ordinary cost-sharing reduction actuarial value.
values:
2014-01-01: 1.5
metadata:
unit: /1
period: year
label: ACA CSR highest actuarial value income threshold
reference:
- title: 45 CFR § 155.305(g)(2)(i) - Eligibility standards
href: https://www.law.cornell.edu/cfr/text/45/155.305#g_2_i
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this maximum household income threshold for ordinary income-based cost-sharing reductions.
values:
2014-01-01: 2.5
metadata:
unit: /1
period: year
label: ACA CSR maximum income threshold
reference:
- title: 45 CFR § 155.305(g)(1)(i)(C) - Eligibility standards
href: https://www.law.cornell.edu/cfr/text/45/155.305#g_1_i_C
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this maximum household income threshold for the middle ordinary cost-sharing reduction actuarial value.
values:
2014-01-01: 2
metadata:
unit: /1
period: year
label: ACA CSR middle actuarial value income threshold
reference:
- title: 45 CFR § 155.305(g)(2)(ii) - Eligibility standards
href: https://www.law.cornell.edu/cfr/text/45/155.305#g_2_ii
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this actuarial value for bronze Marketplace plans.
values:
2014-01-01: 0.6
metadata:
unit: /1
period: year
label: ACA bronze plan actuarial value
reference:
- title: 45 CFR § 156.140(b)(1) - Levels of coverage
href: https://www.law.cornell.edu/cfr/text/45/156.140#b_1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description: The Affordable Care Act sets this actuarial value for silver Marketplace plans.
values:
2014-01-01: 0.7
metadata:
unit: /1
period: year
label: ACA silver plan actuarial value
reference:
- title: 45 CFR § 156.140(b)(2) - Levels of coverage
href: https://www.law.cornell.edu/cfr/text/45/156.140#b_2
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
- name: Case 1, silver enrollee at 125 percent FPL receives 94 percent AV CSR.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: true
aca_magi_fraction: 1.25
selected_marketplace_plan_category: SILVER
output:
person_receives_aca: true
marketplace_csr_eligible: true
marketplace_csr_category: AV_94
selected_marketplace_plan_actuarial_value: 0.7
marketplace_csr_actuarial_value: 0.94
marketplace_effective_actuarial_value: 0.94

- name: Case 2, silver enrollee at 175 percent FPL receives 87 percent AV CSR.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: true
aca_magi_fraction: 1.75
selected_marketplace_plan_category: SILVER
output:
marketplace_csr_eligible: true
marketplace_csr_category: AV_87
marketplace_csr_actuarial_value: 0.87
marketplace_effective_actuarial_value: 0.87

- name: Case 3, silver enrollee at 225 percent FPL receives 73 percent AV CSR.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: true
aca_magi_fraction: 2.25
selected_marketplace_plan_category: SILVER
output:
marketplace_csr_eligible: true
marketplace_csr_category: AV_73
marketplace_csr_actuarial_value: 0.73
marketplace_effective_actuarial_value: 0.73

- name: Case 4, silver enrollee at 275 percent FPL receives no CSR.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: true
aca_magi_fraction: 2.75
selected_marketplace_plan_category: SILVER
output:
marketplace_csr_eligible: false
marketplace_csr_category: NONE
marketplace_csr_actuarial_value: 0
marketplace_effective_actuarial_value: 0.7

- name: Case 5, APTC-eligible silver enrollee below 100 percent FPL receives 94 percent AV CSR.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: true
aca_magi_fraction: 0.75
selected_marketplace_plan_category: SILVER
output:
person_receives_aca: true
marketplace_csr_eligible: true
marketplace_csr_category: AV_94
marketplace_csr_actuarial_value: 0.94
marketplace_effective_actuarial_value: 0.94
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
- name: Case 1, bronze enrollee is ineligible for ordinary CSR.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: true
aca_magi_fraction: 1.25
selected_marketplace_plan_category: BRONZE
output:
marketplace_csr_eligible: false
marketplace_csr_category: NONE
selected_marketplace_plan_actuarial_value: 0.6
marketplace_csr_actuarial_value: 0
marketplace_effective_actuarial_value: 0.6

- name: Case 2, silver enrollee without PTC eligibility is ineligible for CSR.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: false
aca_magi_fraction: 1.25
selected_marketplace_plan_category: SILVER
output:
person_receives_aca: false
marketplace_csr_eligible: false
marketplace_csr_category: NONE
selected_marketplace_plan_actuarial_value: 0.7
marketplace_csr_actuarial_value: 0
marketplace_effective_actuarial_value: 0.7
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- name: Case 1, CSR changes effective actuarial value but not Marketplace net premium.
absolute_error_margin: 0.001
period: 2026
input:
is_aca_ptc_eligible: true
aca_magi_fraction: 1.25
selected_marketplace_plan_category: SILVER
selected_marketplace_plan_premium_proxy: 5_000
used_aca_ptc: 3_000
output:
selected_marketplace_plan_actuarial_value: 0.7
marketplace_csr_category: AV_94
marketplace_effective_actuarial_value: 0.94
marketplace_net_premium: 2_000
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,17 @@
selected_marketplace_plan_premium_proxy: 8_000
used_aca_ptc: 0
marketplace_net_premium: 8_000

- name: Bronze selected plan net premium uses actual bronze premium.
absolute_error_margin: 0.01
period: 2026
input:
pays_aca_premium: true
selected_marketplace_plan_category: BRONZE
slcsp: 10_000
lcbp: 5_000
aca_ptc: 3_000
output:
selected_marketplace_plan_premium_proxy: 5_000
used_aca_ptc: 3_000
marketplace_net_premium: 2_000
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,26 @@
pays_aca_premium: true
is_aca_ptc_eligible: false
selected_marketplace_plan_premium_proxy: 8_000

- name: Case 6, bronze selected plan uses the lowest-cost bronze premium.
absolute_error_margin: 0.01
period: 2026
input:
pays_aca_premium: true
selected_marketplace_plan_category: BRONZE
slcsp: 10_000
lcbp: 6_500
output:
selected_marketplace_plan_premium_proxy: 6_500

- name: Case 7, silver selected plan keeps the benchmark-ratio proxy.
absolute_error_margin: 0.01
period: 2026
input:
pays_aca_premium: true
selected_marketplace_plan_category: SILVER
slcsp: 10_000
lcbp: 6_500
selected_marketplace_plan_benchmark_ratio: 0.9
output:
selected_marketplace_plan_premium_proxy: 9_000
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
used_aca_ptc: 200
unused_aca_ptc: 0

- name: Case 2, a bronze-like ratio leaves some ACA PTC unused.
- name: Case 2, a lower-than-benchmark selected-plan ratio leaves some ACA PTC unused.
absolute_error_margin: 0.01
period: 2025
input:
Expand Down Expand Up @@ -56,3 +56,21 @@
selected_marketplace_plan_premium_proxy: 0
used_aca_ptc: 0
unused_aca_ptc: 200

- name: Case 5, bronze selected plan uses actual bronze premium before applying PTC.
absolute_error_margin: 0.01
period: 2026
input:
is_aca_ptc_eligible: true
pays_aca_premium: true
selected_marketplace_plan_category: BRONZE
slcsp: 10_000
lcbp: 7_000
aca_magi: 20_000
aca_required_contribution_percentage: 0.04
tax_unit_is_filer: true
output:
aca_ptc: 9_200
selected_marketplace_plan_premium_proxy: 7_000
used_aca_ptc: 7_000
unused_aca_ptc: 2_200
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from policyengine_us.model_api import *
from policyengine_us.variables.gov.aca.csr.marketplace_csr_category import (
MarketplaceCSRCategory,
)


class marketplace_csr_actuarial_value(Variable):
value_type = float
entity = TaxUnit
label = "Marketplace cost-sharing reduction actuarial value"
unit = "/1"
definition_period = YEAR
reference = "https://www.law.cornell.edu/cfr/text/45/156.420#a"
defined_for = "marketplace_csr_eligible"

def formula(tax_unit, period, parameters):
category = tax_unit("marketplace_csr_category", period)
p = parameters(period).gov.aca.csr.actuarial_value
return select(
[
category == MarketplaceCSRCategory.AV_94,
category == MarketplaceCSRCategory.AV_87,
category == MarketplaceCSRCategory.AV_73,
],
[p.highest, p.middle, p.lowest],
)
36 changes: 36 additions & 0 deletions policyengine_us/variables/gov/aca/csr/marketplace_csr_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from policyengine_us.model_api import *


class MarketplaceCSRCategory(Enum):
NONE = "None"
AV_94 = "94 percent actuarial value"
AV_87 = "87 percent actuarial value"
AV_73 = "73 percent actuarial value"


class marketplace_csr_category(Variable):
value_type = Enum
possible_values = MarketplaceCSRCategory
default_value = MarketplaceCSRCategory.NONE
entity = TaxUnit
label = "Marketplace cost-sharing reduction category"
definition_period = YEAR
reference = "https://www.law.cornell.edu/cfr/text/45/155.305#g_2"

def formula(tax_unit, period, parameters):
eligible = tax_unit("marketplace_csr_eligible", period)
magi_fraction = tax_unit("aca_magi_fraction", period)
p = parameters(period).gov.aca.csr.income_threshold
return select(
[
eligible & (magi_fraction <= p.highest_av_maximum),
eligible & (magi_fraction <= p.middle_av_maximum),
eligible & (magi_fraction <= p.maximum),
],
[
MarketplaceCSRCategory.AV_94,
MarketplaceCSRCategory.AV_87,
MarketplaceCSRCategory.AV_73,
],
default=MarketplaceCSRCategory.NONE,
)
23 changes: 23 additions & 0 deletions policyengine_us/variables/gov/aca/csr/marketplace_csr_eligible.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from policyengine_us.model_api import *
from policyengine_us.variables.gov.aca.ptc.selected_marketplace_plan_category import (
MarketplacePlanCategory,
)


class marketplace_csr_eligible(Variable):
value_type = bool
entity = TaxUnit
label = "Tax unit is eligible for ordinary Marketplace cost-sharing reductions"
definition_period = YEAR
reference = "https://www.law.cornell.edu/cfr/text/45/155.305#g_1"

def formula(tax_unit, period, parameters):
person = tax_unit.members
receives_aca = tax_unit.sum(person("person_receives_aca", period)) > 0
category = tax_unit("selected_marketplace_plan_category", period)
silver_selected = category == MarketplacePlanCategory.SILVER
magi_fraction = tax_unit("aca_magi_fraction", period)
income_eligible = (
magi_fraction <= parameters(period).gov.aca.csr.income_threshold.maximum
)
return receives_aca & silver_selected & income_eligible
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from policyengine_us.model_api import *


class marketplace_effective_actuarial_value(Variable):
value_type = float
entity = TaxUnit
label = "Marketplace selected plan effective actuarial value"
unit = "/1"
definition_period = YEAR
reference = (
"https://www.law.cornell.edu/cfr/text/45/156.140#b",
"https://www.law.cornell.edu/cfr/text/45/156.420#a",
)

def formula(tax_unit, period, parameters):
selected_plan_av = tax_unit("selected_marketplace_plan_actuarial_value", period)
csr_av = tax_unit("marketplace_csr_actuarial_value", period)
return max_(selected_plan_av, csr_av)
Loading
Loading