-
-
Notifications
You must be signed in to change notification settings - Fork 159
/
calcfunctions.py
3788 lines (3578 loc) · 143 KB
/
calcfunctions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
"""
Tax-Calculator functions that calculate payroll and individual income taxes.
These functions are imported into the Calculator class.
Note: the parameter_indexing_CPI_offset policy parameter is the only
policy parameter that does not appear here; it is used in the policy.py
file to possibly adjust the price inflation rate used to index policy
parameters (as would be done in a reform that introduces chained-CPI
indexing).
"""
# CODING-STYLE CHECKS:
# pycodestyle calcfunctions.py
# pylint --disable=locally-disabled calcfunctions.py
#
# pylint: disable=too-many-lines
# pylint: disable=invalid-name
# pylint: disable=too-many-arguments
# pylint: disable=too-many-locals
import math
import copy
import numpy as np
from taxcalc.decorators import iterate_jit, JIT
def BenefitPrograms(calc):
"""
Calculate total government cost and consumption value of benefits
delivered by non-repealed benefit programs.
Parameters
----------
calc: Calculator object
calc represents the reform while self represents the baseline
Returns
-------
None:
The function modifies calc
"""
# zero out benefits delivered by repealed programs
zero = np.zeros(calc.array_len)
if calc.policy_param('BEN_housing_repeal'):
calc.array('housing_ben', zero)
if calc.policy_param('BEN_ssi_repeal'):
calc.array('ssi_ben', zero)
if calc.policy_param('BEN_snap_repeal'):
calc.array('snap_ben', zero)
if calc.policy_param('BEN_tanf_repeal'):
calc.array('tanf_ben', zero)
if calc.policy_param('BEN_vet_repeal'):
calc.array('vet_ben', zero)
if calc.policy_param('BEN_wic_repeal'):
calc.array('wic_ben', zero)
if calc.policy_param('BEN_mcare_repeal'):
calc.array('mcare_ben', zero)
if calc.policy_param('BEN_mcaid_repeal'):
calc.array('mcaid_ben', zero)
if calc.policy_param('BEN_oasdi_repeal'):
calc.array('e02400', zero)
if calc.policy_param('BEN_ui_repeal'):
calc.array('e02300', zero)
if calc.policy_param('BEN_other_repeal'):
calc.array('other_ben', zero)
# calculate government cost of all benefits
cost = np.array(
calc.array('housing_ben') +
calc.array('ssi_ben') +
calc.array('snap_ben') +
calc.array('tanf_ben') +
calc.array('vet_ben') +
calc.array('wic_ben') +
calc.array('mcare_ben') +
calc.array('mcaid_ben') +
calc.array('e02400') +
calc.array('e02300') +
calc.array('ubi') +
calc.array('other_ben')
)
calc.array('benefit_cost_total', cost)
# calculate consumption value of all benefits
# (assuming that cash benefits have full value)
value = np.array(
calc.array('housing_ben') * calc.consump_param('BEN_housing_value') +
calc.array('ssi_ben') +
calc.array('snap_ben') * calc.consump_param('BEN_snap_value') +
calc.array('tanf_ben') * calc.consump_param('BEN_tanf_value') +
calc.array('vet_ben') * calc.consump_param('BEN_vet_value') +
calc.array('wic_ben') * calc.consump_param('BEN_wic_value') +
calc.array('mcare_ben') * calc.consump_param('BEN_mcare_value') +
calc.array('mcaid_ben') * calc.consump_param('BEN_mcaid_value') +
calc.array('e02400') +
calc.array('e02300') +
calc.array('ubi') +
calc.array('other_ben') * calc.consump_param('BEN_other_value')
)
calc.array('benefit_value_total', value)
@iterate_jit(nopython=True)
def EI_PayrollTax(SS_Earnings_c, e00200p, e00200s, pencon_p, pencon_s,
FICA_ss_trt_employer, FICA_ss_trt_employee,
FICA_mc_trt_employer, FICA_mc_trt_employee,
ALD_SelfEmploymentTax_hc, SS_Earnings_thd, SECA_Earnings_thd,
e00900p, e00900s, e02100p, e02100s, k1bx14p,
k1bx14s, payrolltax, ptax_was, setax, c03260, ptax_oasdi,
sey, earned, earned_p, earned_s,
was_plus_sey_p, was_plus_sey_s):
"""
Compute part of total OASDI+HI payroll taxes and earned income variables.
Parameters
----------
SS_Earnings_c: float
Maximum taxable earnings for Social Security.
Individual earnings below this amount are subjected to OASDI payroll tax.
This parameter is indexed by rate of growth in average wages not by the price inflation rate.
e00200p: float
Wages, salaries, and tips for taxpayer net of pension contributions
e00200s: float
Wages, salaries, and tips for spouse net of pension contributions
pencon_p: float
Contributions to defined-contribution pension plans for taxpayer
pencon_s: float
Contributions to defined-contribution pension plans for spouse
FICA_ss_trt_employer: float
Employer side social security payroll tax rate
FICA_ss_trt_employee: float
Employee side social security payroll tax rate
FICA_mc_trt_employer: float
Employer side medicare payroll tax rate
FICA_mc_trt_employee: float
Employee side medicare payroll tax rate
ALD_SelfEmploymentTax_hc: float
Adjustment for self-employment tax haircut
If greater than zero, reduces the employer equivalent portion of self-employment adjustment
Final adjustment amount = (1-Haircut)*SelfEmploymentTaxAdjustment
SS_Earnings_thd: float
Additional taxable earnings threshold for Social Security
Individual earnings above this threshold are subjected to OASDI payroll tax, in addtion to
earnings below the maximum taxable earnings threshold.
SECA_Earnings_thd: float
Threshold value for self-employment income below which there is
no SECA tax liability
e00900p: float
Schedule C business net profit/loss for taxpayer
e00900s: float
Schedule C business net profit/loss for spouse
e02100p: float
Farm net income/loss for taxpayer
e02100s: float
Farm net income/loss for spouse
k1bx14p: float
Partner self-employment earnings/loss for taxpayer (included in e26270 total)
k1bx14s: float
Partner self-employment earnings/loss for spouse (included in e26270 total)
payrolltax: float
Total (employee and employer) payroll tax liability
payrolltax = ptax_was
ptax_was: float
Employee and employer OASDI plus HI FICA tax
setax: float
Self-employment tax (included in othertaxes and iitax)
c03260: float
Deductible part of self-employment tax
c03260 = (1 - ALD_SelfEmploymentTax_hc) * 0.5 * setax
ptax_oasdi: float
Employee and employer OASDI FICA tax plus self employment tax
Excludes HI FICA so positive ptax_oasdi is less than ptax_was + setax
sey: float
Total self-employment income for filing unit
earned: float
Earned income for filing unit
earned_p: float
Earned income for taxpayer
earned_s: float
Earned income for spouse
was_plus_sey_p: float
Wage and salary income plus taxable self employment income for taxpayer
was_plus_sey_s: float
Wage and salary income plus taxable self employment income for spouse
Returns
-------
sey: float
Total self-employment income for filing unit
payrolltax: float
Total (employee and employer) payroll tax liability
payrolltax = ptax_was
ptax_was: float
Employee and employer OASDI plus HI FICA tax
setax: float
Self-employment tax (included in othertaxes and iitax)
c03260: float
Deductible part of self-employment tax
c03260 = (1 - ALD_SelfEmploymentTax_hc) * 0.5 * setax
ptax_oasdi: float
Employee and employer OASDI FICA tax plus self employment tax
Excludes HI FICA so positive ptax_oasdi is less than ptax_was + setax
earned: float
Earned income for filing unit
earned_p: float
Earned income for taxpayer
earned_s: float
Earned income for spouse
was_plus_sey_p: float
Wage and salary income plus taxable self employment income for taxpayer
was_plus_sey_s: float
Wage and salary income plus taxable self employment income for spouse
"""
# compute sey and its individual components
sey_p = e00900p + e02100p + k1bx14p
sey_s = e00900s + e02100s + k1bx14s
sey = sey_p + sey_s # total self-employment income for filing unit
# compute gross wage and salary income ('was' denotes 'wage and salary')
gross_was_p = e00200p + pencon_p
gross_was_s = e00200s + pencon_s
# compute taxable gross earnings for OASDI FICA
txearn_was_p = min(SS_Earnings_c, gross_was_p)
txearn_was_s = min(SS_Earnings_c, gross_was_s)
# compute OASDI and HI payroll taxes on wage-and-salary income, FICA
ptax_ss_was_p = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_was_p
ptax_ss_was_s = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_was_s
ptax_mc_was_p = (FICA_mc_trt_employer + FICA_mc_trt_employee) * gross_was_p
ptax_mc_was_s = (FICA_mc_trt_employer + FICA_mc_trt_employee) * gross_was_s
ptax_was = ptax_ss_was_p + ptax_ss_was_s + ptax_mc_was_p + ptax_mc_was_s
# compute taxable self-employment income for OASDI SECA
sey_frac = 1.0 - 0.5 * (FICA_ss_trt_employer + FICA_ss_trt_employee + FICA_mc_trt_employer + FICA_mc_trt_employee)
txearn_sey_p = min(max(0., sey_p * sey_frac), SS_Earnings_c - txearn_was_p)
txearn_sey_s = min(max(0., sey_s * sey_frac), SS_Earnings_c - txearn_was_s)
# compute self-employment tax on taxable self-employment income, SECA
setax_ss_p = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_sey_p
setax_ss_s = (FICA_ss_trt_employer + FICA_ss_trt_employee) * txearn_sey_s
setax_mc_p = (FICA_mc_trt_employer + FICA_mc_trt_employee) * max(0., sey_p * sey_frac)
setax_mc_s = (FICA_mc_trt_employer + FICA_mc_trt_employee) * max(0., sey_s * sey_frac)
setax_p = setax_ss_p + setax_mc_p
setax_s = setax_ss_s + setax_mc_s
setax = setax_p + setax_s
# # no tax if low amount of self-employment income
if sey * sey_frac > SECA_Earnings_thd:
setax = setax_p + setax_s
else:
setax = 0.0
# compute extra OASDI payroll taxes on the portion of the sum
# of wage-and-salary income and taxable self employment income
# that exceeds SS_Earnings_thd
sey_frac = 1.0 - 0.5 * (FICA_ss_trt_employer + FICA_ss_trt_employee)
was_plus_sey_p = gross_was_p + max(0., sey_p * sey_frac)
was_plus_sey_s = gross_was_s + max(0., sey_s * sey_frac)
extra_ss_income_p = max(0., was_plus_sey_p - SS_Earnings_thd)
extra_ss_income_s = max(0., was_plus_sey_s - SS_Earnings_thd)
extra_payrolltax = (extra_ss_income_p * (FICA_ss_trt_employer + FICA_ss_trt_employee) +
extra_ss_income_s * (FICA_ss_trt_employer + FICA_ss_trt_employee))
# compute part of total payroll taxes for filing unit
payrolltax = ptax_was + extra_payrolltax
# compute OASDI part of payroll taxes
ptax_oasdi = (ptax_ss_was_p + ptax_ss_was_s +
setax_ss_p + setax_ss_s +
extra_payrolltax)
# compute earned* variables and AGI deduction for
# "employer share" of self-employment tax, c03260
# Note: c03260 is the amount on 2015 Form 1040, line 27
c03260 = (1. - ALD_SelfEmploymentTax_hc) * 0.5 * setax
earned = max(0., e00200p + e00200s + sey - c03260)
earned_p = max(0., (e00200p + sey_p -
(1. - ALD_SelfEmploymentTax_hc) * 0.5 * setax_p))
earned_s = max(0., (e00200s + sey_s -
(1. - ALD_SelfEmploymentTax_hc) * 0.5 * setax_s))
return (sey, payrolltax, ptax_was, setax, c03260, ptax_oasdi,
earned, earned_p, earned_s, was_plus_sey_p, was_plus_sey_s)
@iterate_jit(nopython=True)
def DependentCare(nu13, elderly_dependents, earned,
MARS, ALD_Dependents_thd, ALD_Dependents_hc,
ALD_Dependents_Child_c, ALD_Dependents_Elder_c,
care_deduction):
"""
Computes dependent-care above-the-line deduction.
Parameters
----------
nu13: int
Number of dependents under 13 years old
elderly_dependents: int
Number of elderly dependents age 65+ in filing unit excluding taxpayer and spouse
earned: float
Earned income for filing unit
MARS: int
Filing marital status (1=single, 2=joint, 3=separate, 4=household-head, 5=widow(er))
ALD_Dependents_thd: list
Maximum income to qualify for dependent care deduction
ALD_Dependents_hc: float
Deduction for childcare costs haircut
ALD_Dependents_Child_c: float
National weighted average cost of childcare, ceiling for available childcare deduction
ALD_Dependents_Elder_c: float
Eldercare deduction ceiling
Returns
-------
care_deduction: float
Total above the line deductions for dependent care.
"""
if earned <= ALD_Dependents_thd[MARS - 1]:
care_deduction = (((1. - ALD_Dependents_hc) * nu13 *
ALD_Dependents_Child_c) +
((1. - ALD_Dependents_hc) * elderly_dependents *
ALD_Dependents_Elder_c))
else:
care_deduction = 0.
return care_deduction
@iterate_jit(nopython=True)
def Adj(e03150, e03210, c03260,
e03270, e03300, e03400, e03500, e00800,
e03220, e03230, e03240, e03290, care_deduction,
ALD_StudentLoan_hc, ALD_SelfEmp_HealthIns_hc, ALD_KEOGH_SEP_hc,
ALD_EarlyWithdraw_hc, ALD_AlimonyPaid_hc, ALD_AlimonyReceived_hc,
ALD_EducatorExpenses_hc, ALD_HSADeduction_hc, ALD_IRAContributions_hc,
ALD_DomesticProduction_hc, ALD_Tuition_hc,
c02900):
"""
Adj calculates Form 1040 AGI adjustments (i.e., Above-the-Line Deductions).
Parameters
-----
e03210: float
Student loan interest paid
e03220: float
Educator expenses
e03150: float
Total deductible IRA plan contributions
e03230: float
Tuition and fees (Form 8917)
e03240: float
Domestic production activity deduction (Form 8903)
c03260: float
Self-employment tax deduction (after haircut)
e03270: float
Self-employed health insurance premiums
e03290: float
HSA deduction (Form 8889)
e03300: float
Total deductible KEOGH/SEP/SIMPLE/etc. plan contributions
e03400: float
Penalty on early withdrawal of savings deduction
e03500: float
Alimony paid
e00800: float
Alimony received
care_deduction: float
Dependent care expense deduction
ALD_StudentLoan_hc: float
Student loan interest deduction haircut
ALD_SelfEmp_HealthIns_hc: float
Self-employed h.i. deduction haircut
ALD_KEOGH_SEP_hc: float
KEOGH/etc. plan contribution deduction haircut
ALD_EarlyWithdraw_hc: float
Penalty on early withdrawal deduction haricut
ALD_AlimonyPaid_hc: float
Alimony paid deduction haircut
ALD_AlimonyReceived_hc: float
Alimony received deduction haircut
ALD_EducatorExpenses_hc: float
Eductor expenses haircut
ALD_HSADeduction_hc: float
HSA Deduction haircut
ALD_IRAContributions_hc: float
IRA Contribution haircut
ALD_DomesticProduction_hc: float
Domestic production haircut
ALD_Tuition_hc: float
Tuition and fees haircut
Returns
-------
c02900: float
Total of all "above the line" income adjustments to get AGI
"""
# Form 2555 foreign earned income exclusion is assumed to be zero
# Form 1040 adjustments that are included in expanded income:
c02900 = ((1. - ALD_StudentLoan_hc) * e03210 +
c03260 +
(1. - ALD_EarlyWithdraw_hc) * e03400 +
(1. - ALD_AlimonyPaid_hc) * e03500 +
(1. - ALD_AlimonyReceived_hc) * e00800 +
(1. - ALD_EducatorExpenses_hc) * e03220 +
(1. - ALD_Tuition_hc) * e03230 +
(1. - ALD_DomesticProduction_hc) * e03240 +
(1. - ALD_HSADeduction_hc) * e03290 +
(1. - ALD_SelfEmp_HealthIns_hc) * e03270 +
(1. - ALD_IRAContributions_hc) * e03150 +
(1. - ALD_KEOGH_SEP_hc) * e03300 +
care_deduction)
return c02900
@iterate_jit(nopython=True)
def ALD_InvInc_ec_base(p22250, p23250, sep,
e00300, e00600, e01100, e01200, MARS,
invinc_ec_base, Capital_loss_limitation):
"""
Computes invinc_ec_base.
Parameters
----------
p22250: float
Net short-term capital gails/losses (Schedule D)
p23250: float
Net long-term capital gains/losses (Schedule D)
sep: int
2 when MARS is 3 (married filing separately); otherwise 1
e00300: float
Taxable interest income
e00600: float
Ordinary dividends included in AGI
e01100: float
Capital gains distributions not reported on Schedule D
e01200: float
Other net gain/loss from Form 4797
MARS: int
Filing marital status (1=single, 2=joint, 3=separate, 4=household-head, 5=widow(er))
invinc_ec_base: float
Exclusion of investment income from AGI
Capital_loss_limitation: float
Limitation on capital losses that are deductible
Returns
-------
invinc_ec_base: float
Exclusion of investment income from AGI
"""
# limitation on net short-term and long-term capital losses
cgain = max((-1 * Capital_loss_limitation[MARS - 1] / sep), p22250 + p23250)
# compute exclusion of investment income from AGI
invinc_ec_base = e00300 + e00600 + cgain + e01100 + e01200
return invinc_ec_base
@iterate_jit(nopython=True)
def CapGains(p23250, p22250, sep, ALD_StudentLoan_hc,
ALD_InvInc_ec_rt, invinc_ec_base,
e00200, e00300, e00600, e00650, e00700, e00800,
CG_nodiff, CG_ec, CG_reinvest_ec_rt, Capital_loss_limitation,
ALD_BusinessLosses_c, MARS,
e00900, e01100, e01200, e01400, e01700, e02000, e02100,
e02300, e00400, e02400, c02900, e03210, e03230, e03240,
c01000, c23650, ymod, ymod1, invinc_agi_ec):
"""
CapGains function: ...
Parameters
----------
p23250: float
Net long-term capital gains/losses (Schedule D)
p22250: float
Net short-term capital gails/losses (Schedule D)
sep: int
2 when MARS is 3 (married filing separately); otherwise 1
ALD_StudentLoan_hc: float
Student loan interest deduction haircut
ALD_InvInc_ec_rt: float
Investment income exclusion rate haircut
invinc_ec_base: float
Exclusion of investment income from AGI
e00200: float
Wages, salaries, tips for filing unit net of pension contributions
e00300: float
Taxable interest income
e00600: float
Ordinary dividends included in AGI
e00650: float
Qualified dividends included in ordinary dividends
e00700: float
Taxable refunds of state and local income taxes
e00800: float
Alimony received
CG_nodiff: bool
Long term capital gains and qualified dividends taxed no differently than regular taxable income
CG_ec: float
Dollar amount of all capital gains and qualified dividends that are excluded from AGI
CG_reinvest_ec_rt: float
Fraction of all capital gains and qualified dividends in excess of the dollar exclusion that are excluded from AGI
Capital_loss_limitation: float
Limitation on capital losses that are deductible
ALD_BusinessLosses_c: list
Maximm amount of business losses deductible
MARS: int
Filing marital status (1=single, 2=joint, 3=separate, 4=household-head, 5=widow(er))
e00900: float
Schedule C business net profit/loss for filing unit
e01100: float
Capital gain distributions not reported on Schedule D
e01200: float
Other net gain/loss from Form 4797
e01400: float
Taxable IRA distributions
e01700: float
Taxable pensions and annunities
e02000: float
Schedule E total rental, royalty, partnership, S-corporation, etc, income/loss (includes e26270 and e27200)
e02100: float
Farm net income/loss for filing unit from Schedule F
e02300: float
Unemployment insurance benefits
e00400: float
Tax-exempt interest income
e02400: float
Total social security (OASDI) benefits
c02900: float
Total of all "above the line" income adjustments to get AGI
e03210: float
Student loan interest
e03230: float
Tuition and fees from Form 8917
e03240: float
Domestic production activities from Form 8903
c01000: float
Limitation on capital losses
c23650: float
Net capital gains (long and short term) before exclusion
ymod: float
Variable that is used in OASDI benefit taxation logic
ymod1: float
Variable that is included in AGI
invinc_agi_ec: float
Exclusion of investment income from AGI
Returns
-------
c01000: float
Limitation on capital losses
c23650: float
Net capital gains (long and short term) before exclusion
ymod: float
Variable that is used in OASDI benefit taxation logic
ymod1: float
Variable that is included in AGI
invinc_agi_ec: float
Exclusion of investment income from AGI
"""
# net capital gain (long term + short term) before exclusion
c23650 = p23250 + p22250
# limitation on capital losses
c01000 = max((-1 * Capital_loss_limitation[MARS - 1] / sep), c23650)
# compute total investment income
invinc = e00300 + e00600 + c01000 + e01100 + e01200
# compute exclusion of investment income from AGI
invinc_agi_ec = ALD_InvInc_ec_rt * max(0., invinc_ec_base)
# compute ymod1 variable that is included in AGI
ymod1 = (e00200 + e00700 + e00800 + e01400 + e01700 +
invinc - invinc_agi_ec + e02100 + e02300 +
max(e00900 + e02000, -ALD_BusinessLosses_c[MARS - 1]))
if CG_nodiff:
# apply QDIV+CG exclusion if QDIV+LTCG receive no special tax treatment
qdcg_pos = max(0., e00650 + c01000)
qdcg_exclusion = (min(CG_ec, qdcg_pos) +
CG_reinvest_ec_rt * max(0., qdcg_pos - CG_ec))
ymod1 = max(0., ymod1 - qdcg_exclusion)
invinc_agi_ec += qdcg_exclusion
# compute ymod variable that is used in OASDI benefit taxation logic
ymod2 = e00400 + (0.50 * e02400) - c02900
ymod3 = (1. - ALD_StudentLoan_hc) * e03210 + e03230 + e03240
ymod = ymod1 + ymod2 + ymod3
return (c01000, c23650, ymod, ymod1, invinc_agi_ec)
@iterate_jit(nopython=True)
def SSBenefits(MARS, ymod, e02400, SS_all_in_agi, SS_thd50, SS_thd85,
SS_percentage1, SS_percentage2, c02500):
"""
Calculates OASDI benefits included in AGI, c02500.
Parameters
----------
MARS: int
Filing marital status (1=single, 2=joint, 3=separate, 4=household-head, 5=widow(er))
ymod: float
Variable that is used in OASDI benefit taxation logic
e02400: float
Total social security (OASDI) benefits
SS_all_in_agi: bool
Whether all social security benefits are included in AGI
SS_thd50: list
Threshold for social security benefit taxability (1)
SS_thd85: list
Threshold for social security benefit taxability (2)
SS_percentage1: float
Social security taxable income decimal fraction (1)
SS_percentage2: float
Social security taxable income decimal fraction (2)
c02500: float
Social security (OASDI) benefits included in AGI
Returns
-------
c02500: float
Social security (OASDI) benefits included in AGI
"""
if ymod < SS_thd50[MARS - 1]:
c02500 = 0.
elif ymod < SS_thd85[MARS - 1]:
c02500 = SS_percentage1 * min(ymod - SS_thd50[MARS - 1], e02400)
else:
c02500 = min(SS_percentage2 * (ymod - SS_thd85[MARS - 1]) +
SS_percentage1 *
min(e02400, SS_thd85[MARS - 1] -
SS_thd50[MARS - 1]), SS_percentage2 * e02400)
if SS_all_in_agi:
c02500 = e02400
return c02500
@iterate_jit(nopython=True)
def UBI(nu18, n1820, n21, UBI_u18, UBI_1820, UBI_21, UBI_ecrt,
ubi, taxable_ubi, nontaxable_ubi):
"""
Calculates total and taxable Universal Basic Income (UBI) amount.
Parameters
----------
nu18: int
Number of people in the tax unit under 18
n1820: int
Number of people in the tax unit age 18-20
n21: int
Number of people in the tax unit age 21+
UBI_u18: float
UBI benefit for those under 18
UBI_1820: float
UBI benefit for those between 18 to 20
UBI_21: float
UBI benefit for those 21 or more
UBI_ecrt: float
Fraction of UBI benefits that are not included in AGI
ubi: float
Total UBI received by the tax unit (is included in expanded_income)
taxable_ubi: float
Amount of UBI that is taxable (is added to AGI)
nontaxable_ubi: float
Amount of UBI that is nontaxable
Returns
-------
ubi: float
Total UBI received by the tax unit (is included in expanded_income)
taxable_ubi: float
Amount of UBI that is taxable (is added to AGI)
nontaxable_ubi: float
Amount of UBI that is nontaxable
"""
ubi = nu18 * UBI_u18 + n1820 * UBI_1820 + n21 * UBI_21
taxable_ubi = ubi * (1. - UBI_ecrt)
nontaxable_ubi = ubi - taxable_ubi
return ubi, taxable_ubi, nontaxable_ubi
@iterate_jit(nopython=True)
def AGI(ymod1, c02500, c02900, XTOT, MARS, sep, DSI, exact, nu18, taxable_ubi,
II_em, II_em_ps, II_prt, II_no_em_nu18,
e02300, UI_thd, UI_em, c00100, pre_c04600, c04600):
"""
Computes Adjusted Gross Income (AGI), c00100, and
compute personal exemption amount, c04600.
Parameters
----------
ymod1: float
Variable that is included in AGI
c02500: float
Social security (OASDI) benefits included in AGI
c02900: float
Total of all "above the line" income adjustments to get AGI
XTOT: int
Total number of exemptions for filing unit
MARS: int
Filing marital status (1=single, 2=joint, 3=separate, 4=household-head, 5=widow(er))
sep: int
2 when MARS is 3 (married filing separately); otherwise 1
DSI: int
1 if claimed as dependent on another return; otherwise 0
exact: int
Whether or not to do rounding of phaseout fraction
nu18: int
Number of people in the tax unit under 18
taxable_ubi: float
Amount of UBI that is taxable (is added to AGI)
II_em: float
Personal and dependent exemption amount
II_em_ps: list
Personal exemption phaseout starting income
II_prt: float
Personal exemption phaseout rate
II_no_em_nu18: float
Repeal personal exemptions for dependents under age 18
e02300: float
Unemployment compensation
UI_thd: list
AGI threshold for unemployment compensation exclusion
UI_em: float
Amount of unemployment compensation excluded from AGI
c00100: float
Adjusted Gross Income (AGI)
pre_c04600: float
Personal exemption before phase-out
c04600: float
Personal exemptions after phase-out
Returns
-------
c00100: float
Adjusted Gross Income (AGI)
pre_c04600: float
Personal exemption before phase-out
c04600: float
Personal exemptions after phase-out
"""
# calculate AGI assuming no foreign earned income exclusion
c00100 = ymod1 + c02500 - c02900 + taxable_ubi
# calculate UI exclusion (e.g., from 2020 AGI due to ARPA)
if (c00100 - e02300) <= UI_thd[MARS - 1]:
ui_excluded = min(e02300, UI_em)
else:
ui_excluded = 0.
c00100 -= ui_excluded
# calculate personal exemption amount
if II_no_em_nu18: # repeal of personal exemptions for deps. under 18
pre_c04600 = max(0, XTOT - nu18) * II_em
else:
pre_c04600 = XTOT * II_em
if DSI:
pre_c04600 = 0.
# phase-out personal exemption amount
if exact == 1: # exact calculation as on tax forms
line5 = max(0., c00100 - II_em_ps[MARS - 1])
line6 = math.ceil(line5 / (2500. / sep))
line7 = II_prt * line6
c04600 = max(0., pre_c04600 * (1. - line7))
else: # smoothed calculation needed for sensible mtr calculation
dispc_numer = II_prt * (c00100 - II_em_ps[MARS - 1])
dispc_denom = 2500. / sep
dispc = min(1., max(0., dispc_numer / dispc_denom))
c04600 = pre_c04600 * (1. - dispc)
return (c00100, pre_c04600, c04600)
@iterate_jit(nopython=True)
def ItemDedCap(e17500, e18400, e18500, e19200, e19800, e20100, e20400, g20500,
c00100, ID_AmountCap_rt, ID_AmountCap_Switch, e17500_capped,
e18400_capped, e18500_capped, e19200_capped, e19800_capped,
e20100_capped, e20400_capped, g20500_capped):
"""
Applies a cap to gross itemized deductions.
Parameters
----------
e17500: float
Itemizable medical and dental expenses
e18400: float
Itemizable state and local income/sales taxes
e18500: float
Itemizable real-estate taxes paid
e19200: float
Itemizable interest paid
e19800: float
Itemizable charitable giving: cash/check contributions
e20100: float
Itemizable charitable giving: other than cash/check contributions
e20400: float
Itemizable gross (before 10% AGI disregard) casualty or theft loss
g20500: float
Itemizable gross (before 10% AGI disregard) casualty or theft loss
c00100: float
Adjusted gross income (AGI)
ID_AmountCap_rt: float
Ceiling on the gross amount of itemized deductions allowed; decimal fraction of AGI
ID_AmountCap_Switch: list
Deductions subject to the cap on itemized deduction benefits
e17500_capped: float
Schedule A: medical expenses, capped by ItemDedCap as a decimal fraction of AGI
e18400_capped: float
Schedule A: state and local income taxes deductlbe, capped by ItemDedCap as a decimal fraction of AGI
e18500_capped: float
Schedule A: state and local real estate taxes deductible, capped by ItemDedCap as a decimal fraction of AGI
e19200_capped: float
Schedule A: interest deduction deductible, capped by ItemDedCap as decimal fraction of AGI
e19800_capped: float
Schedule A: charity cash contributions deductible, capped by ItemDedCap as a decimal fraction of AGI
e20100_capped: float
Schedule A: charity noncash contributions deductible, capped aby ItemDedCap s a decimal fraction of AGI
e20400_capped: float
Schedule A: gross miscellaneous deductions deductible, capped by ItemDedCap as a decimal fraction of AGI
g20500_capped: float
Schedule A: gross casualty or theft loss deductible, capped aby ItemDedCap s a decimal fraction of AGI
Returns
-------
e17500_capped: float
Schedule A: medical expenses, capped by ItemDedCap as a decimal fraction of AGI
e18400_capped: float
Schedule A: state and local income taxes deductlbe, capped by ItemDedCap as a decimal fraction of AGI
e18500_capped: float
Schedule A: state and local real estate taxes deductible, capped by ItemDedCap as a decimal fraction of AGI
e19200_capped: float
Schedule A: interest deduction deductible, capped by ItemDedCap as decimal fraction of AGI
e19800_capped: float
Schedule A: charity cash contributions deductible, capped by ItemDedCap as a decimal fraction of AGI
e20100_capped: float
Schedule A: charity noncash contributions deductible, capped by ItemDedCap as a decimal fraction of AGI
e20400_capped: float
Schedule A: gross miscellaneous deductions deductible, capped by ItemDedCap as a decimal fraction of AGI
g20500_capped: float
Schedule A: gross casualty or theft loss deductible, capped by ItemDedCap as a decimal fraction of AGI
"""
# pylint: disable=too-many-branches
cap = max(0., ID_AmountCap_rt * c00100)
gross_ded_amt = 0
if ID_AmountCap_Switch[0]: # medical
gross_ded_amt += e17500
if ID_AmountCap_Switch[1]: # statelocal
gross_ded_amt += e18400
if ID_AmountCap_Switch[2]: # realestate
gross_ded_amt += e18500
if ID_AmountCap_Switch[3]: # casualty
gross_ded_amt += g20500
if ID_AmountCap_Switch[4]: # misc
gross_ded_amt += e20400
if ID_AmountCap_Switch[5]: # interest
gross_ded_amt += e19200
if ID_AmountCap_Switch[6]: # charity
gross_ded_amt += e19800 + e20100
overage = max(0., gross_ded_amt - cap)
e17500_capped = e17500
e18400_capped = e18400
e18500_capped = e18500
g20500_capped = g20500
e20400_capped = e20400
e19200_capped = e19200
e19800_capped = e19800
e20100_capped = e20100
if overage > 0. and c00100 > 0.:
if ID_AmountCap_Switch[0]: # medical
e17500_capped -= (e17500 / gross_ded_amt) * overage
if ID_AmountCap_Switch[1]: # statelocal
e18400_capped -= (e18400 / (gross_ded_amt) * overage)
if ID_AmountCap_Switch[2]: # realestate
e18500_capped -= (e18500 / gross_ded_amt) * overage
if ID_AmountCap_Switch[3]: # casualty
g20500_capped -= (g20500 / gross_ded_amt) * overage
if ID_AmountCap_Switch[4]: # misc
e20400_capped -= (e20400 / gross_ded_amt) * overage
if ID_AmountCap_Switch[5]: # interest
e19200_capped -= (e19200 / gross_ded_amt) * overage
if ID_AmountCap_Switch[6]: # charity
e19800_capped -= (e19800 / gross_ded_amt) * overage
e20100_capped -= (e20100 / gross_ded_amt) * overage
return (e17500_capped, e18400_capped, e18500_capped, g20500_capped,
e20400_capped, e19200_capped, e19800_capped, e20100_capped)
@iterate_jit(nopython=True)
def ItemDed(e17500_capped, e18400_capped, e18500_capped, e19200_capped,
e19800_capped, e20100_capped, e20400_capped, g20500_capped,
MARS, age_head, age_spouse, c00100, c04470, c21040, c21060,
c17000, c18300, c19200, c19700, c20500, c20800,
ID_ps, ID_Medical_frt, ID_Medical_frt_add4aged, ID_Medical_hc,
ID_Casualty_frt, ID_Casualty_hc, ID_Miscellaneous_frt,
ID_Miscellaneous_hc, ID_Charity_crt_cash, ID_Charity_crt_noncash,
ID_prt, ID_crt, ID_c, ID_StateLocalTax_hc, ID_Charity_frt,
ID_Charity_hc, ID_InterestPaid_hc, ID_RealEstate_hc,
ID_Medical_c, ID_StateLocalTax_c, ID_RealEstate_c,
ID_InterestPaid_c, ID_Charity_c, ID_Casualty_c,
ID_Miscellaneous_c, ID_AllTaxes_c, ID_AllTaxes_hc,
ID_StateLocalTax_crt, ID_RealEstate_crt, ID_Charity_f):
"""
Calculates itemized deductions, Form 1040, Schedule A.
Parameters
----------
e17500_capped: float
Schedule A: medical expenses, capped by ItemDedCap as a decimal fraction of AGI
e18400_capped: float
Schedule A: state and local income taxes deductlbe, capped by ItemDedCap as a decimal fraction of AGI
e18500_capped: float
Schedule A: state and local real estate taxes deductible, capped by ItemDedCap as a decimal fraction of AGI
e19200_capped: float
Schedule A: interest deduction deductible, capped by ItemDedCap as decimal fraction of AGI
e19800_capped: float
Schedule A: charity cash contributions deductible, capped by ItemDedCap as a decimal fraction of AGI
e20100_capped: float
Schedule A: charity noncash contributions deductible, capped by ItemDedCap as a decimal fraction of AGI
e20400_capped: float
Schedule A: gross miscellaneous deductions deductible, capped by ItemDedCap as a decimal fraction of AGI
g20500_capped: float
Schedule A: gross casualty or theft loss deductible, capped by ItemDedCap as a decimal fraction of AGI
MARS: int
Filing marital status (1=single, 2=joint, 3=separate, 4=household-head, 5=widow(er))
age_head: int
Age in years of taxpayer
age_spouse: int
Age in years of spouse
c00100: float
Adjusted gross income (AGI)
c04470: float
Itemized deductions after phase out (0 for non itemizers)
c21040: float
Itemized deductions that are phased out
c21060: float
Itemized deductions before phase out (0 for non itemizers)
c17000: float
Schedule A: medical expenses deducted
c18300: float
Schedule A: state and local taxes plus real estate taxes deducted
c19200: float
Schedule A: interest deducted
c19700: float
Schedule A: charity contributions deducted
c20500: float
Schedule A: net casualty or theft loss deducted
c20800: float
Schedule A: net limited miscellaneous deductions deducted
ID_ps: list
Itemized deduction phaseout AGI start (Pease)
ID_Medical_frt: float
Floor (as decimal fraction of AGI) for deductible medical expenses
ID_Medical_frt_add4aged: float
Add on floor (as decimal fraction of AGI) for deductible medical expenses for elderly filing units
ID_Medical_hc: float
Medical expense deduction haircut
ID_Casualty_frt: float
Floor (as decimal fraction of AGI) for deductible casualty loss
ID_Casualty_hc: float
Casualty expense deduction haircut
ID_Miscellaneous_frt: float
Floor (as decimal fraction of AGI) for deductible miscellaneous expenses
ID_Miscellaneous_hc: float
Miscellaneous expense deduction haircut
ID_Charity_crt_cash: float
Ceiling (as decimal fraction of AGI) for cash charitable contribution deductions
ID_Charity_crt_noncash: float
Ceiling (as decimal fraction of AGI) for noncash charitable contribution deductions
ID_prt: float
Itemized deduction phaseout rate (Pease)
ID_crt: float
Itemized deduction maximum phaseout as a decimal fraction of total itemized deductions (Pease)
ID_c: list
Ceiling on the amount of itemized deductions allowed (dollars)
ID_StateLocalTax_hc: float
State and local income and sales taxes deduction haircut
ID_Charity_frt: float
Floor (as decimal fraction of AGI) for deductible charitable contributions
ID_Charity_hc: float
Charity expense deduction haircut
ID_InterestPaid_hc: float
Interest paid deduction haircut
ID_RealEstate_hc: float
State, local, and foreign real estate taxes deductions haircut
ID_Medical_c: list
Ceiling on the amount of medical expense deduction allowed (dollars)
ID_StateLocalTax_c: list
Ceiling on the amount of state and local income and sales taxes deduction allowed (dollars)
ID_RealEstate_c: list
Ceiling on the amount of state, local, and foreign real estate taxes deduction allowed (dollars)
ID_InterestPaid_c: list
Ceiling on the amount of interest paid deduction allowed (dollars)
ID_Charity_c: list
Ceiling on the amount of charity expense deduction allowed (dollars)
ID_Casualty_c: list
Ceiling on the amount of casualty expense deduction allowed (dollars)
ID_Miscellaneous_c: list
Ceiling on the amount of miscellaneous expense deduction allowed (dollars)
ID_AllTaxes_c: list
Ceiling on the amount of state and local income, stales, and real estate deductions allowed (dollars)
ID_AllTaxes_hc: float
State and local income, sales, and real estate tax deduciton haircut
ID_StateLocalTax_crt: float
Ceiling (as decimal fraction of AGI) for the combination of all state and local income and sales tax deductions
ID_RealEstate_crt: float
Ceiling (as decimal fraction of AGI) for the combination of all state, local, and foreign real estate tax deductions
ID_Charity_f: list