-
-
Notifications
You must be signed in to change notification settings - Fork 158
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
Changes from 20 commits
d9f3dfd
7afe995
6f7c3d3
dc4a957
5a81635
cf261a0
4e19d7b
30cdfa3
d65022f
79375cf
374dbac
ff0477c
dd4768e
f3bc51f
44f4f0c
446747c
0d06e45
c4e1151
95bf395
1c4cfb4
ad30a1c
b6070c9
a9c1d07
46d2b86
992b44e
166be4f
beac958
1398cb0
40204a1
bd66811
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
============================================= | ||
Distributing the Corporate Income Tax in OSPC | ||
============================================= | ||
------------- | ||
Maria Messick | ||
------------- | ||
|
||
The OSPC Tax-Calculator distributes the corporate income tax to individuals, both capital owners and wage earners. In the absence of this corporate income tax, both capital owners and wage earners would receive higher incomes; therefore, the Tax-Calculator imputes how much of the tax is borne by individuals, adding this to each individual’s expanded income measure. The Tax Policy Center allocates 40% to normal returns and 60% to supernormal returns. TPC then says that the burden on owners of capital that have normal returns can be shifted 50% to labor; therefore, TPC assigns 20% to labor, 20% to normal returns, and 60% to supernormal. However, the Joint Committee on Taxation does not distinguish between normal and supernormal returns to capital and thus allocates 75% of the burden to owners of domestic capital and 25% to wage earners. Where many tax calculators decide on a distribution amount to wage earners and capital owners, OSPC leaves this as a parameter open for the user to change to his/her preference. The OSPC allows a user to specify amount of burden allocated to normal and supernormal returns and then the user may allocate, separately, how the burden for normal and supernormal can be shifted to labor. OSPC assumes that these percentages are achieved in the long run and that the long run is completed at the end of the ten-year budget window, if the legislation is enacted in the first year. Since shifting the burden of the corporate income tax to labor is a long-term development, then in the short run, or year one of the budget window, all revenue from the tax is allocated to capital. Over the ten-year budget window, more and more of the burden in shifted to labor until at the end of the budget window, the given percentages are achieved[1]_. | ||
|
||
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 by taking the percent 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]_. | ||
|
||
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]_. | ||
|
||
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. | ||
|
||
Say the United States collects $100 in corporate tax revenue one year and person 1 receives $60.34 in wages, $20.50 in pass-through income, $2.00 in dividends, $5.50 in net capital gains, and $34.20 in bond revenue in that year. Person 2 receives $82.30 in wages, $15.00 in pass-through income, $20.00 in dividends, $20.25 in net capital gains, and $13.70 in that year. For the purposes of this example, we make the assumption that 20% of the tax is distributed to labor, 20% to normal returns, and 60% to supernormal returns for that year. From this example and using the logic for distributing the corporate income tax outlined above, person 1 will bear 27.29% (8.46% for labor, 9.70% for normal returns, and 9.13% for supernormal returns) and person 2 will bear 72.71% (11.54% for labor, 10.30% for normal returns, and 50.87%) of the burden of the corporate income tax. Thus person 1 pays $27.29 and person 2 pays $72.71 of that $100 revenue. | ||
|
||
|
||
..[1] Following assumptions made by the Joint Committee on Taxation. | ||
|
||
..[2]This sum is calculated in the initialization for a Record object in records.py. | ||
|
||
..[3]Aggregate compensation is calculated in the method aggregate_measures in calculate.py (along with all aggregate measures used). | ||
|
||
..[4]Calculated in the method Dist_Corp_Inc_Tax in functions.py | ||
|
||
..[5]This measure is modeled after that done by the JCT. Calculated in the method Dist_Corp_Inc_Tax in functions.py | ||
|
||
..[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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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): | ||
|
@@ -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 | ||
|
@@ -183,10 +187,56 @@ def increment_year(self): | |
self.records.increment_year() | ||
self.params.increment_year() | ||
|
||
""" | ||
TODO: Corporate Income Tax | ||
|
||
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() | ||
|
||
myfunc = np.vectorize(Dist_Corp_Inc_Tax) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we just apply the @vectorize decorator to |
||
|
||
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.share_corptax_burden, self.records.dividends, | ||
self.records.e_and_p, self.records.netcapgains, self.records.bonds, | ||
self.records.compensation) | ||
|
||
# print self.records.share_corptax_burden | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably want to get rid of this commented out print statement |
||
|
||
def mtr(self, income_type_string, diff=100): | ||
""" | ||
This method calculates the marginal tax rate for every record. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -207,6 +207,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 | ||
|
@@ -374,6 +377,7 @@ def TaxGains(e00650, c04800, e01000, c23650, e23250, e01100, e58990, | |
else: | ||
_hasgain = 0. | ||
|
||
|
||
if _hasgain == 1.: | ||
#if/else 1 | ||
_dwks5 = max(0., e58990 - e58980) | ||
|
@@ -1138,9 +1142,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 | ||
|
@@ -1429,6 +1465,63 @@ 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, share_corptax_burden, | ||
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 | ||
""" | ||
|
||
# self-employment (e09400) | ||
# individual's share of total self-employment | ||
self_employed_and_pt = e_and_p / agg_self_employed_and_pt | ||
|
||
share_of_divs = dividends / agg_dividends | ||
share_of_capgains = netcapgains / agg_capgains | ||
|
||
# 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) * | ||
(share_of_divs * .4 + share_of_capgains * .4 + | ||
self_employed_and_pt * .4 + bonds / agg_bonds) | ||
/ 2.2) | ||
|
||
share_from_supernormal = (percent_supernormal * revenue_collected | ||
* (share_of_divs * .6 + share_of_capgains * .6) | ||
/ 1.2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are the two .6 in this line for the supernormal return percentages of dividends and capital gain? If so, we should probably do the weighted sums of supernormal return and normal return first and then calculate the shares. Calculating the weighted sum of all the share would be fine for share from supernormal return if we assume the percentages of supernormal return are the same for dividends and cap gain, but it doesn't seem to work for the normal return part. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes the .6's are for the supernormal return percentages. Why does it not work for the normal return part? |
||
|
||
# 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, | ||
|
@@ -1445,5 +1538,4 @@ def ExpandIncome(FICA_ss_trt, SS_Earnings_c, e00200, FICA_mc_trt, e02400, | |
+ employer_share_fica) | ||
|
||
|
||
return (_expanded_income) | ||
|
||
return (_expanded_income) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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