Skip to content

Commit 22d47c9

Browse files
committed
Added incomplete AuerbachKotlikoff1987 which replicates Chapter 5 (incomplete as does transition paths, but not yet doing them with the welfare-compensating transfers)
1 parent c1612c7 commit 22d47c9

4 files changed

+361
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
% Replication of: Auerbach & Kotlikoff (1987) - Dynamic Fiscal Policy,
2+
% Chapter 5.
3+
4+
% INCOMPLETE:Calculate all the equilibria, and have transition paths but
5+
% they do not yet incorporate the welfare-compenstating transfers.
6+
7+
% A few lines needed for running on the Server
8+
addpath(genpath('./MatlabToolkits/'))
9+
try % Server has 16 cores, but is shared with other users, so use max of 8.
10+
parpool(8)
11+
gpuDevice(1)
12+
catch % Desktop has less than 8, so will give error, on desktop it is fine to use all available cores.
13+
parpool
14+
end
15+
PoolDetails=gcp;
16+
NCores=PoolDetails.NumWorkers;
17+
18+
%%
19+
20+
n_l=51;
21+
n_a=251;
22+
N_j=55;
23+
24+
n_z=1; z_grid=0; pi_z=1; % Deterministic model, so no exogenous shocks z.
25+
26+
%% Parameters
27+
28+
Params.J=N_j;
29+
Params.jj=1:1:Params.J;
30+
31+
% Discount rate
32+
Params.delta=0.015;
33+
Params.beta=1/(1+Params.delta);
34+
35+
% Constant population growth rate
36+
Params.n=0.01;
37+
38+
% Utility function parameters
39+
Params.rho=0.8;
40+
Params.gamma=0.25;
41+
Params.alpha=1.5;
42+
% Params.ej=4.47+0.033*Params.jj-0.00067*Params.jj.^2; % Footnote on pg 52.
43+
% Given Figure 5.2 I suspected may be a typo (that or noone is working more than 0.1 of time)
44+
% Lines 47-50, 62 & 1393 of aktax3.for in codes https://ideas.repec.org/c/dge/qmrbcd/90.html confirm that it should actually be the following
45+
Params.ej=exp(0.47+0.033*Params.jj-0.00067*Params.jj.^2)/(exp(0.47+0.033-0.00067));
46+
% That is, they normalize ej at age 1 to take value of 1.
47+
48+
% Tax parameters for baseline
49+
Params.tau_phi=0.15; % Proportional income tax. This is the only tax used as part of baseline.
50+
Params.tau_pi=0; % Progressivity of income tax.
51+
Params.tau_c=0; % Consumption tax.
52+
Params.tau_w=0; % Earnings (wage income) tax.
53+
Params.tau_k=0; % Capital income tax
54+
Params.z=0; % Fraction of investment which can be deducted from corporate income tax.
55+
56+
% Firm production function
57+
Params.epsilon=0.25; % Capital share in the Cobb-Douglas production fn
58+
Params.sigma=1; % Not actually used (have hard-coded the Cobb-Douglas production function rather than more general CES prodn fn)
59+
Params.A=0.892657593; % Technology level
60+
% Investment adjustment-costs
61+
b=0; % Set to b=10 for Chapter 9
62+
% Note: there is no capital depreciation.
63+
64+
65+
%% Grids
66+
a_grid=gpuArray(linspace(0,7,n_a(1))'); % Is impossition of NO BORROWING CORRECT HERE OR DO THEY ALLOW IT TO BE NEGATIVE???
67+
l_grid=gpuArray(linspace(0,1,n_l)');
68+
69+
%% General eqm variables: give some initial values
70+
GEPriceParamNames={'wt','rt','Gt'};
71+
Params.wt=1; % wage rate
72+
Params.rt=0.067; % interest rate (after corporate taxes, but before income taxes)
73+
Params.Gt=0.7; % Government consumption
74+
75+
%% Initial distribution of agents at age 20 (jj=1)
76+
jequaloneDist=zeros(n_a,1);
77+
jequaloneDist(1,1)=1; % All agents born with zero assets
78+
79+
%% Return Function
80+
DiscountFactorParamNames={'beta'};
81+
ReturnFn=@(l,aprime,a,z,jj,wt,rt,rho,gamma,alpha,ej,tau_phi,tau_pi,tau_c,tau_w) AuerbachKotlikoff1987_ReturnFn(l,aprime,a,z,jj,wt,rt,rho,gamma,alpha,ej,tau_phi,tau_pi,tau_c,tau_w)
82+
ReturnFnParamNames={'jj','wt','rt','rho','gamma','alpha','ej','tau_phi','tau_pi','tau_c','tau_w'}; %It is important that these are in same order as they appear in 'AuerbachKotlikoff1987_ReturnFn'
83+
84+
%% Misc
85+
n_d=n_l;
86+
d_grid=l_grid;
87+
88+
sprintf('Grid sizes:')
89+
n_a
90+
n_z
91+
92+
vfoptions.verbose=1;
93+
vfoptions.policy_forceintegertype=1; % Policy was not being treated as integers (one of the elements was 10^(-15) different from an integer)
94+
95+
%% Now solve the value function iteration problem (this is just for trying out codes before jumping to general eqm)
96+
97+
tic;
98+
[V, Policy]=ValueFnIter_Case1_FHorz(n_d,n_a,n_z,N_j,d_grid, a_grid, z_grid, pi_z, ReturnFn, Params, DiscountFactorParamNames, ReturnFnParamNames, vfoptions);
99+
toc
100+
101+
%% Agents stationary distribution
102+
% Based on the constant population growth rate n, we get that the
103+
% population weights will be
104+
Params.mewj=ones(1,Params.J);
105+
for jj=2:length(Params.mewj)
106+
Params.mewj(jj)=Params.mewj(jj-1)/(1+Params.n);
107+
end
108+
Params.mewj=Params.mewj./sum(Params.mewj);
109+
110+
simoptions.nsims=4*10^5;
111+
simoptions.ncores=NCores;
112+
simoptions.iterate=1;
113+
AgeWeights={'mewj'}; % Many finite horizon models apply different weights to different 'ages'; eg., due to survival rates or population growth rates.
114+
StationaryDist=StationaryDist_FHorz_Case1(jequaloneDist,AgeWeights,Policy,n_d,n_a,n_z,N_j,pi_z,Params,simoptions);
115+
116+
117+
%% General Equilibrium Conditions (aka. marketclearance)
118+
119+
% Steady State Aggregates (important that ordering of Names and Functions is the same)
120+
SSvalueParamNames=struct();
121+
SSvalueParamNames(1).Names={};
122+
SSvalueParamNames(2).Names={'ej'};
123+
SSvalueParamNames(3).Names={'wt','rt','ej','tau_phi','tau_pi','tau_c','tau_w','tau_k'};
124+
SSvaluesFn_1 = @(d_val,aprime_val,a_val,z_val) a_val; % Aggregate assets (which is this periods state)
125+
SSvaluesFn_2 = @(d_val,aprime_val,a_val,z_val,ej) (1-d_val)*ej; % Aggregate labour supply (in efficiency units)
126+
SSvaluesFn_3 = @(d_val,aprime_val,a_val,z_val, wt,rt,ej,tau_phi,tau_pi,tau_c,tau_w,tau_k) AuerbachKotlikoff1987_TotalTaxRevenue(d_val,aprime_val,a_val,z_val,wt,rt,ej,tau_phi,tau_pi,tau_c,tau_w,tau_k); % Total tax revenues
127+
SSvaluesFn={SSvaluesFn_1,SSvaluesFn_2,SSvaluesFn_3};
128+
129+
% General Equilibrium Equations
130+
GeneralEqmEqnParamNames=struct();
131+
GeneralEqmEqnParamNames(1).Names={'epsilon'};
132+
GeneralEqmEqn_1 = @(AggVars,p,epsilon) p(1)-(1-epsilon)*(AggVars(1)^epsilon)*(AggVars(2)^(-epsilon)); % The requirement that the wage rate equals the marginal product of (efficiency units of) labor.
133+
GeneralEqmEqnParamNames(2).Names={'epsilon'};
134+
GeneralEqmEqn_2 = @(AggVars,p,epsilon) p(2)-(epsilon)*(AggVars(1)^(epsilon-1))*(AggVars(2)^(1-epsilon)); % Rate of return on assets is related to Marginal Product of Capital and Tobin's q
135+
%^PRESENTLY IGNORES TOBINS q
136+
GeneralEqmEqnParamNames(3).Names={};
137+
GeneralEqmEqn_3 = @(AggVars,p) p(3)-AggVars(3); % Government balanced budget constraint
138+
GeneralEqmEqns={GeneralEqmEqn_1,GeneralEqmEqn_2,GeneralEqmEqn_3};
139+
140+
141+
%% Test
142+
SSvalues_AggVars=SSvalues_AggVars_FHorz_Case1(StationaryDist, Policy, SSvaluesFn, Params, SSvalueParamNames, n_d, n_a, n_z,N_j, d_grid, a_grid, z_grid, 2); % The 2 is for Parallel (use GPU)
143+
144+
%% Solve for the General Equilibrium
145+
% Use the toolkit to find the equilibrium price index
146+
147+
% GEPriceParamNames={'wt','rt','Gt'}; % Already delared above.
148+
wt_grid=linspace(0.5,2,21)'*Params.wt; %bad
149+
rt_grid=linspace(0.5,2,21)'*Params.rt; %okay
150+
Gt_grid=linspace(0.5,2,21)'*Params.Gt; %good
151+
p_grid=[wt_grid,rt_grid,Gt_grid];
152+
153+
disp('Calculating price vector corresponding to the stationary eqm')
154+
% tic;
155+
n_p=[length(wt_grid),length(rt_grid),length(Gt_grid)];
156+
heteroagentoptions.pgrid=p_grid;
157+
heteroagentoptions.verbose=1;
158+
[p_eqm_init,p_eqm_index, GeneralEqmEqnsValues]=HeteroAgentStationaryEqm_Case1_FHorz(jequaloneDist,AgeWeights,n_d, n_a, n_z, N_j, n_p, pi_z, d_grid, a_grid, z_grid, ReturnFn, SSvaluesFn, GeneralEqmEqns, Params, DiscountFactorParamNames, ReturnFnParamNames, SSvalueParamNames, GeneralEqmEqnParamNames, GEPriceParamNames, heteroagentoptions, simoptions, vfoptions);
159+
% findeqmtime=toc
160+
Params.wt=p_eqm_init(1);
161+
Params.rt=p_eqm_init(2);
162+
Params.Gt=p_eqm_init(3);
163+
164+
save ./SavedOutput/AuerbachKotlikoff1987_GE.mat Params
165+
166+
%% Get Value fn, policy fn, agents dist in GE.
167+
%Params.wt=1; % wage rate
168+
%Params.rt=0.067; % interest rate (after corporate taxes, but before income taxes)
169+
170+
[V_init, Policy_init]=ValueFnIter_Case1_FHorz(n_d,n_a,n_z,N_j,d_grid, a_grid, z_grid, pi_z, ReturnFn, Params, DiscountFactorParamNames, ReturnFnParamNames, vfoptions);
171+
StationaryDist_init=StationaryDist_FHorz_Case1(jequaloneDist,AgeWeights,Policy_init,n_d,n_a,n_z,N_j,pi_z,Params,simoptions);
172+
173+
% Rather than have the population normalized to 1 (I prefer this as then
174+
% the model can be thought of in terms of probability distributions)
175+
% Auerbach & Kotlikoff (1987) normalize their population so that the mass
176+
% of agents of 'age' j=1 is mass one. The following is a correcting factor:
177+
Params.PopnCorrection=gather(1/sum(sum(sum(StationaryDist_init(:,:,1)))));
178+
179+
%% For baseline (initial) steady-state, replicate Table 5.1 and Figure 5.2
180+
181+
SSvalueParamNames(4).Names={'wt','rt','ej','tau_phi','tau_pi','tau_c','tau_w'};
182+
SSvaluesFn_4 = @(d_val,aprime_val,a_val,z_val,wt,rt,ej,tau_phi,tau_pi,tau_c,tau_w) AuerbachKotlikoff1987_ConsumptionFn(d_val,aprime_val,a_val,z_val,wt,rt,ej,tau_phi,tau_pi,tau_c,tau_w); % Private Consumption
183+
SSvalueParamNames(5).Names={'delta'};
184+
SSvaluesFn_5 = @(d_val,aprime_val,a_val,z_val,delta) aprime_val-(1-delta)*a_val; % National Savings rate (gross rate)
185+
SSvalueParamNames(6).Names={'wt','ej'};
186+
SSvaluesFn_6 = @(d_val,aprime_val,a_val,z_val,wt,ej) wt*(1-d_val)*ej; % Earnings (pre-tax)
187+
SSvaluesFn={SSvaluesFn_1,SSvaluesFn_2,SSvaluesFn_3,SSvaluesFn_4,SSvaluesFn_5,SSvaluesFn_6};
188+
SSvalues_AggVars=SSvalues_AggVars_FHorz_Case1(StationaryDist_init, Policy_init, SSvaluesFn, Params, SSvalueParamNames, n_d, n_a, n_z,N_j, d_grid, a_grid, z_grid, 2); % The 2 is for Parallel (use GPU)
189+
SSvalues_AggVars=Params.PopnCorrection*SSvalues_AggVars; % Renormalize to AK1987 population size
190+
191+
if Params.sigma==1 % Cobb-Douglas
192+
Y=Params.A*(SSvalues_AggVars(1)^Params.epsilon)*(SSvalues_AggVars(2)^(1-Params.epsilon));
193+
end
194+
195+
% Table 5_1
196+
FID = fopen('./SavedOutput/LatexInputs/AuerbachKotlikoff_Table5_1.tex', 'w');
197+
fprintf(FID, 'The Base Case Steady-State \\\\ \n');
198+
fprintf(FID, '\\begin{tabular*}{1.00\\textwidth}{@{\\extracolsep{\\fill}}lcclc} \n \\hline \\hline \n');
199+
fprintf(FID, 'Capital Stock & %8.1f & \\quad & Private Consumption & %8.2f \\\\ \n \\hline \n', SSvalues_AggVars(1),SSvalues_AggVars(4));
200+
fprintf(FID, 'Labor Supply & %8.1f & & Capital-Output ratio & %8.2f \\\\ \n \\hline \n', SSvalues_AggVars(2),SSvalues_AggVars(1)/Y);
201+
fprintf(FID, 'Wage & %8.3f & & National Savings rate & %8.2f \\%% \\\\ \n \\hline \n', Params.wt,(Params.delta*SSvalues_AggVars(1))/Y);
202+
fprintf(FID, 'Pre-tax interest rate & %8.2f \\%% & & Income Tax rate & %8.2f \\%% \\\\ \n \\hline \n', 100*Params.rt,100*Params.tau_phi);
203+
fprintf(FID, 'National Income & %8.2f & & Social Security Tax rate & %8.2f \\%% \\\\ \n \\hline \n', Y,0);
204+
fprintf(FID, 'Government Consumption & %8.2f & & Social Security replacement rate & %8.2f \\%% \\\\ \n \\hline \n', Params.PopnCorrection*Params.Gt,0);
205+
fprintf(FID, '\\hline \n \\end{tabular*} \n');
206+
fprintf(FID, '\\begin{minipage}[t]{1.00\\textwidth}{\\baselineskip=.5\\baselineskip \\vspace{.3cm} \\footnotesize{ \n');
207+
fprintf(FID, 'Note: Based on grid sizes of $n_l=%d$ for leisure, and $n_a=%d$ for assets. \\\\ \n', n_d, n_a);
208+
fprintf(FID, '}} \\end{minipage}');
209+
fclose(FID);
210+
211+
SimLifeCycleProfiles=SimLifeCycleProfiles_FHorz_Case1(jequaloneDist,Policy_init, SSvaluesFn,SSvalueParamNames,Params,n_d,n_a,n_z,N_j,d_grid,a_grid,z_grid,pi_z, simoptions);
212+
213+
% Figure 5.2
214+
figure(1)
215+
plot(1:1:N_j, SimLifeCycleProfiles(4,:,1),1:1:N_j, SimLifeCycleProfiles(6,:,1))
216+
legend('Consumption','Earnings')
217+
saveas(gcf,'./SavedOutput/Graphs/Figure_5_2.pdf')
218+
219+
% plot(Params.ej)
220+
221+
222+
%% Calculate some transition paths
223+
224+
% Auerbach & Kotlikoff (1987) define the tax reforms in Chapter 5
225+
% based on keeping government spending the same and setting tax rates to
226+
% raise this revenue.
227+
% To implement this we have to switch our definition of the GE prices, so
228+
% that instead of finding G we find the tax rate (for the relevant reform).
229+
230+
%% Consumption Tax
231+
232+
%% Calculate the final equilibrium
233+
Params.tau_phi=0;
234+
GEPriceParamNames={'wt','rt','tau_c'};
235+
236+
% First, calculate the final general equilibrium.
237+
GeneralEqmEqnParamNames(3).Names={'Gt'};
238+
GeneralEqmEqn_3 = @(AggVars,p, Gt) Gt-AggVars(3); % Government balanced budget constraint (role of GEPriceParamNames already in AggVars(3) which is total tax revenues)
239+
GeneralEqmEqns={GeneralEqmEqn_1,GeneralEqmEqn_2,GeneralEqmEqn_3};
240+
241+
tauc_grid=linspace(0,0.2,21)';
242+
p_grid=[wt_grid,rt_grid,tauc_grid];
243+
244+
disp('Calculating price vector corresponding to the final stationary eqm')
245+
n_p=[length(wt_grid),length(rt_grid),length(tauc_grid)];
246+
heteroagentoptions.pgrid=p_grid;
247+
heteroagentoptions.verbose=1;
248+
[p_eqm_final,p_eqm_index, GeneralEqmEqnsValues]=HeteroAgentStationaryEqm_Case1_FHorz(jequaloneDist,AgeWeights,n_d, n_a, n_z, N_j, n_p, pi_z, d_grid, a_grid, z_grid, ReturnFn, SSvaluesFn, GeneralEqmEqns, Params, DiscountFactorParamNames, ReturnFnParamNames, SSvalueParamNames, GeneralEqmEqnParamNames, GEPriceParamNames, heteroagentoptions, simoptions, vfoptions);
249+
250+
Params.wt=p_eqm_final(1);
251+
Params.rt=p_eqm_final(2);
252+
Params.tau_c=p_eqm_final(3);
253+
[V_final, Policy_final]=ValueFnIter_Case1_FHorz(n_d,n_a,n_z,N_j,d_grid, a_grid, z_grid, pi_z, ReturnFn, Params, DiscountFactorParamNames, ReturnFnParamNames, vfoptions);
254+
255+
256+
%%
257+
save ./SavedOutput/AuerbachKotlikoff1987_TransitionPathSetup.mat V_final StationaryDist_init n_d n_a n_z N_j pi_z d_grid a_grid z_grid ReturnFn SSvaluesFn GeneralEqmEqns Params DiscountFactorParamNames ReturnFnParamNames SSvalueParamNames GeneralEqmEqnParamNames p_eqm_init p_eqm_final
258+
259+
% load ./SavedOutput/AuerbachKotlikoff1987_TransitionPathSetup.mat V_final StationaryDist_init n_d n_a n_z N_j pi_z d_grid a_grid z_grid ReturnFn SSvaluesFn GeneralEqmEqns Params DiscountFactorParamNames ReturnFnParamNames SSvalueParamNames GeneralEqmEqnParamNames p_eqm_init p_eqm_final
260+
261+
%% Now, the transition path
262+
% For this we need the following extra objects: PricePathOld, PriceParamNames, ParamPath, ParamPathNames, T, V_final, StationaryDist_init
263+
% (already calculated V_final & StationaryDist_init above)
264+
Params.tau_phi=0.15;
265+
Params.wt=p_eqm_init(1);
266+
Params.rt=p_eqm_init(2);
267+
Params.tau_c=0;
268+
269+
p_init=[p_eqm_init(1);p_eqm_init(2);0];
270+
p_final=p_eqm_final;
271+
272+
% Number of time periods to allow for the transition (if you set T too low
273+
% it will cause problems, too high just means run-time will be longer).
274+
T=150
275+
276+
% We want to look at a one off unanticipated change of tax rate tau_phi. ParamPath & PathParamNames are thus given by
277+
ParamPath=zeros(T,1); % ParamPath is matrix of size T-by-'number of parameters that change over path'
278+
% (the way ParamPath is set is designed to allow for a series of changes in the parameters)
279+
ParamPathNames={'tau_phi'}; % This is the parameter that gets changed 'away' from it's initial value.
280+
% Consumption tax is considered a GEPriceParam, hence why it is not here.
281+
282+
% We need to give an initial guess for the price path on interest rates
283+
PricePath0_1=[linspace(p_init(1), p_final(1), floor(T/2))'; p_final(1)*ones(T-floor(T/2),1)];
284+
PricePath0_2=[linspace(p_init(2), p_final(2), floor(T/2))'; p_final(2)*ones(T-floor(T/2),1)];
285+
PricePath0_3=[linspace(p_init(3), p_final(3), floor(T/2))'; p_final(3)*ones(T-floor(T/2),1)];
286+
PricePath0=[PricePath0_1,PricePath0_2,PricePath0_3];% PricePath0 is matrix of size T-by-'number of prices'
287+
PricePathNames={'rt','wt','tau_c'};
288+
289+
% Now just run the TransitionPath_Case1 command (all of the other inputs
290+
% are things we had already had to define to be able to solve for the
291+
% initial and final equilibria)
292+
transpathoptions.weightscheme=1;
293+
transpathoptions.verbose=1;
294+
295+
%%
296+
vfoptions.policy_forceintegertype=1
297+
PricePathNew=TransitionPath_Case1_Fhorz(PricePath0, PricePathNames, ParamPath, ParamPathNames, T, V_final, StationaryDist_init, n_d, n_a, n_z, N_j, pi_z, d_grid,a_grid,z_grid, ReturnFn, SSvaluesFn, GeneralEqmEqns, Params, DiscountFactorParamNames, ReturnFnParamNames, AgeWeights, SSvalueParamNames, GeneralEqmEqnParamNames,transpathoptions);
298+
299+
300+
301+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function c=AuerbachKotlikoff1987_ConsumptionFn(l,aprime,a,z,wt,rt,ej,tau_phi,tau_pi,tau_c,tau_w)
2+
% z is unused as model is deterministic
3+
% F=-Inf;
4+
5+
%c=(1+rt)*a+wt*ej*(1-l)-aprime; % in absence of taxes
6+
TaxableIncome=rt*a+(1-tau_w)*wt*ej*(1-l);
7+
c=(1/(1+tau_c))*((1-(tau_phi+tau_pi*TaxableIncome/2))*TaxableIncome+a-aprime);
8+
% ((tau_phi+tau_pi*TaxableIncome/2) is average tax rate on taxable income
9+
%
10+
% if c>0
11+
% Finner=(c^(1-1/rho)+alpha*l^(1-1/rho))^(1/(1-1/rho));
12+
% F=(Finner^(1-1/gamma))/(1-1/gamma);
13+
% end
14+
%
15+
% if jj==55 && aprime<0
16+
% F=-Inf; % Impose a_J>=0
17+
% end
18+
19+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function F=AuerbachKotlikoff1987_ReturnFn(l,aprime,a,z,jj,wt,rt,rho,gamma,alpha,ej,tau_phi,tau_pi,tau_c,tau_w)
2+
% z is unused as model is deterministic
3+
F=-Inf;
4+
5+
%c=(1+rt)*a+wt*ej*(1-l)-aprime; % in absence of taxes
6+
TaxableIncome=rt*a+(1-tau_w)*wt*ej*(1-l);
7+
c=(1/(1+tau_c))*((1-(tau_phi+tau_pi*TaxableIncome/2))*TaxableIncome+a-aprime);
8+
% ((tau_phi+tau_pi*TaxableIncome/2) is average tax rate on taxable income
9+
10+
if c>0
11+
Finner=(c^(1-1/rho)+alpha*l^(1-1/rho))^(1/(1-1/rho));
12+
F=(Finner^(1-1/gamma))/(1-1/gamma);
13+
end
14+
15+
if jj==55 && aprime<0
16+
F=-Inf; % Impose a_J>=0
17+
end
18+
19+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function TotalRevenue=AuerbachKotlikoff1987_TotalTaxRevenue(l,aprime,a,z,wt,rt,ej,tau_phi,tau_pi,tau_c,tau_w,tau_k)
2+
% z is unused as model is deterministic
3+
4+
%c=(1+rt)*a+wt*ej*(1-l)-aprime; % in absence of taxes
5+
6+
% Revenue from earnings tax:
7+
Revenue_w=tau_w*wt*ej*(1-l);
8+
9+
% Revenue from capital income tax
10+
Revenue_capital=tau_k*(1/(1-tau_k)*rt)*a; %rt is after-capital-tax (but before income tax). So 1/(1-tau_k)*rt give the before-capital-tax rate of return on capital
11+
12+
TaxableIncome=rt*a+(1-tau_w)*wt*ej*(1-l);
13+
% Revenue from income tax:
14+
Revenue_income=(tau_phi+tau_pi*TaxableIncome/2)*TaxableIncome; % ((tau_phi+tau_pi*TaxableIncome/2) is average tax rate on taxable income
15+
16+
c=(1/(1+tau_c))*((1-(tau_phi+tau_pi*TaxableIncome/2))*TaxableIncome+a-aprime);
17+
% Revenue from consumption tax:
18+
Revenue_c=tau_c*c;
19+
20+
TotalRevenue=Revenue_w+Revenue_capital+Revenue_income+Revenue_c;
21+
22+
end

0 commit comments

Comments
 (0)