policyengine-us 1.351.4__py3-none-any.whl → 1.352.0__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.

@@ -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
- )