Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename/remove a few policy params and archive some pre-TCJA reforms #2223

Merged
merged 8 commits into from
Feb 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 24 additions & 31 deletions docs/cookbook/recipe01.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,48 @@
import pandas as pd
from taxcalc import *

# read two "old" reform files from Tax-Calculator website
# ("old" means the reform files are defined relative to pre-TCJA policy)
# For more about the compound-reform technique used in this recipe,
# read answer to Question 1 of FAQ at the following URL:
# https://github.com/PSLmodels/Tax-Calculator/issues/1830
# read an "old" reform file from Tax-Calculator website
# ("old" means the reform file is defined relative to pre-TCJA policy)
REFORMS_URL = ('https://raw.githubusercontent.com/'
'PSLmodels/Tax-Calculator/master/taxcalc/reforms/')

baseline_name = '2017_law.json' # pre-TCJA policy
baseline_url = REFORMS_URL + baseline_name
baseline = Calculator.read_json_param_objects(baseline_url, None)

reform1_name = 'TCJA_Senate.json' # TCJA as orginally proposed in Senate
reform1_url = REFORMS_URL + reform1_name
reform2_name = 'TCJA_Reconciliation.json' # TCJA as passed by Congress
reform2_url = REFORMS_URL + reform2_name
reform_name = 'TCJA.json' # TCJA as passed by Congress
reform_url = REFORMS_URL + reform_name

# specify Policy object for static analysis of reform1 relative to pre-TCJA
reform1 = Calculator.read_json_param_objects(reform1_url, None)
policy1 = Policy()
policy1.implement_reform(baseline['policy'], print_warnings=False)
policy1.implement_reform(reform1['policy'], print_warnings=False)
# specify Policy object for pre-TCJA baseline
bpolicy = Policy()
bpolicy.implement_reform(baseline['policy'], print_warnings=False)
assert not bpolicy.parameter_errors

# specify Policy object for static analysis of reform2 relative to pre-TCJA
reform2 = Calculator.read_json_param_objects(reform2_url, None)
policy2 = Policy()
policy1.implement_reform(baseline['policy'], print_warnings=False)
policy2.implement_reform(reform2['policy'], print_warnings=False)
# specify Policy object for static analysis of reform relative to pre-TCJA
reform = Calculator.read_json_param_objects(reform_url, None)
rpolicy = Policy()
rpolicy.implement_reform(baseline['policy'], print_warnings=False)
assert not rpolicy.parameter_errors
rpolicy.implement_reform(reform['policy'], print_warnings=False)
assert not rpolicy.parameter_errors

cyr = 2018

# specify Calculator objects using policy1 and policy2 and calculate for cyr
# specify Calculator objects using bpolicy and rpolicy and calculate for cyr
recs = Records.cps_constructor()
calc1 = Calculator(policy=policy1, records=recs)
calc1 = Calculator(policy=bpolicy, records=recs)
calc1.advance_to_year(cyr)
calc1.calc_all()
calc2 = Calculator(policy=policy2, records=recs)
calc2 = Calculator(policy=rpolicy, records=recs)
calc2.advance_to_year(cyr)
calc2.calc_all()

# compare aggregate individual income tax revenue in cyr
iitax_rev1 = calc1.weighted_total('iitax')
iitax_rev2 = calc2.weighted_total('iitax')

# construct reform2-vs-reform1 difference table with results for income deciles
diff_table = calc1.difference_table(calc2, 'weighted_deciles', 'iitax')
# construct reform-vs-baseline difference table with results for income deciles
diff_table = calc2.difference_table(calc1, 'weighted_deciles', 'iitax')
assert isinstance(diff_table, pd.DataFrame)
diff_extract = pd.DataFrame()
dif_colnames = ['count', 'tax_cut', 'tax_inc',
Expand All @@ -58,12 +54,9 @@

# print total revenue estimates for cyr
# (estimates in billons of dollars rounded to nearest tenth of a billion)
print('{}_REFORM1_iitax_rev($B)= {:.3f}'.format(cyr, iitax_rev1 * 1e-9))
print('{}_REFORM2_iitax_rev($B)= {:.3f}'.format(cyr, iitax_rev2 * 1e-9))
print('{}_BASELINE_iitax_rev($B)= {:.3f}'.format(cyr, iitax_rev1 * 1e-9))
print('{}_REFORM___iitax_rev($B)= {:.3f}'.format(cyr, iitax_rev2 * 1e-9))
print('')

title = 'Extract of {} income-tax difference table by expanded-income decile'
print(title.format(cyr))
print('(taxfall is count of funits with cut in income tax in reform 2 vs 1)')
print('(taxrise is count of funits with rise in income tax in reform 2 vs 1)')
print(diff_extract.to_string())
# print reform-vs-baseline difference table
print(diff_extract)
15 changes: 11 additions & 4 deletions docs/index.htmx
Original file line number Diff line number Diff line change
Expand Up @@ -1029,15 +1029,24 @@ section.</p>

<!-- Nonrefundable Credits @ Child And Dependent Care -->

<!-- Nonrefundable Credits @ Child Tax Credit -->

<!-- Nonrefundable Credits @ Misc. Credit Limits -->

<!-- Nonrefundable Credits @ Personal Nonrefundable Credit -->

<p><a href="#pol">Back to Section Contents</a></p>


<h3 id="pol-childdependent-credits">Child/Dependent Credits</h3>

<!-- Child/Dependent Credits @ Child Tax Credit -->

<!-- Child/Dependent Credits @ Additional Child Tax Credit -->

<!-- Child/Dependent Credits @ Other Dependent Tax Credit -->

<p><a href="#pol">Back to Section Contents</a></p>


<h3 id="pol-itemized-deductions">Itemized Deductions</h3>

<!-- Itemized Deductions @ Medical Expenses -->
Expand Down Expand Up @@ -1098,8 +1107,6 @@ section.</p>

<!-- Refundable Credits @ Earned Income Tax Credit -->

<!-- Refundable Credits @ Additional Child Tax Credit -->

<!-- Refundable Credits @ New Refundable Child Tax Credit -->

<!-- Refundable Credits @ Personal Refundable Credit -->
Expand Down
59 changes: 19 additions & 40 deletions taxcalc/calcfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ def ALD_InvInc_ec_base(p22250, p23250, sep,

@iterate_jit(nopython=True)
def CapGains(p23250, p22250, sep, ALD_StudentLoan_hc,
ALD_InvInc_ec_rt, invinc_ec_base, ALD_InvInc_ec_base_RyanBrady,
ALD_InvInc_ec_rt, invinc_ec_base,
e00200, e00300, e00600, e00650, e00700, e00800,
CG_nodiff, CG_ec, CG_reinvest_ec_rt,
ALD_BusinessLosses_c, MARS,
Expand All @@ -301,18 +301,6 @@ def CapGains(p23250, p22250, sep, ALD_StudentLoan_hc,
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 exclusion of investment income for Ryan-Brady plan
if ALD_InvInc_ec_base_RyanBrady:
# This RyanBrady code interprets the Blueprint reform as providing
# an investment income AGI exclusion for each of three investment
# income types (e00300, e00650, p23250) separately. The alternative
# interpretation (that is not adopted here) is that the investment
# income AGI exclusion is calculated using a base that is the sum
# of those three investment income types, with the base being zero
# if the sum of the three is negative.
CG_ec_RyanBrady = (c01000 - max(-3000. / sep,
p22250 + ALD_InvInc_ec_rt * p23250))
invinc_agi_ec = ALD_InvInc_ec_rt * (e00300 + e00650) + CG_ec_RyanBrady
# compute ymod1 variable that is included in AGI
ymod1 = (e00200 + e00700 + e00800 + e01400 + e01700 +
invinc - invinc_agi_ec + e02100 + e02300 +
Expand Down Expand Up @@ -1233,20 +1221,17 @@ def ChildDepTaxCredit(n24, MARS, c00100, XTOT, num, c05800,
c07230,
e07240, CR_RetirementSavings_hc,
c07200,
CTC_c, CTC_ps, CTC_prt, exact,
DependentCredit_Child_c, DependentCredit_Nonchild_c,
CTC_c_under5_bonus, nu05, FilerCredit_c,
c07220, dep_credit, codtc_limited):
CTC_c, CTC_ps, CTC_prt, exact, ODC_c,
CTC_c_under5_bonus, nu05,
c07220, odc, codtc_limited):
"""
Computes amounts on "Child Tax Credit and Credit for Other Dependents
Worksheet" in 2018 Publication 972, which pertain to these two
nonrefundable tax credits.
"""
# Worksheet Part 1
line1 = ((CTC_c + DependentCredit_Child_c) * n24 +
CTC_c_under5_bonus * nu05)
line2 = (DependentCredit_Nonchild_c * max(0, XTOT - n24 - num) +
FilerCredit_c[MARS - 1])
line1 = CTC_c * n24 + CTC_c_under5_bonus * nu05
line2 = ODC_c * max(0, XTOT - n24 - num)
line3 = line1 + line2
modAGI = c00100 # no foreign earned income exclusion to add to AGI (line6)
if line3 > 0. and modAGI > CTC_ps[MARS - 1]:
Expand All @@ -1273,14 +1258,14 @@ def ChildDepTaxCredit(n24, MARS, c00100, XTOT, num, c05800,
line16 = 0.
# separate the CTC and ODTC amounts
c07220 = 0. # nonrefundable CTC amount
dep_credit = 0. # nonrefundable ODTC amount
odc = 0. # nonrefundable ODTC amount
if line16 > 0.:
if line1 > 0.:
c07220 = line16 * line1 / line3
dep_credit = max(0., line16 - c07220)
odc = max(0., line16 - c07220)
# compute codtc_limited for use in AdditionalCTC function
codtc_limited = max(0., line10 - line16)
return (c07220, dep_credit, codtc_limited)
return (c07220, odc, codtc_limited)


@iterate_jit(nopython=True)
Expand Down Expand Up @@ -1500,14 +1485,13 @@ def CharityCredit(e19800, e20100, c00100, CR_Charity_rt, CR_Charity_f,

@iterate_jit(nopython=True)
def NonrefundableCredits(c05800, e07240, e07260, e07300, e07400,
e07600, p08000, dep_credit,
e07600, p08000, odc,
personal_nonrefundable_credit,
CR_RetirementSavings_hc, CR_ForeignTax_hc,
CR_ResidentialEnergy_hc, CR_GeneralBusiness_hc,
CR_MinimumTax_hc, CR_OtherCredits_hc, charity_credit,
c07180, c07200, c07220, c07230, c07240,
c07260, c07300, c07400, c07600, c08000,
DependentCredit_before_CTC):
c07260, c07300, c07400, c07600, c08000):
"""
NonRefundableCredits function sequentially limits credits to tax liability.

Expand All @@ -1534,13 +1518,12 @@ def NonrefundableCredits(c05800, e07240, e07260, e07300, e07400,
# Retirement savings credit - Form 8880
c07240 = min(e07240 * (1. - CR_RetirementSavings_hc), avail)
avail = avail - c07240
if DependentCredit_before_CTC:
# Other dependent credit
dep_credit = min(dep_credit, avail)
avail = avail - dep_credit
# Child tax credit
c07220 = min(c07220, avail)
avail = avail - c07220
# Other dependent credit
odc = min(odc, avail)
avail = avail - odc
# Residential energy credit - Form 5695
c07260 = min(e07260 * (1. - CR_ResidentialEnergy_hc), avail)
avail = avail - c07260
Expand All @@ -1553,10 +1536,6 @@ def NonrefundableCredits(c05800, e07240, e07260, e07300, e07400,
# Schedule R credit
c07200 = min(c07200, avail)
avail = avail - c07200
if not DependentCredit_before_CTC:
# Dependent credit
dep_credit = min(dep_credit, avail)
avail = avail - dep_credit
# Other credits
c08000 = min(p08000 * (1. - CR_OtherCredits_hc), avail)
avail = avail - c08000
Expand All @@ -1565,13 +1544,13 @@ def NonrefundableCredits(c05800, e07240, e07260, e07300, e07400,
# Personal nonrefundable credit
personal_nonrefundable_credit = min(personal_nonrefundable_credit, avail)
avail = avail - personal_nonrefundable_credit
return (c07180, c07200, c07220, c07230, c07240, dep_credit,
return (c07180, c07200, c07220, c07230, c07240, odc,
c07260, c07300, c07400, c07600, c08000, charity_credit,
personal_nonrefundable_credit)


@iterate_jit(nopython=True)
def AdditionalCTC(codtc_limited, CTC_c, n24, earned, ACTC_Income_thd,
def AdditionalCTC(codtc_limited, ACTC_c, n24, earned, ACTC_Income_thd,
ACTC_rt, nu05, ACTC_rt_bonus_under5family, ACTC_ChildNum,
ptax_was, c03260, e09800, c59660, e11200,
c11070):
Expand All @@ -1581,7 +1560,7 @@ def AdditionalCTC(codtc_limited, CTC_c, n24, earned, ACTC_Income_thd,
"""
# Part I
line3 = codtc_limited
line4 = CTC_c * n24
line4 = ACTC_c * n24
c11070 = 0. # line15
if line3 > 0. and line4 > 0.:
line5 = min(line3, line4)
Expand Down Expand Up @@ -1612,15 +1591,15 @@ def AdditionalCTC(codtc_limited, CTC_c, n24, earned, ACTC_Income_thd,
@iterate_jit(nopython=True)
def C1040(c05800, c07180, c07200, c07220, c07230, c07240, c07260, c07300,
c07400, c07600, c08000, e09700, e09800, e09900, niit, othertaxes,
c07100, c09200, dep_credit, charity_credit,
c07100, c09200, odc, charity_credit,
personal_nonrefundable_credit):
"""
Computes total used nonrefundable credits, c07100, othertaxes, and
income tax before refundable credits, c09200.
"""
# total used nonrefundable credits (as computed in NonrefundableCredits)
c07100 = (c07180 + c07200 + c07600 + c07300 + c07400 + c07220 + c08000 +
c07230 + c07240 + c07260 + dep_credit + charity_credit +
c07230 + c07240 + c07260 + odc + charity_credit +
personal_nonrefundable_credit)
# tax after credits (2016 Form 1040, line 56)
tax_net_nonrefundable_credits = max(0., c05800 - c07100)
Expand Down
19 changes: 16 additions & 3 deletions taxcalc/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,25 @@ def _validate_parameter_names_types(self, reform):
in the specified reform dictionary.
"""
# pylint: disable=too-many-branches,too-many-nested-blocks
# pylint: disable=too-many-locals
# pylint: disable=too-many-statements,too-many-locals
removed_param_names = set([
'_DependentCredit_Child_c',
'_DependentCredit_Nonchild_c',
'_DependentCredit_before_CTC',
'_FilerCredit_c',
'_ALD_InvInc_ec_base_RyanBrady'
])
param_names = set(self._vals.keys())
for year in sorted(reform.keys()):
for name in reform[year]:
if name.endswith('_cpi'):
if isinstance(reform[year][name], bool):
pname = name[:-4] # root parameter name
if pname not in param_names:
msg = '{} {} unknown parameter name'
if pname in removed_param_names:
msg = '{} {} is a removed parameter name'
else:
msg = '{} {} is an unknown parameter name'
self.parameter_errors += (
'ERROR: ' + msg.format(year, name) + '\n'
)
Expand All @@ -477,7 +487,10 @@ def _validate_parameter_names_types(self, reform):
)
else: # if name does not end with '_cpi'
if name not in param_names:
msg = '{} {} unknown parameter name'
if name in removed_param_names:
msg = '{} {} is a removed parameter name'
else:
msg = '{} {} is an unknown parameter name'
self.parameter_errors += (
'ERROR: ' + msg.format(year, name) + '\n'
)
Expand Down
Loading