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

[WIP] Distributing the Corporate Income Tax #286

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d9f3dfd
starting on documentation
mmessick Jun 2, 2015
7afe995
added variables to allow the calculation of the distribution of the c…
mmessick Jun 10, 2015
6f7c3d3
removed unnecessary files
mmessick Jun 10, 2015
dc4a957
work in progress of implementing corporate income tax
mmessick Jun 15, 2015
5a81635
updated records file
mmessick Jun 15, 2015
cf261a0
updated model to include passthrough income
mmessick Jun 16, 2015
4e19d7b
updated to fix passthrough value
mmessick Jun 16, 2015
30cdfa3
updates to the corp income tax, runs and gets values now
mmessick Jun 22, 2015
d65022f
update to tests
mmessick Jun 22, 2015
79375cf
merge conflicts resolved
mmessick Jun 22, 2015
374dbac
fixing error for travis build
mmessick Jun 22, 2015
ff0477c
added xml file for paper on the model
mmessick Jun 23, 2015
dd4768e
changed how I calculate percent to normal and supernomal by dividing …
mmessick Jun 25, 2015
f3bc51f
reStructuredText file of the paper explaining how to distribute
mmessick Jun 25, 2015
44f4f0c
fixing merge conflicts
mmessick Jun 25, 2015
446747c
fixing layout for reStructuredText
mmessick Jun 25, 2015
0d06e45
figuring out format
mmessick Jun 25, 2015
c4e1151
formatting
mmessick Jun 25, 2015
95bf395
new functionality for a table showing distribution by decile for the …
mmessick Jun 30, 2015
1c4cfb4
fixing test suite to match
mmessick Jun 30, 2015
ad30a1c
minor changes
mmessick Jul 1, 2015
b6070c9
modified descrip of implementation
mmessick Jul 14, 2015
a9c1d07
changed doc location
mmessick Jul 16, 2015
46d2b86
updated docs for this proposal
mmessick Jul 16, 2015
992b44e
fixed typo
mmessick Jul 17, 2015
166be4f
added bibliography to proposal
mmessick Aug 6, 2015
beac958
Merge branch 'master' of https://github.com/mmessick/Tax-Calculator i…
mmessick Aug 6, 2015
1398cb0
merging
mmessick Aug 6, 2015
40204a1
changed calculation of shares to normal and supernormal
mmessick Aug 8, 2015
bd66811
changed proposal to reflect changes in calculation
mmessick Aug 8, 2015
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
56 changes: 56 additions & 0 deletions CorpIncTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Testing file for calculate.py
"""

from pandas import DataFrame, concat
from taxcalc.calculate import *
from taxcalc.functions import *
from taxcalc.records import *
from taxcalc.parameters import *
import taxcalc.parameters as parameters
import numpy as np
#from timer.timed_calculate import *


def to_csv(fname, df):
"""
Save this dataframe to a CSV file with name 'fname' and containing
a header with the column names of the dataframe.
"""
df.to_csv(fname, float_format= '%1.3f', sep=',', header=True, index=False)



def run(puf=True):
"""
Run each function defined in calculate.py, saving the ouput to a CSV file.
'puf' set to True by default, to use the 'puf2.csv' as an input

For functions returning an additional non-global variable in addition
to the DataFrame to be printed, one line saves the dataFrame to be printed
first, and then saves the variable to be used by a following function second.
"""

# Create a Parameters object
params = Parameters()

# Create a Public Use File object

tax_dta = pd.read_csv("puf.csv")

blowup_factors = "./taxcalc/StageIFactors.csv"
weights = "./taxcalc/WEIGHTS.csv"

puf = Records(tax_dta, blowup_factors, weights)

# Create a Calculator
calc = Calculator(parameters=params, records=puf)
# Dist_Corp_Inc_Tax(calc.params, calc.records)

calc.corp_inc_tax()

create_corpinctax_table(calc, "weighted_deciles", "weighted_sum")


if __name__ == '__main__':
run()
14 changes: 12 additions & 2 deletions docs/proposed_features/DistributingCorpIncTax.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ The OSPC Tax-Calculator distributes the corporate income tax to individuals, bot

The way OSPC accounts for the share of the corporate income tax borne by labor is first to calculate each individual’s compensation share. This is done by summing the individual’s wages, benefits given by the employer, and the untaxed voluntary contribution to his/her retirement plans[2]_ and dividing it by the aggregate compensation[3]_ people earn in the economy. Next, this compensation share is multiplied by the percent borne by labor and multiplied again by the aggregate revenue from the corporate income tax[4]_.

The way OSPC accounts for the share of the corporate income tax borne by supernormal returns to capital is to take the percentage given to distribute to supernormal returns multiplied by the aggregate revenue collected from the tax multiplied by the sum of the individual’s share of the total of dividends in the market times 0.6 and the individual’s share of the capital gains in the market times 0.6[5]_. This value is then divided by 1.2 (the sum of the .6's), so as not to inflate this value from the multplication of the .6's.
The way OSPC accounts for the share of the corporate income tax borne by supernormal returns to capital is to take the percentage given to distribute to supernormal returns multiplied by the aggregate revenue collected from the tax multiplied by the individual’s supernormal returns divided by the total supernormal returns in the economy. OSPC defines supernormal returns as 60% of net capital gains and 60% of dividends[5]_.

The way OSPC accounts for the share of the corporate income tax borne by normal returns to capital is by taking the percent given to distribute to normal returns multiplied by the aggregate revenue collected from the tax multiplied by the sum of the individual’s share of the total dividends in the domestic market times 0.4 and the individual’s share of the capital gains in the domestic market times 0.4 and the individual’s share of self-employment and pass-through income times 0.4 and the individual’s share of the bonds in the domestic market[6]_. This value is then divided by 2.2 (the sum of the .4's and 1), so as not to inflate this value.
The way OSPC accounts for the share of the corporate income tax borne by normal returns to capital is by taking the percent given to distribute to normal returns multiplied by the aggregate revenue collected from the tax multiplied by the individual’s normal returns divided by the total supernormal returns in the economy. OSPC defines the normal returns as 40% of net capital gains, 40% of dividends, 40% of self-employed and pass-through income, and 100% of bond ownership[6]_.

OSPC’s model for labor is limited by lack of information regarding payroll taxes and benefits given by an individual’s employer. Currently, OSPC uses the sum of wages, employer provided benefit for dependent care, Archer MSA, and retirement savings contribution credit to determine an individual’s compensation, but this leaves many other factors out, such as employer’s contribution to health insurance and other contributions to retirement plans[7]_. Limitations on share to capital come from OSPC’s lack of data regarding IRA holdings, 401(k) account ownership, and other self-employment and pass-through income.

Expand All @@ -32,3 +32,13 @@ Say the United States collects $100 in corporate tax revenue one year and person
..[6]Discernment between assets that have a certain percentage from normal returns and supernormal returns was adapted from the Tax Policy Center.

..[7]This measure is modeled after that done by the JCT. Calculated in the method Dist_Corp_Inc_Tax in functions.py

Bibliography
------------
Edward Harris. 2012. “The Distribution of Household Income and Federal Taxes, 2008 and 2009.” Edited by Sherry Snyder. Congressional Budget Office.http://www.cbo.gov/sites/default/files/cbofiles/attachments/43373-AverageTaxRates_screen.pdf.

Jim Nunns. 2012. “How TPC Distributes the Corporate Income Tax.” Tax Policy Center. http://www.taxpolicycenter.org/UploadedPDF/412651-Tax-Model-Corporate-Tax-Incidence.pdf.

Julie-Anne Cronin, Emily Y. Lin, Laura Power, and Michael Cooper. 2012. “Distributing the Corporate Income Tax: Revised U.S. Treasury Methodology.” The Department of the Treasury.http://www.treasury.gov/resource-center/tax-policy/tax-analysis/Documents/OTA-T2012-05-Distributing-the-Corporate-Income-Tax-Methodology-May-2012.pdf.

The Staff of the Joint Committee on Taxation. 2013. “Modeling the Distribution of Taxes on Business Income.” The Joint Committee on Taxation. https://www.jct.gov/publications.html?func=showdown&id=4528.
59 changes: 59 additions & 0 deletions taxcalc/calculate.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ def __init__(self, params=None, records=None, sync_years=True, **kwargs):
print("Your data have beeen extrapolated to "
+ str(self._records.current_year) + ".")

self.corp_inc_tax()

assert self._params.current_year == self._records.current_year

@property
Expand Down Expand Up @@ -142,6 +144,7 @@ def calc_all(self):
C1040(self.params, self.records)
DEITC(self.params, self.records)
OSPC_TAX(self.params, self.records)
self.corp_inc_tax()
ExpandIncome(self.params, self.records)

def calc_all_test(self):
Expand Down Expand Up @@ -175,6 +178,7 @@ def calc_all_test(self):
add_df(all_dfs, C1040(self.params, self.records))
add_df(all_dfs, DEITC(self.params, self.records))
add_df(all_dfs, OSPC_TAX(self.params, self.records))
self.corp_inc_tax()
add_df(all_dfs, ExpandIncome(self.params, self.records))
totaldf = pd.concat(all_dfs, axis=1)
return totaldf
Expand All @@ -183,10 +187,65 @@ def increment_year(self):
self.records.increment_year()
self.params.increment_year()

"""
TODO: Corporate Income Tax
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something left to do here still?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we haven't decided on how we are going to impute it for future years


Change the json parameters for percent_labor, etc.
For example, percent_labor is given to be 25%, but it is a long
term affect for labor to bear the buren of this tax, so year 1
it should be 0 percent and then smoothly transition to 25 percent
over the 10-year budget window
"""

@property
def current_year(self):
return self.params.current_year

def corp_inc_tax(self):
"""
Calculates the aggregate dividends, capital gains, bonds, self-employed
income, and compensation for this calculator's Records attribute
Once calculated, uses these values to determine this caclulator's
Records's shares of the corporate income tax burden
"""

self.records.agg_self_employed_and_pt = (self.records.e_and_p * self.records.s006).sum()

self.records.agg_bonds = (self.records.bonds * self.records.s006).sum()

self.records.agg_comp = (self.records.compensation * self.records.s006).sum()

self.records.agg_capgains = (self.records.netcapgains * self.records.s006).sum()

self.records.agg_dividends = (self.records.dividends * self.records.s006).sum()

self.records.agg_normal = ((self.records.dividends * self.records.s006).sum() * .4
+ (self.records.netcapgains * self.records.s006).sum() * .4
+ (self.records.e_and_p * self.records.s006).sum() * .4
+ (self.records.bonds * self.records.s006).sum())

self.records.agg_supernormal = ((self.records.netcapgains * self.records.s006).sum() * .6
+ (self.records.dividends * self.records.s006).sum() * .6)

myfunc = np.vectorize(Dist_Corp_Inc_Tax)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just apply the @vectorize decorator to Dist_Corp_Inc_Tax?


revenue_collected = 1000000000000.
percent_labor = .2
percent_supernormal = .6
percent_normal = .2

self.records.share_corptax_burden = myfunc(revenue_collected,
percent_labor, percent_supernormal,
percent_normal, self.records.agg_comp, self.records.agg_dividends,
self.records.agg_capgains, self.records.agg_bonds,
self.records.agg_self_employed_and_pt, self.records.agg_normal,
self.records.normal, self.records.agg_supernormal,
self.records.share_corptax_burden, self.records.supernormal,
self.records.dividends, self.records.e_and_p,
self.records.netcapgains, self.records.bonds,
self.records.compensation)


def mtr(self, income_type_string, diff=100):
"""
This method calculates the marginal tax rate for every record.
Expand Down
89 changes: 86 additions & 3 deletions taxcalc/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,9 @@ def ItemDed(_posagi, e17500, e18400, e18425, e18450, e18500, e18800, e18900,
def EI_FICA( e00900, e02100, SS_Earnings_c, e00200,
e11055, e00250, e30100, FICA_ss_trt, FICA_mc_trt):
# Earned Income and FICA #

# employer_share_fica = (max(0, FICA_ss_trt * min(SS_Earnings_c, e00200)
# + FICA_mc_trt * e00200))

_sey = e00900 + e02100
_fica_ss = max(0, FICA_ss_trt * min(SS_Earnings_c, e00200
Expand Down Expand Up @@ -580,6 +583,7 @@ def TaxGains(e00650, c04800, e01000, c23650, e23250, e01100, e58990,
else:
_hasgain = 0.


if _hasgain == 1.:
#if/else 1
_dwks5 = max(0., e58990 - e58980)
Expand Down Expand Up @@ -1402,9 +1406,41 @@ def RefAmOpp(_cmp, c87521, _num, c00100, EDCRAGE, c87668):
def NonEdCr(c87550, MARS, ETC_pe_Married, c00100, _num,
c07180, e07200, c07230, e07240, e07960, e07260, e07300,
e07700, e07250, t07950, c05800, _precrd, ETC_pe_Single, _xlin3, _xlin6, c87668, c87620):
"""
Nonrefundable Education Credits
Form 8863 Tentative Education Credits

Notes
-----
Tax Law Parameters:

e07180 : Child Care Credit

e07200 : Credit for Elderly or Disabled

e07240 : Retirement Savings Contribution Credit

e07960 : Qualified Electric Vehicle Credit

e07260 : Residential Energy Credit

e07300 : Foreign Tax Credit

e07700 : Mortgage Int. Credit

e07250 : Adoption Credit Amt.

Intermediate Variables:

_num : filing status, number of people filing jointly

c87668 : nonrefundable Education Credit

Returns
-------

"""

# Nonrefundable Education Credits
# Form 8863 Tentative Education Credits
c87560 = c87550

# Phase Out
Expand Down Expand Up @@ -1689,6 +1725,54 @@ def Taxer_i(inc_in, MARS, II_rt1, II_rt2, II_rt3, II_rt4, II_rt5, II_rt6,
return inc_out


def Dist_Corp_Inc_Tax(revenue_collected, percent_labor, percent_supernormal,
percent_normal, agg_comp, agg_dividends, agg_capgains,
agg_bonds, agg_self_employed_and_pt, agg_normal, normal,
agg_supernormal, share_corptax_burden, supernormal,
dividends, e_and_p, netcapgains, bonds, compensation):
"""
This function calculates the burden of the corporate income tax borne
by an individual in the economy. It also incorporates this burden into
our measure of the individual's expanded income.

Parameters
----------
revenue_collected : float
value of yearly revenue estimated to be collected in aggregate from the
corporate income tax assigned by the user
percent_labor : float
percent of the burden that will be borne by labor
percent_normal : float
percent of the burden that will be borne by normal returns
percent_supernormal : float
percent of the burden that will be borne by supernormal returns

Returns
-------
share_corptax_burden : float
individual's share of the corporate income tax
"""

# adapted from the JCT
share_from_labor = (percent_labor * revenue_collected *
compensation / agg_comp)

# adapted from the JCT and TPC
share_from_normal = (percent_normal * revenue_collected
* normal / agg_normal)

share_from_supernormal = (percent_supernormal * revenue_collected
* supernormal / agg_supernormal)

# individual's share of the corporate income tax
share_corptax_burden = share_from_labor + share_from_normal + share_from_supernormal

# incorporating the burden into our measure of expanded income
# expanded_income = expanded_income + corp_tax_burden

return share_corptax_burden


@iterate_jit(nopython=True, parameters=['FICA_ss_trt', 'SS_Earnings_c',
'FICA_mc_trt'])
def ExpandIncome(FICA_ss_trt, SS_Earnings_c, e00200, FICA_mc_trt, e02400,
Expand All @@ -1706,4 +1790,3 @@ def ExpandIncome(FICA_ss_trt, SS_Earnings_c, e00200, FICA_mc_trt, e02400,


return (_expanded_income)

50 changes: 47 additions & 3 deletions taxcalc/params.json
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@
},
"_CG_rt1":{
"long_name": "Long term capital gain and qualified dividends rate 1",
"description": "",
"description": "",
"start_year": 2013,
"col_var": "",
"row_var": "",
Expand Down Expand Up @@ -1146,7 +1146,7 @@
"col_label": "",
"value": [0.20]
},
"_CG_thd1":{
"_CG_thd1":{
"long_name": "Long term capital gain and qualified dividends threshold 1",
"description": "",
"start_year": 2013,
Expand Down Expand Up @@ -1208,7 +1208,7 @@
"col_label": "",
"value": [0.20]
},
"_AMT_CG_thd1":{
"_AMT_CG_thd1":{
"long_name": "Long term capital gain and qualified dividend threshold 1",
"description": "",
"start_year": 2013,
Expand All @@ -1233,5 +1233,49 @@
"value": [ [400000, 450000, 225000, 425000, 450000, 225000],
[406750, 457600, 228800, 432200, 457600, 228800],
[413200, 464850, 223425, 439000, 464850, 223425]]
},
"revenue_collected":{
"long_name": "Yearly Revnue Collected by the Corporate Income Tax",
"description": "",
"start_year": 2013,
"col_var": "",
"row_var": "",
"row_label": "",
"cpi_inflated": false,
"col_label": "",
"value": [20000]
},
"percent_labor":{
"long_name": "Percent of the Corporate Income Tax allocated to Labor",
"description": "",
"start_year": 2013,
"col_var": "",
"row_var": "",
"row_label": "",
"cpi_inflated": false,
"col_label": "",
"value": [0.20]
},
"percent_supernormal":{
"long_name": "Percent of the Corporate Income Tax allocated to Supernormal Returns",
"description": "",
"start_year": 2013,
"col_var": "",
"row_var": "",
"row_label": "",
"cpi_inflated": false,
"col_label": "",
"value": [0.60]
},
"percent_normal":{
"long_name": "Percent of the Corporate Income Tax allocated to Normal Returns",
"description": "",
"start_year": 2013,
"col_var": "",
"row_var": "",
"row_label": "",
"cpi_inflated": false,
"col_label": "",
"value": [0.20]
}
}
Loading