-
-
Notifications
You must be signed in to change notification settings - Fork 33
/
get_taxcalc_rates.py
154 lines (137 loc) · 6.35 KB
/
get_taxcalc_rates.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
# imports
import numpy as np
from taxcalc import Policy, Records, Calculator
from ccc.utils import DEFAULT_START_YEAR, TC_LAST_YEAR, RECORDS_START_YEAR
def get_calculator(baseline, calculator_start_year, reform=None,
data='cps', gfactors=None, weights=None,
records_start_year=RECORDS_START_YEAR):
'''
This function creates the tax calculator object for the microsim
Args:
baseline (bool): `True` if baseline tax policy
calculator_start_year (integer): first year of budget window
reform (dictionary): IIT reform parameters
data (string or Pandas DataFrame): path to file or DataFrame
for Tax-Calculator Records object (optional)
weights (DataFrame): weights DataFrame for Tax-Calculator
Records object (optional)
records_start_year (integer): the start year for the data and
weights dfs
Returns:
calc1 (Tax Calculator Calculator object): TC Calculator object
with a current_year equal to calculator_start_year
'''
# create a calculator
policy1 = Policy()
if data is not None and "cps" in data:
records1 = Records.cps_constructor()
# impute short and long term capital gains if using CPS data
# in 2012 SOI data 6.587% of CG as short-term gains
records1.p22250 = 0.06587 * records1.e01100
records1.p23250 = (1 - 0.06587) * records1.e01100
# set total capital gains to zero
records1.e01100 = np.zeros(records1.e01100.shape[0])
elif data is not None: # pragma: no cover
records1 = Records(
data=data, gfactors=gfactors, weights=weights,
start_year=records_start_year) # pragma: no cover
else:
records1 = Records() # pragma: no cover
if baseline:
# Should not be a reform if baseline is True
assert not reform
if not baseline:
policy1.implement_reform(reform)
# the default set up increments year to 2013
calc1 = Calculator(records=records1, policy=policy1)
# this increment_year function extrapolates all PUF variables to
# the next year so this step takes the calculator to the start_year
if calculator_start_year > TC_LAST_YEAR:
raise RuntimeError("Start year is beyond data extrapolation.")
while calc1.current_year < calculator_start_year:
calc1.increment_year()
return calc1
def get_rates(baseline=False, start_year=DEFAULT_START_YEAR, reform={},
data='cps'):
'''
This function computes weighted average marginal tax rates using
micro data from the tax calculator
Args:
baseline (bool): `True` if baseline tax policy, `False` if reform
start_year (integer): first year of budget window
reform (dict): reform parameters
Returns:
individual_rates (dict): individual income (IIT+payroll)
marginal tax rates
'''
calc1 = get_calculator(baseline=baseline,
calculator_start_year=start_year,
reform=reform, data=data)
# running all the functions and calculates taxes
calc1.calc_all()
# Loop over years in window of calculations
end_year = start_year
array_size = end_year - start_year + 1
rates_dict = {'tau_div': 'e00650', 'tau_int': 'e00300',
'tau_scg': 'p22250', 'tau_lcg': 'p23250'}
individual_rates = {
'tau_nc': np.zeros(array_size), 'tau_div': np.zeros(array_size),
'tau_int': np.zeros(array_size), 'tau_scg': np.zeros(array_size),
'tau_lcg': np.zeros(array_size), 'tau_td': np.zeros(array_size),
'tau_h': np.zeros(array_size)}
for year in range(start_year, end_year + 1):
calc1.advance_to_year(year)
print('year: ', str(calc1.current_year))
# Compute mtrs
# Sch C
[mtr_fica_schC, mtr_iit_schC, mtr_combined_schC] =\
calc1.mtr('e00900p')
# Sch E - includes partnership and s corp income
[mtr_fica_schE, mtr_iit_schE, mtr_combined_schE] =\
calc1.mtr('e02000')
# Partnership and s corp income
[mtr_fica_PT, mtr_iit_PT, mtr_combined_PT] = calc1.mtr('e26270')
# pension distributions
# does PUF have e01500? Do we want IRA distributions here?
# Weird - I see e01500 in PUF, but error when try to call it
[mtr_fica_pension, mtr_iit_pension, mtr_combined_pension] =\
calc1.mtr('e01700')
# mortgage interest and property tax deductions
# do we also want mtg ins premiums here?
# mtg interest
[mtr_fica_mtg, mtr_iit_mtg, mtr_combined_mtg] =\
calc1.mtr('e19200')
# prop tax
[mtr_fica_prop, mtr_iit_prop, mtr_combined_prop] =\
calc1.mtr('e18500')
pos_ti = calc1.array("c04800") > 0
individual_rates['tau_nc'][year - start_year] = (
(((mtr_iit_schC * np.abs(calc1.array("e00900p"))) +
(mtr_iit_schE * np.abs(calc1.array("e02000") -
calc1.array("e26270"))) +
(mtr_iit_PT * np.abs(calc1.array("e26270")))) *
pos_ti * calc1.array("s006")).sum() /
((np.abs(calc1.array("e00900p")) +
np.abs(calc1.array("e02000") - calc1.array("e26270")) +
np.abs(calc1.array("e26270"))) *
pos_ti * calc1.array("s006")).sum())
individual_rates['tau_td'][year - start_year] = (
(mtr_iit_pension * calc1.array("e01500") * pos_ti *
calc1.array("s006")).sum() /
(calc1.array("e01500") * pos_ti *
calc1.array("s006")).sum())
individual_rates['tau_h'][year - start_year] = -1 * (
((mtr_iit_mtg * calc1.array("e19200")) +
(mtr_iit_prop * calc1.array("e18500")) * pos_ti *
calc1.array("s006")).sum() / (
(calc1.array("e19200")) + (calc1.array("e18500")) *
pos_ti * calc1.array("s006")).sum())
# Loop over MTRs that have only one income source
for k, v in rates_dict.items():
[mtr_fica, mtr_iit, mtr_combined] = calc1.mtr(v)
individual_rates[k][year - start_year] = (
(mtr_iit * calc1.array(v) * pos_ti *
calc1.array("s006")).sum() /
(calc1.array(v) * pos_ti * calc1.array("s006")).sum())
print(individual_rates)
return individual_rates