Ok, it was a bit of work but I managed to create a MWE so that it is easy to realize where the bug is.
The MWE is available on my github: IntroToLifeCycleModels/ALE/AleModel24.m at main · aledinola/IntroToLifeCycleModels · GitHub
I have modified the orginal example “Life-Cycle Model 24: Using Permanent Type to model fixed-effects” by making very few changes:
- Added a second
z
shock which is age-dependent and that I interpret as a health shock. The probability of getting sick (or remaining sick) increases with age.
- I reduced the number of PT from 5 to 2, also cut number of grid points for labor supply. These are minor changes just to speed up the code.
I compute the life-cycle profiles of assets conditional on health: z2=0 (sick) vs z2=1 (healthy). So first I set up these conditional restrictions in lines 209-213:
%--- Conditional restrictions. Must return either 0 or 1
condres.sick = @(h,aprime,a,z1,z2,e) (z2==0);
condres.healthy = @(h,aprime,a,z1,z2,e) (z2==1);
% Add additional field to simoptions
simoptions.conditionalrestrictions = condres;
Then I compute the life-cycle profiles conditional on health (see lines 217-220):
simoptions.whichstats = [1,1,0,0,0,0,0];
tic
AgeStats=LifeCycleProfiles_FHorz_Case1_PType(StatDist, Policy, FnsToEvaluate, Params,n_d,n_a,n_z,N_j,N_i,d_grid, a_grid, z_grid, simoptions);
toc
Finally I compute the moments conditional on health for the entire population in line 225:
AllStats=EvalFnOnAgentDist_AllStats_FHorz_Case1_PType(StatDist, Policy, FnsToEvaluate, Params,n_d,n_a,n_z,N_j,N_i,d_grid, a_grid, z_grid, simoptions);
I plot the life-cycle profiles for assets conditional on health status (stored in the struct AgeStats
):
figure
plot(1:1:Params.J,AgeStats.sick.assets.Mean)
hold on
plot(1:1:Params.J,AgeStats.assets.Mean)
hold on
plot(1:1:Params.J,AgeStats.healthy.assets.Mean)
hold off
title('Assets by health status')
xlabel('Age, j')
legend('Sick','All','Healthy')
The figure is shown here:
You can see that assets conditional on sick are always lower than assets conditional on healthy, for every age j.
Finally, I show the conditional averages of assets by health obtained in AllStats
as follows
ave_by_health.assets = [AllStats.sick.assets.Mean,...
AllStats.assets.Mean,...
AllStats.healthy.assets.Mean];
disp('THIS IS NOT CONSISTENT WITH THE ASSETS GRAPH!!!!')
fprintf('Average assets <sick> = %f \n',ave_by_health.assets(1))
fprintf('Average assets <all> = %f \n',ave_by_health.assets(2))
fprintf('Average assets <healthy> = %f \n',ave_by_health.assets(3))
The result is:
Average assets <sick> = 2.652637
Average assets <all> = 2.040498
Average assets <healthy> = 1.961682
which is not consistent with the graph: here it seems that sick people hold more assets than healthy, while the opposite was true in the plot based on AgeStats!
@robertdkirkby I would be really grateful if you could look into this potential bug. I suspect that LifeCycleProfiles_FHorz_Case1_PType
is OK but there is some bug in EvalFnOnAgentDist_AllStats_FHorz_Case1_PType
.
Thank you so much!
EDIT
I also show the share of sick (with z2=0) households in the population, by age, in the figure below:
There is a positive correlation between age and sick: older people are more likely to be sick. This might explain why average assets conditional on sick are higher, even though average assets conditional on sick and on age are lower.