policyengine-us 1.351.3__py3-none-any.whl → 1.351.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of policyengine-us might be problematic. Click here for more details.
- policyengine_us/reforms/reforms.py +0 -7
- policyengine_us/tests/policy/baseline/income/spm_unit_income_decile.yaml +0 -18
- policyengine_us/variables/household/income/spm_unit/spm_unit_income_decile.py +1 -2
- {policyengine_us-1.351.3.dist-info → policyengine_us-1.351.5.dist-info}/METADATA +1 -1
- {policyengine_us-1.351.3.dist-info → policyengine_us-1.351.5.dist-info}/RECORD +8 -11
- policyengine_us/reforms/second_earner/__init__.py +0 -3
- policyengine_us/reforms/second_earner/second_earner_tax_reform.py +0 -820
- policyengine_us/tests/policy/contrib/second_earner/second_earner_tax_reform.yaml +0 -371
- {policyengine_us-1.351.3.dist-info → policyengine_us-1.351.5.dist-info}/WHEEL +0 -0
- {policyengine_us-1.351.3.dist-info → policyengine_us-1.351.5.dist-info}/entry_points.txt +0 -0
- {policyengine_us-1.351.3.dist-info → policyengine_us-1.351.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -63,9 +63,6 @@ from .ctc import (
|
|
|
63
63
|
create_ctc_older_child_supplement_reform,
|
|
64
64
|
create_ctc_additional_bracket_reform,
|
|
65
65
|
)
|
|
66
|
-
from .second_earner import (
|
|
67
|
-
create_second_earner_tax_reform,
|
|
68
|
-
)
|
|
69
66
|
from .snap import (
|
|
70
67
|
create_abolish_snap_deductions_reform,
|
|
71
68
|
create_abolish_snap_net_income_test_reform,
|
|
@@ -192,9 +189,6 @@ def create_structural_reforms_from_parameters(parameters, period):
|
|
|
192
189
|
ctc_older_child_supplement = create_ctc_older_child_supplement_reform(
|
|
193
190
|
parameters, period
|
|
194
191
|
)
|
|
195
|
-
second_earner_tax_reform = create_second_earner_tax_reform(
|
|
196
|
-
parameters, period
|
|
197
|
-
)
|
|
198
192
|
abolish_snap_deductions = create_abolish_snap_deductions_reform(
|
|
199
193
|
parameters, period
|
|
200
194
|
)
|
|
@@ -301,7 +295,6 @@ def create_structural_reforms_from_parameters(parameters, period):
|
|
|
301
295
|
salt_phase_out,
|
|
302
296
|
repeal_state_dependent_exemptions,
|
|
303
297
|
ctc_older_child_supplement,
|
|
304
|
-
second_earner_tax_reform,
|
|
305
298
|
abolish_snap_deductions,
|
|
306
299
|
abolish_snap_net_income_test,
|
|
307
300
|
dc_property_tax_credit,
|
|
@@ -55,21 +55,3 @@
|
|
|
55
55
|
state_code: CA
|
|
56
56
|
output:
|
|
57
57
|
spm_unit_income_decile: 10
|
|
58
|
-
|
|
59
|
-
- name: Zero weight SPM unit does not get assigned a decile
|
|
60
|
-
period: 2024
|
|
61
|
-
input:
|
|
62
|
-
people:
|
|
63
|
-
person1:
|
|
64
|
-
age: 30
|
|
65
|
-
spm_units:
|
|
66
|
-
spm_unit1:
|
|
67
|
-
members: [person1]
|
|
68
|
-
spm_unit_oecd_equiv_net_income: 25_000
|
|
69
|
-
spm_unit_weight: 0
|
|
70
|
-
households:
|
|
71
|
-
household1:
|
|
72
|
-
members: [person1]
|
|
73
|
-
state_code: CA
|
|
74
|
-
output:
|
|
75
|
-
spm_unit_income_decile: 0
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from policyengine_us.model_api import *
|
|
2
|
+
from microdf import MicroSeries
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class spm_unit_income_decile(Variable):
|
|
@@ -9,8 +10,6 @@ class spm_unit_income_decile(Variable):
|
|
|
9
10
|
definition_period = YEAR
|
|
10
11
|
|
|
11
12
|
def formula(spm_unit, period, parameters):
|
|
12
|
-
from microdf import MicroSeries
|
|
13
|
-
|
|
14
13
|
income = spm_unit("spm_unit_oecd_equiv_net_income", period)
|
|
15
14
|
weights = spm_unit("spm_unit_weight", period) * spm_unit.nb_persons()
|
|
16
15
|
return MicroSeries(income, weights=weights).decile_rank()
|
|
@@ -3014,7 +3014,7 @@ policyengine_us/params_on_demand/gov/hhs/medicaid/geography/medicaid_rating_area
|
|
|
3014
3014
|
policyengine_us/reforms/__init__.py,sha256=FPV8k2633kzUhbKUK8jC6yJONbnZ5n9zLAq2UL57KH4,113
|
|
3015
3015
|
policyengine_us/reforms/dc_kccatc.py,sha256=LyGMfEKe-0TgQ-2vCYGOD8W-EGEW8_DgIqCQP89qDyg,4283
|
|
3016
3016
|
policyengine_us/reforms/dc_tax_threshold_joint_ratio.py,sha256=G-5E1EJFGZ3VeUl_fuyj82nMIttHRNRdlT-x98koJrk,1633
|
|
3017
|
-
policyengine_us/reforms/reforms.py,sha256=
|
|
3017
|
+
policyengine_us/reforms/reforms.py,sha256=9DUPk18pt7__WmlGSOLHU12Ym7XDdKCuaeqnEEidVyQ,11733
|
|
3018
3018
|
policyengine_us/reforms/taxsim.py,sha256=bXNFWfjBX5USld1C7fziT6BBmRy-avz00QtL8WmCHy0,5276
|
|
3019
3019
|
policyengine_us/reforms/winship.py,sha256=_q74Af1nkmoh0-M6PZJ2FcJAn6v5zf5sAEgvxjwHwyA,3069
|
|
3020
3020
|
policyengine_us/reforms/additional_tax_bracket/__init__.py,sha256=087GDzojnzkbARUgGTQDMNVWJzjtNZvBGr46jfu1kXc,89
|
|
@@ -3083,8 +3083,6 @@ policyengine_us/reforms/reconciliation/reconciliation_charitable_deduction.py,sh
|
|
|
3083
3083
|
policyengine_us/reforms/reconciliation/reconciliation_qbid_with_floor.py,sha256=EQWZ6d550cvFa1OTT9H2c6-076k0ooP1JKJqA77sjBU,2596
|
|
3084
3084
|
policyengine_us/reforms/salt_phase_out/__init__.py,sha256=hrFYpSJFxELcG5l2xg38-3lT5oAqBpTGAxG8U5Jcd7E,73
|
|
3085
3085
|
policyengine_us/reforms/salt_phase_out/salt_phase_out_reform.py,sha256=OfNb_kkd8ohfjchIStNaGtaphK-3eBPufWA2QTLzGlo,1823
|
|
3086
|
-
policyengine_us/reforms/second_earner/__init__.py,sha256=pTtUV6BuWBPjUyp_Bj6YDbN0pyygzFw4aiMwYSlYggI,79
|
|
3087
|
-
policyengine_us/reforms/second_earner/second_earner_tax_reform.py,sha256=iv33aMPnTModp0A3yRrI5ITrQUDLD5GuXEtPX_t7Quk,32572
|
|
3088
3086
|
policyengine_us/reforms/snap/__init__.py,sha256=p98y33zLWFe0CMvINQzRAa6av-yHuejyBFYbciOEC4c,178
|
|
3089
3087
|
policyengine_us/reforms/snap/abolish_snap_deductions.py,sha256=Ad4J4_qiCXa-ORIxWRCD372ITJiCRzdvqRedHOXX5dw,1032
|
|
3090
3088
|
policyengine_us/reforms/snap/abolish_snap_net_income_test.py,sha256=KoWaDtPkYr5mLt-xcMT6UkmVcCo0UDRYaMVRfiCm9Rs,1166
|
|
@@ -5009,7 +5007,7 @@ policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_is_in_s
|
|
|
5009
5007
|
policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_market_income.yaml,sha256=gd9JLw32eDURuKYPjxwQZhyRV_6JBWcAm8qk83Tpuus,276
|
|
5010
5008
|
policyengine_us/tests/policy/baseline/household/income/spm_unit/spm_unit_net_income.yaml,sha256=lZorN8LQYPCNpHDriLdLbaJ8vg3kHHK_UIVcbo7tkdk,218
|
|
5011
5009
|
policyengine_us/tests/policy/baseline/household/income/tax_unit/spouse_separate_adjusted_gross_income.yaml,sha256=zNhFBR3IFmCJjnScfTvpVfmUv3Xl-yIXKlFA3pNjwsg,373
|
|
5012
|
-
policyengine_us/tests/policy/baseline/income/spm_unit_income_decile.yaml,sha256=
|
|
5010
|
+
policyengine_us/tests/policy/baseline/income/spm_unit_income_decile.yaml,sha256=1wLKnDqXKVBadZKYVGYlA1NpsS8VgHAlnV9JU97IRf4,1263
|
|
5013
5011
|
policyengine_us/tests/policy/contrib/dc_kccatc.yaml,sha256=v4woAJveF3mZH6d4W3xAYlejcTIHTEQZM4nnenGNq-8,1786
|
|
5014
5012
|
policyengine_us/tests/policy/contrib/dc_single_joint_threshold_ratio.yaml,sha256=vDMmkKdvjCtR8uweKDptp1gt05OI78Pm7GoIL0Apxxg,632
|
|
5015
5013
|
policyengine_us/tests/policy/contrib/reported_state_income_tax.yaml,sha256=697RFAYWbmvD4LdQA-RHnIJ8nuu9wwEc2IRejdJ4QAQ,232
|
|
@@ -5052,7 +5050,6 @@ policyengine_us/tests/policy/contrib/reconciliation/reconciliation_cdcc.yaml,sha
|
|
|
5052
5050
|
policyengine_us/tests/policy/contrib/reconciliation/reconciliation_charitable_deduction.yaml,sha256=FeuKCLKePa4G-bWVcCGiK5CFmxK3nwppH3xEqKCRZ50,2336
|
|
5053
5051
|
policyengine_us/tests/policy/contrib/reconciliation/reconciliation_qbid_with_floor.yaml,sha256=GrZzqHljo8pYanbg3HQ0UapuVEgXkteq9gazH13wmxY,1386
|
|
5054
5052
|
policyengine_us/tests/policy/contrib/salt_phase_out/salt_phase_out_reform.yaml,sha256=xOwKAjQm-c191Ig2JoosB541CrQ8Xl4SSfXqUvvZmps,3602
|
|
5055
|
-
policyengine_us/tests/policy/contrib/second_earner/second_earner_tax_reform.yaml,sha256=FAEAJplFE6y93Yo2y6ikOCjn6afbKzE168cU32_PcV0,10836
|
|
5056
5053
|
policyengine_us/tests/policy/contrib/snap/abolish_snap_deductions.yaml,sha256=5pgcUuafSNIF2dWsBHMebB7YSrRq9svD0SkzJcvy6po,467
|
|
5057
5054
|
policyengine_us/tests/policy/contrib/snap/abolish_snap_net_income_test.yaml,sha256=8zy1seb0mfTruajlBK01Vl1vajlABDQak0P-lWmwG98,427
|
|
5058
5055
|
policyengine_us/tests/policy/contrib/snap_ea/mid_year_snap_ea_reform.py,sha256=ABpm6JVBoziFM3hKvil1xLkWOiz60c9UmcTl8rz_40E,410
|
|
@@ -8094,7 +8091,7 @@ policyengine_us/variables/household/income/spm_unit/spm_unit_capped_housing_subs
|
|
|
8094
8091
|
policyengine_us/variables/household/income/spm_unit/spm_unit_energy_subsidy.py,sha256=4sikpqROToak71R57YEFthjxabRoVo0tK1XVMSMtxQ4,488
|
|
8095
8092
|
policyengine_us/variables/household/income/spm_unit/spm_unit_energy_subsidy_reported.py,sha256=4FYjIyyXCK1Wsiakq1aFs9mItOGy4rrcTWOH4tbIrHU,271
|
|
8096
8093
|
policyengine_us/variables/household/income/spm_unit/spm_unit_fips.py,sha256=5QDrBrIraBnRRSXwZfsTO-sIYLwdLORTiNdwBiUOalo,295
|
|
8097
|
-
policyengine_us/variables/household/income/spm_unit/spm_unit_income_decile.py,sha256=
|
|
8094
|
+
policyengine_us/variables/household/income/spm_unit/spm_unit_income_decile.py,sha256=P7RIRqa1L-Nn-Rt_i0IkWN1NAbtiRmz2g9XUoNTYDDw,584
|
|
8098
8095
|
policyengine_us/variables/household/income/spm_unit/spm_unit_is_in_deep_spm_poverty.py,sha256=epHelbN5RdzUM3DIVy_ON8Mf8N7Lc_-zxZ7CeJn-pq8,428
|
|
8099
8096
|
policyengine_us/variables/household/income/spm_unit/spm_unit_is_in_spm_poverty.py,sha256=0fVppPyrvQuu4hBHbl44TfXrEaKyqX5oJqKMZHc9fcY,414
|
|
8100
8097
|
policyengine_us/variables/household/income/spm_unit/spm_unit_market_income.py,sha256=GpSFUcSEsBYWVBZBR3VmdMgIMMMTHYCizvalPzlF0rk,228
|
|
@@ -8122,8 +8119,8 @@ policyengine_us/variables/input/farm_income.py,sha256=BEKxYmHNNnWJAAvULl5qZJigy5
|
|
|
8122
8119
|
policyengine_us/variables/input/geography.py,sha256=XmBlgXhzBoLRKk6R8taVZHqUw1eU8MbNeGS9iJ7_l44,4506
|
|
8123
8120
|
policyengine_us/variables/input/self_employment_income.py,sha256=PwsGz8R4lRikKWUYOhsC0qosNNLXq4f5SQmfw4S3mk8,511
|
|
8124
8121
|
policyengine_us/variables/input/self_employment_income_before_lsr.py,sha256=E8fcX9Nlyqz8dziHhQv_euutdmoIwFMMWePUwbbwv_w,379
|
|
8125
|
-
policyengine_us-1.351.
|
|
8126
|
-
policyengine_us-1.351.
|
|
8127
|
-
policyengine_us-1.351.
|
|
8128
|
-
policyengine_us-1.351.
|
|
8129
|
-
policyengine_us-1.351.
|
|
8122
|
+
policyengine_us-1.351.5.dist-info/METADATA,sha256=G7kIwoeS_BGXfygItInB6H8iTnl5VtB_6jtHffJJnt4,1693
|
|
8123
|
+
policyengine_us-1.351.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
8124
|
+
policyengine_us-1.351.5.dist-info/entry_points.txt,sha256=MLaqNyNTbReALyKNkde85VkuFFpdPWAcy8VRG1mjczc,57
|
|
8125
|
+
policyengine_us-1.351.5.dist-info/licenses/LICENSE,sha256=2N5ReRelkdqkR9a-KP-y-shmcD5P62XoYiG-miLTAzo,34519
|
|
8126
|
+
policyengine_us-1.351.5.dist-info/RECORD,,
|
|
@@ -1,820 +0,0 @@
|
|
|
1
|
-
from policyengine_us.model_api import *
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def create_second_earner_tax() -> Reform:
|
|
5
|
-
|
|
6
|
-
class is_primary_earner(Variable):
|
|
7
|
-
value_type = bool
|
|
8
|
-
entity = Person
|
|
9
|
-
label = "Whether this person is the primary earner in their tax unit"
|
|
10
|
-
definition_period = YEAR
|
|
11
|
-
|
|
12
|
-
def formula(person, period, parameters):
|
|
13
|
-
earned_income = person("earned_income", period)
|
|
14
|
-
is_tax_unit_head_or_spouse = person(
|
|
15
|
-
"is_tax_unit_head_or_spouse", period
|
|
16
|
-
)
|
|
17
|
-
is_tax_unit_head = person("is_tax_unit_head", period)
|
|
18
|
-
is_tax_unit_dependent = person("is_tax_unit_dependent", period)
|
|
19
|
-
|
|
20
|
-
# Add dependent income to head's income
|
|
21
|
-
dependent_income = (earned_income * is_tax_unit_dependent).sum()
|
|
22
|
-
earner_income = earned_income * is_tax_unit_head_or_spouse
|
|
23
|
-
earner_income = where(
|
|
24
|
-
is_tax_unit_head,
|
|
25
|
-
earner_income + dependent_income,
|
|
26
|
-
earner_income,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
max_income = person.tax_unit.max(earner_income)
|
|
30
|
-
return (earner_income == max_income) & (
|
|
31
|
-
(
|
|
32
|
-
earner_income
|
|
33
|
-
> person.tax_unit.max(
|
|
34
|
-
where(~is_tax_unit_head, earner_income, 0)
|
|
35
|
-
)
|
|
36
|
-
)
|
|
37
|
-
| is_tax_unit_head
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
class taxable_income_person(Variable):
|
|
41
|
-
value_type = float
|
|
42
|
-
entity = Person
|
|
43
|
-
label = "IRS taxable income for each person"
|
|
44
|
-
unit = USD
|
|
45
|
-
definition_period = YEAR
|
|
46
|
-
|
|
47
|
-
def formula(person, period, parameters):
|
|
48
|
-
agi = person("adjusted_gross_income_person", period)
|
|
49
|
-
exemption_amount = person.tax_unit("exemptions", period)
|
|
50
|
-
is_joint = person.tax_unit("tax_unit_is_joint", period)
|
|
51
|
-
exemptions = where(
|
|
52
|
-
is_joint, exemption_amount / 2, exemption_amount
|
|
53
|
-
)
|
|
54
|
-
deductions = person("taxable_income_deductions_person", period)
|
|
55
|
-
return max_(0, agi - exemptions - deductions)
|
|
56
|
-
|
|
57
|
-
class income_tax_main_rates(Variable):
|
|
58
|
-
value_type = float
|
|
59
|
-
entity = TaxUnit
|
|
60
|
-
definition_period = YEAR
|
|
61
|
-
label = "Income tax main rates"
|
|
62
|
-
reference = "https://www.law.cornell.edu/uscode/text/26/1"
|
|
63
|
-
unit = USD
|
|
64
|
-
|
|
65
|
-
def formula(tax_unit, period, parameters):
|
|
66
|
-
person = tax_unit.members
|
|
67
|
-
full_taxable_income = person("taxable_income_person", period)
|
|
68
|
-
is_tax_unit_head_or_spouse = person(
|
|
69
|
-
"is_tax_unit_head_or_spouse", period
|
|
70
|
-
)
|
|
71
|
-
cg_exclusion = (
|
|
72
|
-
tax_unit("capital_gains_excluded_from_taxable_income", period)
|
|
73
|
-
/ 2
|
|
74
|
-
) * is_tax_unit_head_or_spouse
|
|
75
|
-
taxinc = max_(0, full_taxable_income - cg_exclusion)
|
|
76
|
-
p = parameters(period).gov.irs.income
|
|
77
|
-
bracket_tops = p.bracket.thresholds
|
|
78
|
-
bracket_rates = p.bracket.rates
|
|
79
|
-
filing_status = tax_unit("filing_status", period)
|
|
80
|
-
|
|
81
|
-
# Determine primary and secondary earner incomes based on income size
|
|
82
|
-
is_tax_unit_dependent = person("is_tax_unit_dependent", period)
|
|
83
|
-
|
|
84
|
-
# Add dependent income to head's income
|
|
85
|
-
dependent_income = (taxinc * is_tax_unit_dependent).sum()
|
|
86
|
-
earner_taxinc = taxinc * is_tax_unit_head_or_spouse
|
|
87
|
-
|
|
88
|
-
is_primary_earner = person("is_primary_earner", period)
|
|
89
|
-
is_secondary_earner = (
|
|
90
|
-
is_tax_unit_head_or_spouse & ~is_primary_earner
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
taxable_income_primary_earner = where(
|
|
94
|
-
is_primary_earner, earner_taxinc + dependent_income, 0
|
|
95
|
-
).sum()
|
|
96
|
-
taxable_income_secondary_earner = where(
|
|
97
|
-
is_secondary_earner, earner_taxinc, 0
|
|
98
|
-
).sum()
|
|
99
|
-
|
|
100
|
-
# Calculate primary earner tax using actual filing status
|
|
101
|
-
primary_earner_tax = 0
|
|
102
|
-
bracket_bottom = 0
|
|
103
|
-
for i in range(1, len(list(bracket_rates.__iter__())) + 1):
|
|
104
|
-
b = str(i)
|
|
105
|
-
bracket_top = bracket_tops[b][filing_status]
|
|
106
|
-
primary_earner_tax += bracket_rates[b] * amount_between(
|
|
107
|
-
taxable_income_primary_earner, bracket_bottom, bracket_top
|
|
108
|
-
)
|
|
109
|
-
bracket_bottom = bracket_top
|
|
110
|
-
|
|
111
|
-
# Calculate secondary earner tax using single filing status
|
|
112
|
-
secondary_earner_tax = 0
|
|
113
|
-
bracket_bottom = 0
|
|
114
|
-
single_status = "SINGLE"
|
|
115
|
-
for i in range(1, len(list(bracket_rates.__iter__())) + 1):
|
|
116
|
-
b = str(i)
|
|
117
|
-
bracket_top = bracket_tops[b][single_status]
|
|
118
|
-
secondary_earner_tax += bracket_rates[b] * amount_between(
|
|
119
|
-
taxable_income_secondary_earner,
|
|
120
|
-
bracket_bottom,
|
|
121
|
-
bracket_top,
|
|
122
|
-
)
|
|
123
|
-
bracket_bottom = bracket_top
|
|
124
|
-
|
|
125
|
-
return primary_earner_tax + secondary_earner_tax
|
|
126
|
-
|
|
127
|
-
class basic_standard_deduction_person(Variable):
|
|
128
|
-
value_type = float
|
|
129
|
-
entity = Person
|
|
130
|
-
label = "Basic standard deduction"
|
|
131
|
-
definition_period = YEAR
|
|
132
|
-
unit = USD
|
|
133
|
-
reference = "https://www.law.cornell.edu/uscode/text/26/63#c_2"
|
|
134
|
-
|
|
135
|
-
def formula(person, period, parameters):
|
|
136
|
-
std = parameters(period).gov.irs.deductions.standard
|
|
137
|
-
filing_status = person.tax_unit("filing_status", period)
|
|
138
|
-
separate_filer_itemizes = person.tax_unit(
|
|
139
|
-
"separate_filer_itemizes", period
|
|
140
|
-
)
|
|
141
|
-
dependent_elsewhere = person.tax_unit(
|
|
142
|
-
"head_is_dependent_elsewhere", period
|
|
143
|
-
)
|
|
144
|
-
# Determine primary and secondary earners
|
|
145
|
-
is_tax_unit_head_or_spouse = person(
|
|
146
|
-
"is_tax_unit_head_or_spouse", period
|
|
147
|
-
)
|
|
148
|
-
is_primary_earner = person("is_primary_earner", period)
|
|
149
|
-
is_secondary_earner = (
|
|
150
|
-
is_tax_unit_head_or_spouse & ~is_primary_earner
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
# Calculate primary earner deduction using actual filing status
|
|
154
|
-
primary_deduction = std.amount[filing_status]
|
|
155
|
-
|
|
156
|
-
# Calculate secondary earner deduction using single filing status
|
|
157
|
-
secondary_deduction = std.amount["SINGLE"]
|
|
158
|
-
# Combine deductions based on earner status
|
|
159
|
-
standard_deduction = where(
|
|
160
|
-
is_primary_earner,
|
|
161
|
-
primary_deduction,
|
|
162
|
-
where(is_secondary_earner, secondary_deduction, 0),
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
standard_deduction_if_dependent = min_(
|
|
166
|
-
standard_deduction,
|
|
167
|
-
max_(
|
|
168
|
-
std.dependent.additional_earned_income
|
|
169
|
-
+ person.tax_unit("tax_unit_earned_income", period),
|
|
170
|
-
std.dependent.amount,
|
|
171
|
-
),
|
|
172
|
-
)
|
|
173
|
-
|
|
174
|
-
return select(
|
|
175
|
-
[
|
|
176
|
-
separate_filer_itemizes,
|
|
177
|
-
dependent_elsewhere,
|
|
178
|
-
True,
|
|
179
|
-
],
|
|
180
|
-
[
|
|
181
|
-
0,
|
|
182
|
-
standard_deduction_if_dependent,
|
|
183
|
-
standard_deduction,
|
|
184
|
-
],
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
class additional_standard_deduction_person(Variable):
|
|
188
|
-
value_type = float
|
|
189
|
-
entity = Person
|
|
190
|
-
label = "Additional standard deduction for each person"
|
|
191
|
-
unit = USD
|
|
192
|
-
definition_period = YEAR
|
|
193
|
-
reference = "https://www.law.cornell.edu/uscode/text/26/63#f"
|
|
194
|
-
|
|
195
|
-
def formula(person, period, parameters):
|
|
196
|
-
std = parameters(period).gov.irs.deductions.standard
|
|
197
|
-
filing_status = person.tax_unit("filing_status", period)
|
|
198
|
-
is_blind = person("is_blind", period).astype(int)
|
|
199
|
-
age_threshold = parameters(
|
|
200
|
-
period
|
|
201
|
-
).gov.irs.deductions.standard.aged_or_blind.age_threshold
|
|
202
|
-
is_aged = (person("age", period) >= age_threshold).astype(int)
|
|
203
|
-
aged_blind = is_blind + is_aged
|
|
204
|
-
primary_earner = person("is_primary_earner", period)
|
|
205
|
-
amount = where(
|
|
206
|
-
primary_earner,
|
|
207
|
-
std.aged_or_blind.amount[filing_status],
|
|
208
|
-
std.aged_or_blind.amount["SINGLE"],
|
|
209
|
-
)
|
|
210
|
-
return aged_blind * amount
|
|
211
|
-
|
|
212
|
-
class bonus_guaranteed_deduction_person(Variable):
|
|
213
|
-
value_type = float
|
|
214
|
-
entity = Person
|
|
215
|
-
label = "Bonus guaranteed deduction"
|
|
216
|
-
unit = USD
|
|
217
|
-
definition_period = YEAR
|
|
218
|
-
reference = "https://waysandmeans.house.gov/malliotakis-steel-lead-legislation-to-provide-tax-relief-to-working-families/"
|
|
219
|
-
|
|
220
|
-
def formula(person, period, parameters):
|
|
221
|
-
filing_status = person.tax_unit("filing_status", period)
|
|
222
|
-
wftca = parameters(
|
|
223
|
-
period
|
|
224
|
-
).gov.contrib.congress.wftca.bonus_guaranteed_deduction
|
|
225
|
-
primary_earner = person("is_primary_earner", period)
|
|
226
|
-
amount = where(
|
|
227
|
-
primary_earner,
|
|
228
|
-
wftca.amount[filing_status],
|
|
229
|
-
wftca.amount["SINGLE"],
|
|
230
|
-
)
|
|
231
|
-
agi = person("adjusted_gross_income_person", period)
|
|
232
|
-
threshold = where(
|
|
233
|
-
primary_earner,
|
|
234
|
-
wftca.phase_out.threshold[filing_status],
|
|
235
|
-
wftca.phase_out.threshold["SINGLE"],
|
|
236
|
-
)
|
|
237
|
-
income_in_phase_out_region = max_(agi - threshold, 0)
|
|
238
|
-
reduction = wftca.phase_out.rate * income_in_phase_out_region
|
|
239
|
-
return max_(amount - reduction, 0)
|
|
240
|
-
|
|
241
|
-
class standard_deduction_person(Variable):
|
|
242
|
-
value_type = float
|
|
243
|
-
entity = Person
|
|
244
|
-
label = "Standard deduction for each person"
|
|
245
|
-
unit = USD
|
|
246
|
-
definition_period = YEAR
|
|
247
|
-
reference = "https://www.law.cornell.edu/uscode/text/26/63#c"
|
|
248
|
-
|
|
249
|
-
def formula(person, period, parameters):
|
|
250
|
-
basic_deduction = person("basic_standard_deduction_person", period)
|
|
251
|
-
additional_deduction = person(
|
|
252
|
-
"additional_standard_deduction_person", period
|
|
253
|
-
)
|
|
254
|
-
bonus_deduction = person(
|
|
255
|
-
"bonus_guaranteed_deduction_person", period
|
|
256
|
-
)
|
|
257
|
-
return basic_deduction + additional_deduction + bonus_deduction
|
|
258
|
-
|
|
259
|
-
class taxable_income_deductions_person(Variable):
|
|
260
|
-
value_type = float
|
|
261
|
-
entity = Person
|
|
262
|
-
label = "Taxable income deductions for each person"
|
|
263
|
-
unit = USD
|
|
264
|
-
definition_period = YEAR
|
|
265
|
-
|
|
266
|
-
def formula(person, period, parameters):
|
|
267
|
-
itemizes = person.tax_unit("tax_unit_itemizes", period)
|
|
268
|
-
is_joint = person.tax_unit("tax_unit_is_joint", period)
|
|
269
|
-
deductions_if_itemizing_amount = person.tax_unit(
|
|
270
|
-
"taxable_income_deductions_if_itemizing", period
|
|
271
|
-
)
|
|
272
|
-
deductions_if_itemizing = where(
|
|
273
|
-
is_joint,
|
|
274
|
-
deductions_if_itemizing_amount / 2,
|
|
275
|
-
deductions_if_itemizing_amount,
|
|
276
|
-
)
|
|
277
|
-
standard_deduction = person("standard_deduction_person", period)
|
|
278
|
-
qbid = person("qualified_business_income_deduction_person", period)
|
|
279
|
-
return where(
|
|
280
|
-
itemizes, deductions_if_itemizing, standard_deduction + qbid
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
class net_capital_gain_person(Variable):
|
|
284
|
-
value_type = float
|
|
285
|
-
entity = Person
|
|
286
|
-
label = "Net capital gain"
|
|
287
|
-
unit = USD
|
|
288
|
-
documentation = (
|
|
289
|
-
"The excess of net long-term capital gain over net short-term capital"
|
|
290
|
-
'loss, plus qualified dividends (the definition of "net capital gain"'
|
|
291
|
-
"which applies to 26 U.S.C. § 1(h) from § 1(h)(11))."
|
|
292
|
-
)
|
|
293
|
-
definition_period = YEAR
|
|
294
|
-
reference = dict(
|
|
295
|
-
title="26 U.S. Code § 1222(11)",
|
|
296
|
-
href="https://www.law.cornell.edu/uscode/text/26/1222#11",
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
def formula(person, period, parameters):
|
|
300
|
-
lt_capital_gain = person("long_term_capital_gains", period)
|
|
301
|
-
st_capital_loss = -person("short_term_capital_gains", period)
|
|
302
|
-
net_cap_gain = max_(0, lt_capital_gain - st_capital_loss)
|
|
303
|
-
qual_div_income = person("qualified_dividend_income", period)
|
|
304
|
-
return net_cap_gain + qual_div_income
|
|
305
|
-
|
|
306
|
-
class adjusted_net_capital_gain_person(Variable):
|
|
307
|
-
value_type = float
|
|
308
|
-
entity = Person
|
|
309
|
-
label = "Adjusted net capital gain"
|
|
310
|
-
unit = USD
|
|
311
|
-
documentation = "The excess of net long-term capital gain over net short-term capital loss."
|
|
312
|
-
definition_period = YEAR
|
|
313
|
-
reference = dict(
|
|
314
|
-
title="26 U.S. Code § 1(h)(3)",
|
|
315
|
-
href="https://www.law.cornell.edu/uscode/text/26/1#h_3",
|
|
316
|
-
)
|
|
317
|
-
defined_for = "is_tax_unit_head_or_spouse"
|
|
318
|
-
|
|
319
|
-
def formula(person, period, parameters):
|
|
320
|
-
net_capital_gain = person("net_capital_gain_person", period)
|
|
321
|
-
# The law actually uses the original definition of 'net capital gain' which does not include
|
|
322
|
-
# qualified dividend income, but separately adds qualified dividends here. The definition of
|
|
323
|
-
# 'net capital gain' in the variable 'net_capital_gain' actually has some very specific exclusion
|
|
324
|
-
# criteria for particular types of dividends and companies, so it's not an *exact* fit to the
|
|
325
|
-
# definition here, but it's a good enough approximation. See 26 U.S. Code § 1(h)(11)(B) for the
|
|
326
|
-
# definition of 'net capital gain' for the above variable, and 26 U.S. Code § 1(h)(3) for the definition
|
|
327
|
-
# of adjusted net capital gain (this variable).
|
|
328
|
-
qualified_dividend_income = person(
|
|
329
|
-
"qualified_dividend_income", period
|
|
330
|
-
)
|
|
331
|
-
is_joint = person.tax_unit("tax_unit_is_joint", period)
|
|
332
|
-
divisor = where(is_joint, 2, 1)
|
|
333
|
-
unrecaptured_s_1250_gain = (
|
|
334
|
-
person.tax_unit("unrecaptured_section_1250_gain", period)
|
|
335
|
-
/ divisor
|
|
336
|
-
)
|
|
337
|
-
cg_28_pct_rate_gain = (
|
|
338
|
-
person.tax_unit("capital_gains_28_percent_rate_gain", period)
|
|
339
|
-
/ divisor
|
|
340
|
-
)
|
|
341
|
-
net_gains_less_dividends = max_(
|
|
342
|
-
0,
|
|
343
|
-
net_capital_gain - qualified_dividend_income,
|
|
344
|
-
)
|
|
345
|
-
reduced_capital_gains = max_(
|
|
346
|
-
net_gains_less_dividends
|
|
347
|
-
- (unrecaptured_s_1250_gain + cg_28_pct_rate_gain),
|
|
348
|
-
0,
|
|
349
|
-
)
|
|
350
|
-
return reduced_capital_gains + qualified_dividend_income
|
|
351
|
-
|
|
352
|
-
class capital_gains_tax(Variable):
|
|
353
|
-
value_type = float
|
|
354
|
-
entity = TaxUnit
|
|
355
|
-
label = "Maximum income tax after capital gains tax"
|
|
356
|
-
unit = USD
|
|
357
|
-
definition_period = YEAR
|
|
358
|
-
|
|
359
|
-
def formula(tax_unit, period, parameters):
|
|
360
|
-
person = tax_unit.members
|
|
361
|
-
net_cg = person("net_capital_gain_person", period)
|
|
362
|
-
taxable_income = person("taxable_income_person", period)
|
|
363
|
-
adjusted_net_cg = min_(
|
|
364
|
-
person("adjusted_net_capital_gain_person", period),
|
|
365
|
-
taxable_income,
|
|
366
|
-
) # ANCG is referred to in all cases as ANCG or taxable income if less.
|
|
367
|
-
|
|
368
|
-
cg = parameters(period).gov.irs.capital_gains
|
|
369
|
-
|
|
370
|
-
excluded_cg = tax_unit(
|
|
371
|
-
"capital_gains_excluded_from_taxable_income", period
|
|
372
|
-
)
|
|
373
|
-
non_cg_taxable_income = max_(0, taxable_income - excluded_cg)
|
|
374
|
-
|
|
375
|
-
filing_status = tax_unit("filing_status", period)
|
|
376
|
-
is_tax_unit_head_or_spouse = person(
|
|
377
|
-
"is_tax_unit_head_or_spouse", period
|
|
378
|
-
)
|
|
379
|
-
is_primary_earner = person("is_primary_earner", period)
|
|
380
|
-
is_secondary_earner = (
|
|
381
|
-
is_tax_unit_head_or_spouse & ~is_primary_earner
|
|
382
|
-
)
|
|
383
|
-
is_tax_unit_dependent = person("is_tax_unit_dependent", period)
|
|
384
|
-
# Split capital gains between primary and secondary earners
|
|
385
|
-
primary_cg = where(is_primary_earner, adjusted_net_cg, 0)
|
|
386
|
-
secondary_cg = where(is_secondary_earner, adjusted_net_cg, 0)
|
|
387
|
-
dependent_cg = where(
|
|
388
|
-
is_tax_unit_dependent, adjusted_net_cg, 0
|
|
389
|
-
).sum()
|
|
390
|
-
primary_cg += dependent_cg # Add dependent gains to primary earner
|
|
391
|
-
|
|
392
|
-
# Calculate primary earner capital gains tax (using filing status thresholds)
|
|
393
|
-
first_threshold_primary = cg.brackets.thresholds["1"][
|
|
394
|
-
filing_status
|
|
395
|
-
]
|
|
396
|
-
second_threshold_primary = cg.brackets.thresholds["2"][
|
|
397
|
-
filing_status
|
|
398
|
-
]
|
|
399
|
-
|
|
400
|
-
# Calculate secondary earner capital gains tax (using single thresholds)
|
|
401
|
-
first_threshold_secondary = cg.brackets.thresholds["1"]["SINGLE"]
|
|
402
|
-
second_threshold_secondary = cg.brackets.thresholds["2"]["SINGLE"]
|
|
403
|
-
|
|
404
|
-
# Calculate brackets for primary earner
|
|
405
|
-
primary_cg_in_first = clip(primary_cg, 0, first_threshold_primary)
|
|
406
|
-
primary_cg_in_second = clip(
|
|
407
|
-
primary_cg - first_threshold_primary,
|
|
408
|
-
0,
|
|
409
|
-
second_threshold_primary - first_threshold_primary,
|
|
410
|
-
)
|
|
411
|
-
primary_cg_in_third = max_(
|
|
412
|
-
0, primary_cg - second_threshold_primary
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
# Calculate brackets for secondary earner
|
|
416
|
-
secondary_cg_in_first = clip(
|
|
417
|
-
secondary_cg, 0, first_threshold_secondary
|
|
418
|
-
)
|
|
419
|
-
secondary_cg_in_second = clip(
|
|
420
|
-
secondary_cg - first_threshold_secondary,
|
|
421
|
-
0,
|
|
422
|
-
second_threshold_secondary - first_threshold_secondary,
|
|
423
|
-
)
|
|
424
|
-
secondary_cg_in_third = max_(
|
|
425
|
-
0, secondary_cg - second_threshold_secondary
|
|
426
|
-
)
|
|
427
|
-
|
|
428
|
-
# Calculate total capital gains tax
|
|
429
|
-
main_cg_tax = (
|
|
430
|
-
(primary_cg_in_first + secondary_cg_in_first)
|
|
431
|
-
* cg.brackets.rates["1"]
|
|
432
|
-
+ (primary_cg_in_second + secondary_cg_in_second)
|
|
433
|
-
* cg.brackets.rates["2"]
|
|
434
|
-
+ (primary_cg_in_third + secondary_cg_in_third)
|
|
435
|
-
* cg.brackets.rates["3"]
|
|
436
|
-
)
|
|
437
|
-
is_joint = tax_unit("tax_unit_is_joint", period)
|
|
438
|
-
divisor = where(is_joint, 2, 1)
|
|
439
|
-
unrecaptured_s_1250_gain = (
|
|
440
|
-
tax_unit("unrecaptured_section_1250_gain", period) / divisor
|
|
441
|
-
)
|
|
442
|
-
qualified_dividends = (
|
|
443
|
-
add(tax_unit, period, ["qualified_dividend_income"]) / divisor
|
|
444
|
-
)
|
|
445
|
-
max_taxable_unrecaptured_gain = min_(
|
|
446
|
-
unrecaptured_s_1250_gain,
|
|
447
|
-
max_(0, net_cg - qualified_dividends),
|
|
448
|
-
)
|
|
449
|
-
unrecaptured_gain_deduction = max_(
|
|
450
|
-
non_cg_taxable_income + net_cg - taxable_income,
|
|
451
|
-
0,
|
|
452
|
-
)
|
|
453
|
-
taxable_unrecaptured_gain = max_(
|
|
454
|
-
max_taxable_unrecaptured_gain - unrecaptured_gain_deduction,
|
|
455
|
-
0,
|
|
456
|
-
)
|
|
457
|
-
|
|
458
|
-
unrecaptured_gain_tax = (
|
|
459
|
-
cg.unrecaptured_s_1250_rate * taxable_unrecaptured_gain
|
|
460
|
-
)
|
|
461
|
-
|
|
462
|
-
remaining_cg_tax = (
|
|
463
|
-
tax_unit("capital_gains_28_percent_rate_gain", period)
|
|
464
|
-
* cg.other_cg_rate
|
|
465
|
-
) / divisor
|
|
466
|
-
return tax_unit.sum(
|
|
467
|
-
main_cg_tax + unrecaptured_gain_tax + remaining_cg_tax
|
|
468
|
-
)
|
|
469
|
-
|
|
470
|
-
class amt_excluded_deductions_person(Variable):
|
|
471
|
-
value_type = float
|
|
472
|
-
entity = Person
|
|
473
|
-
definition_period = YEAR
|
|
474
|
-
label = "AMT taxable income excluded deductions"
|
|
475
|
-
unit = USD
|
|
476
|
-
reference = "https://www.law.cornell.edu/uscode/text/26/55#b_2"
|
|
477
|
-
|
|
478
|
-
def formula(person, period, parameters):
|
|
479
|
-
itemizing = person.tax_unit("tax_unit_itemizes", period)
|
|
480
|
-
standard_deduction = person("standard_deduction_person", period)
|
|
481
|
-
is_joint = person.tax_unit("tax_unit_is_joint", period)
|
|
482
|
-
divisor = where(is_joint, 2, 1)
|
|
483
|
-
salt_deduction = (
|
|
484
|
-
person.tax_unit("salt_deduction", period) / divisor
|
|
485
|
-
)
|
|
486
|
-
return where(itemizing, salt_deduction, standard_deduction)
|
|
487
|
-
|
|
488
|
-
class amt_income_person(Variable):
|
|
489
|
-
value_type = float
|
|
490
|
-
entity = Person
|
|
491
|
-
definition_period = YEAR
|
|
492
|
-
label = "AMT taxable income"
|
|
493
|
-
unit = USD
|
|
494
|
-
reference = "https://www.law.cornell.edu/uscode/text/26/55#b_2"
|
|
495
|
-
defined_for = "is_tax_unit_head_or_spouse"
|
|
496
|
-
|
|
497
|
-
def formula(person, period, parameters):
|
|
498
|
-
taxable_income = person("taxable_income_person", period)
|
|
499
|
-
deductions = person("amt_excluded_deductions_person", period)
|
|
500
|
-
is_joint = person.tax_unit("tax_unit_is_joint", period)
|
|
501
|
-
divisor = where(is_joint, 2, 1)
|
|
502
|
-
separate_addition = (
|
|
503
|
-
person.tax_unit("amt_separate_addition", period) / divisor
|
|
504
|
-
)
|
|
505
|
-
return taxable_income + deductions + separate_addition
|
|
506
|
-
|
|
507
|
-
class alternative_minimum_tax(Variable):
|
|
508
|
-
value_type = float
|
|
509
|
-
entity = TaxUnit
|
|
510
|
-
definition_period = YEAR
|
|
511
|
-
label = "Alternative Minimum Tax"
|
|
512
|
-
unit = USD
|
|
513
|
-
documentation = "Alternative Minimum Tax (AMT) liability"
|
|
514
|
-
|
|
515
|
-
def formula(tax_unit, period, parameters):
|
|
516
|
-
person = tax_unit.members
|
|
517
|
-
amt_income = person("amt_income_person", period)
|
|
518
|
-
# Form 6251, Part II top
|
|
519
|
-
p = parameters(period).gov.irs.income.amt
|
|
520
|
-
phase_out = p.exemption.phase_out
|
|
521
|
-
filing_status = tax_unit("filing_status", period)
|
|
522
|
-
|
|
523
|
-
# Split calculations for primary and secondary earners
|
|
524
|
-
is_primary_earner = person("is_primary_earner", period)
|
|
525
|
-
is_secondary_earner = (
|
|
526
|
-
person("is_tax_unit_head_or_spouse", period)
|
|
527
|
-
& ~is_primary_earner
|
|
528
|
-
)
|
|
529
|
-
is_tax_unit_dependent = person("is_tax_unit_dependent", period)
|
|
530
|
-
|
|
531
|
-
# Primary earner uses filing status thresholds
|
|
532
|
-
primary_base_exemption = p.exemption.amount[filing_status]
|
|
533
|
-
primary_phase_out_start = phase_out.start[filing_status]
|
|
534
|
-
|
|
535
|
-
# Secondary earner uses single thresholds
|
|
536
|
-
secondary_base_exemption = p.exemption.amount["SINGLE"]
|
|
537
|
-
secondary_phase_out_start = phase_out.start["SINGLE"]
|
|
538
|
-
|
|
539
|
-
# Calculate income for each earner
|
|
540
|
-
primary_income = where(is_primary_earner, amt_income, 0)
|
|
541
|
-
secondary_income = where(is_secondary_earner, amt_income, 0)
|
|
542
|
-
dependent_income = where(
|
|
543
|
-
is_tax_unit_dependent, amt_income, 0
|
|
544
|
-
).sum()
|
|
545
|
-
primary_income += (
|
|
546
|
-
dependent_income # Add dependent income to primary
|
|
547
|
-
)
|
|
548
|
-
|
|
549
|
-
# Calculate exemption amounts
|
|
550
|
-
primary_excess = max_(0, primary_income - primary_phase_out_start)
|
|
551
|
-
secondary_excess = max_(
|
|
552
|
-
0, secondary_income - secondary_phase_out_start
|
|
553
|
-
)
|
|
554
|
-
|
|
555
|
-
primary_exemption = max_(
|
|
556
|
-
0, primary_base_exemption - phase_out.rate * primary_excess
|
|
557
|
-
)
|
|
558
|
-
secondary_exemption = max_(
|
|
559
|
-
0, secondary_base_exemption - phase_out.rate * secondary_excess
|
|
560
|
-
)
|
|
561
|
-
|
|
562
|
-
age_head = tax_unit("age_head", period)
|
|
563
|
-
child = parameters(period).gov.irs.dependent.ineligible_age
|
|
564
|
-
young_head = (age_head != 0) & (age_head < child.non_student)
|
|
565
|
-
no_or_young_spouse = (
|
|
566
|
-
tax_unit("age_spouse", period) < child.non_student
|
|
567
|
-
)
|
|
568
|
-
adj_earnings = person("adjusted_earnings", period)
|
|
569
|
-
child_amount = p.exemption.child.amount
|
|
570
|
-
|
|
571
|
-
kiddie_tax_exemption_cap_applies = young_head & no_or_young_spouse
|
|
572
|
-
exemption_cap = where(
|
|
573
|
-
kiddie_tax_exemption_cap_applies,
|
|
574
|
-
adj_earnings + child_amount,
|
|
575
|
-
np.inf,
|
|
576
|
-
)
|
|
577
|
-
primary_exemption = min_(primary_exemption, exemption_cap)
|
|
578
|
-
secondary_exemption = min_(secondary_exemption, exemption_cap)
|
|
579
|
-
|
|
580
|
-
# Calculate taxable income
|
|
581
|
-
taxable_income = person("taxable_income_person", period)
|
|
582
|
-
# Do not add back deduction for filers subject to the kiddie tax
|
|
583
|
-
primary_applied_income = where(
|
|
584
|
-
kiddie_tax_exemption_cap_applies,
|
|
585
|
-
where(is_primary_earner, taxable_income, 0),
|
|
586
|
-
primary_income,
|
|
587
|
-
)
|
|
588
|
-
secondary_applied_income = where(
|
|
589
|
-
kiddie_tax_exemption_cap_applies,
|
|
590
|
-
where(is_secondary_earner, taxable_income, 0),
|
|
591
|
-
secondary_income,
|
|
592
|
-
)
|
|
593
|
-
|
|
594
|
-
primary_reduced_income = max_(
|
|
595
|
-
0, primary_applied_income - primary_exemption
|
|
596
|
-
)
|
|
597
|
-
secondary_reduced_income = max_(
|
|
598
|
-
0, secondary_applied_income - secondary_exemption
|
|
599
|
-
)
|
|
600
|
-
|
|
601
|
-
# Calculate bracket fractions
|
|
602
|
-
primary_bracket_fraction = where(
|
|
603
|
-
filing_status == filing_status.possible_values.SEPARATE,
|
|
604
|
-
0.5,
|
|
605
|
-
1.0,
|
|
606
|
-
)
|
|
607
|
-
secondary_bracket_fraction = (
|
|
608
|
-
1.0 # Single always uses full brackets
|
|
609
|
-
)
|
|
610
|
-
|
|
611
|
-
# Calculate tax thresholds
|
|
612
|
-
primary_tax_threshold = (
|
|
613
|
-
p.brackets.thresholds[-1] * primary_bracket_fraction
|
|
614
|
-
)
|
|
615
|
-
secondary_tax_threshold = (
|
|
616
|
-
p.brackets.thresholds[-1] * secondary_bracket_fraction
|
|
617
|
-
)
|
|
618
|
-
|
|
619
|
-
lower_rate = p.brackets.rates[0]
|
|
620
|
-
higher_rate = p.brackets.rates[1]
|
|
621
|
-
|
|
622
|
-
# Calculate tax for primary earner
|
|
623
|
-
primary_lower_tax = (
|
|
624
|
-
min_(primary_reduced_income, primary_tax_threshold)
|
|
625
|
-
* lower_rate
|
|
626
|
-
)
|
|
627
|
-
primary_higher_tax = (
|
|
628
|
-
max_(0, primary_reduced_income - primary_tax_threshold)
|
|
629
|
-
* higher_rate
|
|
630
|
-
)
|
|
631
|
-
|
|
632
|
-
# Calculate tax for secondary earner
|
|
633
|
-
secondary_lower_tax = (
|
|
634
|
-
min_(secondary_reduced_income, secondary_tax_threshold)
|
|
635
|
-
* lower_rate
|
|
636
|
-
)
|
|
637
|
-
secondary_higher_tax = (
|
|
638
|
-
max_(0, secondary_reduced_income - secondary_tax_threshold)
|
|
639
|
-
* higher_rate
|
|
640
|
-
)
|
|
641
|
-
|
|
642
|
-
# Combine taxes
|
|
643
|
-
reduced_income_tax = (
|
|
644
|
-
primary_lower_tax
|
|
645
|
-
+ primary_higher_tax
|
|
646
|
-
+ secondary_lower_tax
|
|
647
|
-
+ secondary_higher_tax
|
|
648
|
-
)
|
|
649
|
-
|
|
650
|
-
dwks10, dwks13, dwks14, dwks19, e24515 = [
|
|
651
|
-
add(tax_unit, period, [variable])
|
|
652
|
-
for variable in [
|
|
653
|
-
"dwks10",
|
|
654
|
-
"dwks13",
|
|
655
|
-
"dwks14",
|
|
656
|
-
"dwks19",
|
|
657
|
-
"unrecaptured_section_1250_gain",
|
|
658
|
-
]
|
|
659
|
-
]
|
|
660
|
-
form_6251_part_iii_required = np.any(
|
|
661
|
-
[
|
|
662
|
-
variable > 0
|
|
663
|
-
for variable in [
|
|
664
|
-
dwks10,
|
|
665
|
-
dwks13,
|
|
666
|
-
dwks14,
|
|
667
|
-
dwks19,
|
|
668
|
-
e24515,
|
|
669
|
-
]
|
|
670
|
-
]
|
|
671
|
-
)
|
|
672
|
-
|
|
673
|
-
# Complete Form 6251, Part III
|
|
674
|
-
line37 = dwks13
|
|
675
|
-
line38 = e24515
|
|
676
|
-
line39 = min_(line37 + line38, dwks10)
|
|
677
|
-
line40 = min_(
|
|
678
|
-
primary_reduced_income + secondary_reduced_income, line39
|
|
679
|
-
)
|
|
680
|
-
line41 = max_(
|
|
681
|
-
0, primary_reduced_income + secondary_reduced_income - line40
|
|
682
|
-
)
|
|
683
|
-
line42 = p.brackets.calc(line41)
|
|
684
|
-
line44 = dwks14
|
|
685
|
-
|
|
686
|
-
# Apply different thresholds for primary/secondary for capital gains
|
|
687
|
-
cg = parameters(period).gov.irs.capital_gains.brackets
|
|
688
|
-
primary_line45 = max_(
|
|
689
|
-
0, cg.thresholds["1"][filing_status] - line44
|
|
690
|
-
)
|
|
691
|
-
secondary_line45 = max_(0, cg.thresholds["1"]["SINGLE"] - line44)
|
|
692
|
-
|
|
693
|
-
line46 = min_(
|
|
694
|
-
primary_reduced_income + secondary_reduced_income, line37
|
|
695
|
-
)
|
|
696
|
-
primary_line47 = min_(primary_line45, line46)
|
|
697
|
-
secondary_line47 = min_(secondary_line45, line46)
|
|
698
|
-
|
|
699
|
-
cgtax1 = (
|
|
700
|
-
primary_line47 * cg.rates["1"]
|
|
701
|
-
+ secondary_line47 * cg.rates["1"]
|
|
702
|
-
)
|
|
703
|
-
|
|
704
|
-
line48 = line46 - (primary_line47 + secondary_line47)
|
|
705
|
-
line51 = dwks19
|
|
706
|
-
|
|
707
|
-
primary_line52 = primary_line45 + line51
|
|
708
|
-
secondary_line52 = secondary_line45 + line51
|
|
709
|
-
|
|
710
|
-
primary_line53 = max_(
|
|
711
|
-
0, cg.thresholds["2"][filing_status] - primary_line52
|
|
712
|
-
)
|
|
713
|
-
secondary_line53 = max_(
|
|
714
|
-
0, cg.thresholds["2"]["SINGLE"] - secondary_line52
|
|
715
|
-
)
|
|
716
|
-
|
|
717
|
-
primary_line54 = min_(line48, primary_line53)
|
|
718
|
-
secondary_line54 = min_(line48, secondary_line53)
|
|
719
|
-
|
|
720
|
-
cgtax2 = (
|
|
721
|
-
primary_line54 * cg.rates["2"]
|
|
722
|
-
+ secondary_line54 * cg.rates["2"]
|
|
723
|
-
)
|
|
724
|
-
|
|
725
|
-
line56 = (
|
|
726
|
-
primary_line47
|
|
727
|
-
+ secondary_line47
|
|
728
|
-
+ primary_line54
|
|
729
|
-
+ secondary_line54
|
|
730
|
-
)
|
|
731
|
-
line57 = where(line41 == line56, 0, line46 - line56)
|
|
732
|
-
linex2 = where(
|
|
733
|
-
line41 == line56,
|
|
734
|
-
0,
|
|
735
|
-
max_(0, primary_line54 + secondary_line54 - line48),
|
|
736
|
-
)
|
|
737
|
-
cgtax3 = line57 * cg.rates["3"]
|
|
738
|
-
|
|
739
|
-
line61 = where(
|
|
740
|
-
line38 == 0,
|
|
741
|
-
0,
|
|
742
|
-
p.capital_gains.capital_gain_excess_tax_rate
|
|
743
|
-
* max_(
|
|
744
|
-
0,
|
|
745
|
-
(
|
|
746
|
-
primary_reduced_income
|
|
747
|
-
+ secondary_reduced_income
|
|
748
|
-
- line41
|
|
749
|
-
- line56
|
|
750
|
-
- line57
|
|
751
|
-
- linex2
|
|
752
|
-
),
|
|
753
|
-
),
|
|
754
|
-
)
|
|
755
|
-
line62 = line42 + cgtax1 + cgtax2 + cgtax3 + line61
|
|
756
|
-
line64 = min_(reduced_income_tax, line62)
|
|
757
|
-
line31 = where(
|
|
758
|
-
form_6251_part_iii_required, line64, reduced_income_tax
|
|
759
|
-
)
|
|
760
|
-
|
|
761
|
-
# Form 6251, Part II bottom
|
|
762
|
-
is_joint = tax_unit("tax_unit_is_joint", period)
|
|
763
|
-
divisor = where(is_joint, 2, 1)
|
|
764
|
-
line32 = tax_unit("foreign_tax_credit", period) / divisor
|
|
765
|
-
line33 = line31 - line32
|
|
766
|
-
regular_tax_before_credits = (
|
|
767
|
-
tax_unit("regular_tax_before_credits", period) / divisor
|
|
768
|
-
)
|
|
769
|
-
lump_sum_distributions = (
|
|
770
|
-
tax_unit("form_4972_lumpsum_distributions", period) / divisor
|
|
771
|
-
)
|
|
772
|
-
capital_gains = tax_unit("capital_gains_tax", period)
|
|
773
|
-
tax_before_credits = regular_tax_before_credits + capital_gains
|
|
774
|
-
|
|
775
|
-
return tax_unit.sum(
|
|
776
|
-
max_(
|
|
777
|
-
0,
|
|
778
|
-
line33
|
|
779
|
-
- max_(
|
|
780
|
-
0,
|
|
781
|
-
(tax_before_credits - line32 - lump_sum_distributions),
|
|
782
|
-
),
|
|
783
|
-
)
|
|
784
|
-
)
|
|
785
|
-
|
|
786
|
-
class reform(Reform):
|
|
787
|
-
def apply(self):
|
|
788
|
-
self.update_variable(taxable_income_person)
|
|
789
|
-
self.update_variable(income_tax_main_rates)
|
|
790
|
-
self.update_variable(basic_standard_deduction_person)
|
|
791
|
-
self.update_variable(standard_deduction_person)
|
|
792
|
-
self.update_variable(taxable_income_deductions_person)
|
|
793
|
-
self.update_variable(is_primary_earner)
|
|
794
|
-
self.update_variable(capital_gains_tax)
|
|
795
|
-
self.update_variable(net_capital_gain_person)
|
|
796
|
-
self.update_variable(adjusted_net_capital_gain_person)
|
|
797
|
-
self.update_variable(alternative_minimum_tax)
|
|
798
|
-
self.update_variable(amt_income_person)
|
|
799
|
-
self.update_variable(amt_excluded_deductions_person)
|
|
800
|
-
self.update_variable(bonus_guaranteed_deduction_person)
|
|
801
|
-
self.update_variable(additional_standard_deduction_person)
|
|
802
|
-
|
|
803
|
-
return reform
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
def create_second_earner_tax_reform(parameters, period, bypass: bool = False):
|
|
807
|
-
if bypass:
|
|
808
|
-
return create_second_earner_tax()
|
|
809
|
-
|
|
810
|
-
p = parameters(period).gov.contrib.second_earner_reform
|
|
811
|
-
|
|
812
|
-
if p.in_effect:
|
|
813
|
-
return create_second_earner_tax()
|
|
814
|
-
else:
|
|
815
|
-
return None
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
second_earner_tax_reform = create_second_earner_tax_reform(
|
|
819
|
-
None, None, bypass=True
|
|
820
|
-
)
|
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
- name: Two people, both with income in the first bracket
|
|
2
|
-
period: 2023
|
|
3
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
4
|
-
input:
|
|
5
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
6
|
-
people:
|
|
7
|
-
person1:
|
|
8
|
-
is_tax_unit_head_or_spouse: true
|
|
9
|
-
taxable_income_person: 20_000
|
|
10
|
-
person2:
|
|
11
|
-
is_tax_unit_head_or_spouse: true
|
|
12
|
-
taxable_income_person: 1_000
|
|
13
|
-
tax_units:
|
|
14
|
-
tax_unit:
|
|
15
|
-
members: [person1, person2]
|
|
16
|
-
capital_gains_excluded_from_taxable_income: 0
|
|
17
|
-
filing_status: JOINT
|
|
18
|
-
output:
|
|
19
|
-
income_tax_main_rates: 2_100
|
|
20
|
-
|
|
21
|
-
- name: Two people, spouse in second single bracket
|
|
22
|
-
period: 2023
|
|
23
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
24
|
-
input:
|
|
25
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
26
|
-
people:
|
|
27
|
-
person1:
|
|
28
|
-
is_tax_unit_head_or_spouse: true
|
|
29
|
-
taxable_income_person: 20_000
|
|
30
|
-
person2:
|
|
31
|
-
is_tax_unit_head_or_spouse: true
|
|
32
|
-
taxable_income_person: 15_000
|
|
33
|
-
tax_units:
|
|
34
|
-
tax_unit:
|
|
35
|
-
members: [person1, person2]
|
|
36
|
-
capital_gains_excluded_from_taxable_income: 0
|
|
37
|
-
filing_status: JOINT
|
|
38
|
-
output:
|
|
39
|
-
income_tax_main_rates: 3_580
|
|
40
|
-
|
|
41
|
-
- name: Two people, spouse in second single bracket - reform not applied
|
|
42
|
-
period: 2023
|
|
43
|
-
input:
|
|
44
|
-
gov.contrib.second_earner_reform.in_effect: false
|
|
45
|
-
people:
|
|
46
|
-
person1:
|
|
47
|
-
is_tax_unit_head_or_spouse: true
|
|
48
|
-
person2:
|
|
49
|
-
is_tax_unit_head_or_spouse: true
|
|
50
|
-
tax_units:
|
|
51
|
-
tax_unit:
|
|
52
|
-
members: [person1, person2]
|
|
53
|
-
capital_gains_excluded_from_taxable_income: 0
|
|
54
|
-
filing_status: JOINT
|
|
55
|
-
taxable_income: 45_000
|
|
56
|
-
output:
|
|
57
|
-
income_tax_main_rates: 4_960
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- name: Spouse with higher income becomes primary earner
|
|
61
|
-
period: 2023
|
|
62
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
63
|
-
input:
|
|
64
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
65
|
-
people:
|
|
66
|
-
person1:
|
|
67
|
-
is_tax_unit_head_or_spouse: true
|
|
68
|
-
taxable_income_person: 20_000
|
|
69
|
-
person2:
|
|
70
|
-
is_tax_unit_head_or_spouse: true
|
|
71
|
-
taxable_income_person: 40_000
|
|
72
|
-
is_primary_earner: true
|
|
73
|
-
tax_units:
|
|
74
|
-
tax_unit:
|
|
75
|
-
members: [person1, person2]
|
|
76
|
-
capital_gains_excluded_from_taxable_income: 0
|
|
77
|
-
filing_status: JOINT
|
|
78
|
-
output:
|
|
79
|
-
income_tax_main_rates: 6_540
|
|
80
|
-
|
|
81
|
-
- name: One person with one dependent taxes as head of household
|
|
82
|
-
period: 2023
|
|
83
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
84
|
-
input:
|
|
85
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
86
|
-
people:
|
|
87
|
-
person1:
|
|
88
|
-
taxable_income_person: 40_000
|
|
89
|
-
person2:
|
|
90
|
-
age: 10
|
|
91
|
-
tax_units:
|
|
92
|
-
tax_unit:
|
|
93
|
-
members: [person1, person2]
|
|
94
|
-
capital_gains_excluded_from_taxable_income: 0
|
|
95
|
-
output:
|
|
96
|
-
income_tax_main_rates: 4_486
|
|
97
|
-
|
|
98
|
-
- name: One person alone is taxed as single
|
|
99
|
-
period: 2023
|
|
100
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
101
|
-
input:
|
|
102
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
103
|
-
people:
|
|
104
|
-
person1:
|
|
105
|
-
taxable_income_person: 15_000
|
|
106
|
-
tax_units:
|
|
107
|
-
tax_unit:
|
|
108
|
-
members: [person1]
|
|
109
|
-
capital_gains_excluded_from_taxable_income: 0
|
|
110
|
-
output:
|
|
111
|
-
income_tax_main_rates: 1_580
|
|
112
|
-
|
|
113
|
-
- name: Joint couple with one dependent, cg exclusion included
|
|
114
|
-
period: 2023
|
|
115
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
116
|
-
input:
|
|
117
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
118
|
-
people:
|
|
119
|
-
person1:
|
|
120
|
-
age: 40
|
|
121
|
-
taxable_income_person: 30_000
|
|
122
|
-
person2:
|
|
123
|
-
age: 40
|
|
124
|
-
taxable_income_person: 15_000
|
|
125
|
-
person3:
|
|
126
|
-
age: 16
|
|
127
|
-
taxable_income_person: 1_000
|
|
128
|
-
tax_units:
|
|
129
|
-
tax_unit:
|
|
130
|
-
members: [person1, person2, person3]
|
|
131
|
-
capital_gains_excluded_from_taxable_income: 2_000
|
|
132
|
-
output:
|
|
133
|
-
income_tax_main_rates: 4_620
|
|
134
|
-
|
|
135
|
-
- name: Integration, joint household with one depedent, reform not applied
|
|
136
|
-
period: 2023
|
|
137
|
-
input:
|
|
138
|
-
gov.contrib.second_earner_reform.in_effect: false
|
|
139
|
-
people:
|
|
140
|
-
person1:
|
|
141
|
-
age: 40
|
|
142
|
-
employment_income: 50_000
|
|
143
|
-
person2:
|
|
144
|
-
age: 40
|
|
145
|
-
employment_income: 40_000
|
|
146
|
-
person3:
|
|
147
|
-
age: 16
|
|
148
|
-
employment_income: 1_000
|
|
149
|
-
tax_units:
|
|
150
|
-
tax_unit:
|
|
151
|
-
members: [person1, person2, person3]
|
|
152
|
-
output:
|
|
153
|
-
adjusted_gross_income: 90_000
|
|
154
|
-
adjusted_gross_income_person: [50_000, 40_000, 0]
|
|
155
|
-
exemptions: 0
|
|
156
|
-
taxable_income_deductions: 27_700
|
|
157
|
-
taxable_income: 62_300
|
|
158
|
-
income_tax_main_rates: 7_036
|
|
159
|
-
|
|
160
|
-
- name: Integration, joint household with one depedent, reform applied
|
|
161
|
-
period: 2023
|
|
162
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
163
|
-
input:
|
|
164
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
165
|
-
people:
|
|
166
|
-
person1:
|
|
167
|
-
age: 40
|
|
168
|
-
employment_income: 50_000
|
|
169
|
-
person2:
|
|
170
|
-
age: 40
|
|
171
|
-
employment_income: 40_000
|
|
172
|
-
person3:
|
|
173
|
-
age: 16
|
|
174
|
-
employment_income: 1_000
|
|
175
|
-
tax_units:
|
|
176
|
-
tax_unit:
|
|
177
|
-
members: [person1, person2, person3]
|
|
178
|
-
output:
|
|
179
|
-
adjusted_gross_income: 90_000
|
|
180
|
-
adjusted_gross_income_person: [50_000, 40_000, 0]
|
|
181
|
-
taxable_income: 62_300
|
|
182
|
-
exemptions: 0
|
|
183
|
-
taxable_income_deductions: 27_700
|
|
184
|
-
taxable_income_deductions_person: [27_700, 13_850, 0]
|
|
185
|
-
taxable_income_person: [22_300, 26_150, 0]
|
|
186
|
-
income_tax_main_rates: 5_154
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
- name: Two people both without income
|
|
190
|
-
period: 2024
|
|
191
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
192
|
-
input:
|
|
193
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
194
|
-
people:
|
|
195
|
-
person1:
|
|
196
|
-
age: 40
|
|
197
|
-
person2:
|
|
198
|
-
age: 40
|
|
199
|
-
tax_units:
|
|
200
|
-
tax_unit:
|
|
201
|
-
members: [person1, person2]
|
|
202
|
-
filing_status: JOINT
|
|
203
|
-
output:
|
|
204
|
-
basic_standard_deduction_person: [29_200, 14_600]
|
|
205
|
-
|
|
206
|
-
- name: Taxable income deductions - standard deduction case
|
|
207
|
-
period: 2024
|
|
208
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
209
|
-
input:
|
|
210
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
211
|
-
people:
|
|
212
|
-
person1:
|
|
213
|
-
age: 40
|
|
214
|
-
earned_income: 50_000
|
|
215
|
-
person2:
|
|
216
|
-
age: 40
|
|
217
|
-
earned_income: 30_000
|
|
218
|
-
tax_units:
|
|
219
|
-
tax_unit:
|
|
220
|
-
members: [person1, person2]
|
|
221
|
-
filing_status: JOINT
|
|
222
|
-
tax_unit_itemizes: false
|
|
223
|
-
output:
|
|
224
|
-
taxable_income_deductions_person: [29_200, 14_600]
|
|
225
|
-
|
|
226
|
-
- name: Taxable income deductions - itemizing case
|
|
227
|
-
period: 2024
|
|
228
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
229
|
-
input:
|
|
230
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
231
|
-
people:
|
|
232
|
-
person1:
|
|
233
|
-
age: 40
|
|
234
|
-
earned_income: 50_000
|
|
235
|
-
person2:
|
|
236
|
-
age: 40
|
|
237
|
-
earned_income: 30_000
|
|
238
|
-
tax_units:
|
|
239
|
-
tax_unit:
|
|
240
|
-
members: [person1, person2]
|
|
241
|
-
filing_status: JOINT
|
|
242
|
-
tax_unit_itemizes: true
|
|
243
|
-
taxable_income_deductions_if_itemizing: 40_000
|
|
244
|
-
output:
|
|
245
|
-
taxable_income_deductions_person: [20_000, 20_000]
|
|
246
|
-
|
|
247
|
-
- name: Integration test - joint household with one dependent
|
|
248
|
-
period: 2024
|
|
249
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
250
|
-
input:
|
|
251
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
252
|
-
people:
|
|
253
|
-
person1: # Head
|
|
254
|
-
age: 40
|
|
255
|
-
employment_income: 50_000
|
|
256
|
-
person2: # Spouse
|
|
257
|
-
age: 40
|
|
258
|
-
employment_income: 30_000
|
|
259
|
-
person3: # Dependent
|
|
260
|
-
age: 16
|
|
261
|
-
employment_income: 1_000
|
|
262
|
-
tax_units:
|
|
263
|
-
tax_unit:
|
|
264
|
-
members: [person1, person2, person3]
|
|
265
|
-
filing_status: JOINT
|
|
266
|
-
output:
|
|
267
|
-
# Income variables
|
|
268
|
-
adjusted_gross_income: 80_000
|
|
269
|
-
adjusted_gross_income_person: [50_000, 30_000, 0]
|
|
270
|
-
taxable_income: 50_800 # AGI minus standard deduction
|
|
271
|
-
taxable_income_person: [20_800, 15_400, 0] # Individual taxable incomes
|
|
272
|
-
# Deduction variables
|
|
273
|
-
basic_standard_deduction: 29_200
|
|
274
|
-
basic_standard_deduction_person: [29_200, 14_600, 0] # Head gets joint, spouse gets single
|
|
275
|
-
taxable_income_deductions: 29_200
|
|
276
|
-
taxable_income_deductions_person: [29_200, 14_600, 0]
|
|
277
|
-
# Tax variables
|
|
278
|
-
income_tax_main_rates: 3_696
|
|
279
|
-
|
|
280
|
-
- name: Capital gains tax test, two people with CG taxes
|
|
281
|
-
period: 2024
|
|
282
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
283
|
-
input:
|
|
284
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
285
|
-
people:
|
|
286
|
-
person1:
|
|
287
|
-
age: 40
|
|
288
|
-
adjusted_net_capital_gain_person: 150_000
|
|
289
|
-
taxable_income_person: 150_000
|
|
290
|
-
is_tax_unit_head_or_spouse: true
|
|
291
|
-
qualified_dividend_income: 11_000
|
|
292
|
-
person2:
|
|
293
|
-
age: 40
|
|
294
|
-
is_tax_unit_head_or_spouse: true
|
|
295
|
-
adjusted_net_capital_gain_person: 100_000
|
|
296
|
-
taxable_income_person: 100_000
|
|
297
|
-
tax_units:
|
|
298
|
-
tax_unit:
|
|
299
|
-
members: [person1, person2]
|
|
300
|
-
filing_status: JOINT
|
|
301
|
-
output:
|
|
302
|
-
capital_gains_tax: 16_338.75
|
|
303
|
-
|
|
304
|
-
- name: AMT test
|
|
305
|
-
period: 2024
|
|
306
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
307
|
-
input:
|
|
308
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
309
|
-
people:
|
|
310
|
-
person1:
|
|
311
|
-
age: 40
|
|
312
|
-
amt_income_person: 150_000
|
|
313
|
-
is_primary_earner: true
|
|
314
|
-
person2:
|
|
315
|
-
age: 40
|
|
316
|
-
amt_income_person: 100_000
|
|
317
|
-
tax_units:
|
|
318
|
-
tax_unit:
|
|
319
|
-
members: [person1, person2]
|
|
320
|
-
filing_status: JOINT
|
|
321
|
-
output:
|
|
322
|
-
alternative_minimum_tax: 8_060
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
- name: Counterfactual integration test - single household with one dependent - reform not applied
|
|
326
|
-
period: 2024
|
|
327
|
-
input:
|
|
328
|
-
gov.contrib.second_earner_reform.in_effect: false
|
|
329
|
-
people:
|
|
330
|
-
person1:
|
|
331
|
-
age: 40
|
|
332
|
-
employment_income: 150_000
|
|
333
|
-
person2:
|
|
334
|
-
age: 10
|
|
335
|
-
tax_units:
|
|
336
|
-
tax_unit:
|
|
337
|
-
members: [person1, person2]
|
|
338
|
-
output:
|
|
339
|
-
# Income variables
|
|
340
|
-
adjusted_gross_income: 150_000
|
|
341
|
-
taxable_income: 128_100
|
|
342
|
-
# Deduction variables
|
|
343
|
-
basic_standard_deduction: 21_900
|
|
344
|
-
taxable_income_deductions: 21_900
|
|
345
|
-
# Tax variables
|
|
346
|
-
income_tax_main_rates: 22_093
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
- name: Integration test - single household with one dependent - nothing should change
|
|
350
|
-
period: 2024
|
|
351
|
-
reforms: policyengine_us.reforms.second_earner.second_earner_tax_reform.second_earner_tax_reform
|
|
352
|
-
input:
|
|
353
|
-
gov.contrib.second_earner_reform.in_effect: true
|
|
354
|
-
people:
|
|
355
|
-
person1:
|
|
356
|
-
age: 40
|
|
357
|
-
employment_income: 150_000
|
|
358
|
-
person2:
|
|
359
|
-
age: 10
|
|
360
|
-
tax_units:
|
|
361
|
-
tax_unit:
|
|
362
|
-
members: [person1, person2]
|
|
363
|
-
output:
|
|
364
|
-
# Income variables
|
|
365
|
-
adjusted_gross_income: 150_000
|
|
366
|
-
taxable_income: 128_100
|
|
367
|
-
# Deduction variables
|
|
368
|
-
basic_standard_deduction: 21_900
|
|
369
|
-
taxable_income_deductions: 21_900
|
|
370
|
-
# Tax variables
|
|
371
|
-
income_tax_main_rates: 22_093
|
|
File without changes
|
|
File without changes
|
|
File without changes
|