$title Overlapping Generations Modeling with MPSGE: A Pure Exchange Model
* Thomas F. Rutherford
* Department of Economics
* University of Colorado
* February, 1998
$setglobal horizon 150
$setglobal sigma 0.5
sets
g All generations and time periods /t1*t%horizon%/,
t(g) Time periods in the transition model
tl Life cycle /1*60/,
r interest rates for exploring the steady-state /r0*r70/,
* Logical sets used for distinguishing the initial and final periods in the
* model:
tfirst(g) First time period
tlast(g) Last time period
sigval Elasticities for steady-state analysis /"0.25", "0.5", "0.75"/
* Sets defined to produce labels in the gnuplot calls:
decade(*) /6 25, 31 50, 56 75/,
byage(*) /t10 "-50", t35 "-25", t60 "0", t85 "25", t110 "50", t135 "75"/,
intrate(r) labels for plot of the steady-state equilibrium /r0 -5, r10 0, r30 10, r50 20, r70 30/;
alias (tl,ttl), (g,gg);
t(g) = yes$(ord(g) gt card(tl)-1);
tfirst(g) = yes$(ord(g) eq smin(gg$t(gg), ord(gg)));
tlast(g) = yes$(ord(g) eq card(g));
display tfirst;
scalar sigma Elasticity of intertemporal substitution,
r0 Baseline interest rate /0.05/
g0 Reference consumption growth rate /0.01/
rho Calibrated rate of time preference;
* Calibrate the discount rate to the specified
* reference interest and growth rate:
rho = (1+r0) / (1+g0) - 1;
parameter endow(tl) Endowments over the lifecycle (exogenous)
pref(g) Reference price path
distrib Endowment and income distribution over a lifecycle
ir(r) Numerical value of the interest rate
gr(r) Growth rate for various interest rates
cl0(r) Base consumption
cl(tl,r) Consumption level
pl(tl,r) Price path
deviation Income balance in steady-state
e(g,*) Endowments by generation and time period,
d(g,*) Reference demand by generation and time period (based on g0)
p0(*) Reference prices by period (based on r0)
age(g,*) Age of generation g in time period t
excess(g,*) Excess demand by generation g in time period t (for computing e0 and et)
e0(*) Initial endowments for generates born prior to initial period
et(*) Terminal endowments for generations dying after the final period
w0(g) Baseline welfare index (for computing equivalent variation)
scenario1 10% Proportional Reduction in Initial Assets
scenario2 10% Random Perturbation of Initial Assets;
* Read endowments profile:
$include endow.dat
* Convert endowments to shares:
endow(ttl) = endow(ttl) / sum(tl, endow(tl));
* Set up a file for storing solution values:
file ksol /%horizon%.sol/;
$libinclude gams2prm
*----------------------------------------------------------------------------------------------
* Plot the lifecycle distribution of endowment and earnings:
distrib(tl,"supply") = endow(tl) + eps;
distrib(tl,"earnings") = eps + (1/(1+r0))**(ord(tl)-1) * endow(tl) /
sum(ttl, (1/(1+r0))**(ord(ttl)-1) * endow(ttl));
$setglobal gp_key 'top right'
$setglobal gp_xl decade
$setglobal gp_xlabel age
$setglobal gp_ylabel density
$libinclude gnuplot distrib
put ksol;
$libinclude gams2prm distrib
*----------------------------------------------------------------------------------------------
* Generate a graphical representation of the steady-state equilibrium:
* Consider interest rates ranging from -5% to 30%:
ir(r) = -0.05 + 0.35 * (ord(r)-1)/(card(r)-1);
* For each interest rate, compute the present value price
* of output over a lifecycle:
pl(tl,r) = (1/(1+ir(r)))**(ord(tl)-1);
display ir;
* Consider alternative intertemporal elasticities of substitution:
loop(sigval,
sigma = 0.25 * ord(sigval);
* Given the interest rate, first-order conditions determine the
* consumption growth rate over a typical lifecycle:
gr(r) = (1 + g0) * ( (1+ir(r)) / ( (1+rho) * (1+g0) ) )**sigma - 1;
* Market clearance then determines the time-path of consumption:
cl0(r) = sum(tl, endow(tl)) / sum(tl, (1+gr(r))**ord(tl));
cl(tl,r) = cl0(r) * (1+gr(r))**ord(tl);
* Given a time path of consumption, we can then compute an index
* of deviation from steady-state equilibrium using the percentage imbalance
* in the present value of consumption relative to the present value
* of endowments:
deviation(r,sigval) = 100 * sum(tl, pl(tl,r) * (cl(tl,r) - endow(tl))) / sum(tl, pl(tl,r) * endow(tl));
);
* Plot the deviations:
$setglobal gp_key 'top right'
$setglobal gp_row r
$setglobal gp_xl intrate
$setglobal gp_grid yes
$setglobal gp_xlabel interest rate \%
$setglobal gp_ylabel budget devation \%
$libinclude gnuplot deviation
put ksol;
$libinclude gams2prm deviation
* Assign a particular value of sigma for the subsequent calculations:
sigma = %sigma%;
*----------------------------------------------------------------------------------------------
* Set up and solve the steady-state growth path for this value of sigma:
variables grate growth rate in consumption
irate interest rate
c0 base year consumption level;
equations gdef optimality condition in consumption determines growth rate,
mkt market clearance condition
budget income balance condition;
gdef.. (1+grate) =e= (1 + g0) * ( (1+irate) / ( (1+rho) * (1 + g0) ) )**sigma;
mkt.. c0 * sum(tl, (1+grate)**ord(tl) ) =e= sum(tl, endow(tl));
budget.. sum(tl, (1/(1+irate))**ord(tl) * (c0 * (1+grate)**ord(tl) - endow(tl))) =e= 0;
model sseq / gdef.grate, mkt.c0, budget.irate/;
grate.l = g0;
irate.l = ( (1+g0)*(1+rho) )**(1/sigma) - 1;
c0.l = sum(tl, endow(tl)) / sum(tl, (1+g0)**ord(tl) );
solve sseq using mcp;
*----------------------------------------------------------------------------------------------
* Set up endowments for the intertemporal model:
* Age of generation g in time period t:
age(g,gg)$t(gg) = ord(gg) - ord(g) + 1;
* Reference prices for the steady-state equilibrium and
* for the calibrated preferences:
pref(t) = 1;
p0(t) = 1;
loop(g$t(g),
pref(g+1) = pref(g) /(1 + irate.l);
p0(g+1) = p0(g) / (1 + r0);
);
* Labor endowements during time periods of the model:
e(g,t) = sum(tl$(ord(tl) eq age(g,t)), endow(tl));
d(g,t) = sum(tl$(ord(tl) eq age(g,t)), c0.l * (1+g0)**ord(tl));
* Compute net assets for generations born prior to the first time period,
* assuming an initial steady-state.
* Begin by computing the excess demands by time period for every generation
* over the model horizon:
excess(g,t)$((age(g,t) ge 1) * (age(g,t) le card(tl))) =
sum(tl$( (ord(tl) gt card(tl)-ord(g)) and (age(g,t) eq ord(tl)) ), c0.l * (1+grate.l)**ord(tl) - endow(tl) );
display excess;
* In steady-state, assets in the first period equal the difference
* between the present value of consumption and income over the model period:
e0(g)$(not t(g)) = sum(t, pref(t) * excess(g,t));
e0("checksum") = sum(g, e0(g));
* Terminal endowments are generated for generations born within the model horizon.
* The magnitude of the terminal adjustment equals the present value of the income
* imbalance over the time horizon converted into units of terminal period goods:
loop((g,tlast)$(age(g,tlast) lt card(tl)), et(g) = sum(t, pref(t) * excess(g,t)) / pref(tlast); );
et("checksum") = sum(g, et(g));
display e,d,e0,et;
$ontext
$model:olg
$commodities:
p(g)$t(g) ! Output prices in period g
$consumers:
ra(g) ! Consumer born in period g
$demand:ra(g) s:sigma
e:p(tfirst) q:e0(g)
e:p(tlast) q:et(g)
e:p(t) q:e(g,t)
d:p(t) q:d(g,t) p:p0(t)
$report:
v:welfare(g) w:ra(g)
$offtext
$sysinclude mpsgeset olg
* -----------------------------------------------------------------------
* Baseline replication:
p.l(t) = pref(t);
* Assign a numeraire price index to prevent MPSGE from
* fixing an income level to 1 (along the steady-state, all
* generations have income levels less than 1):
p.fx(tfirst) = p.l(tfirst);
olg.iterlim = 0;
$include olg.gen
solve olg using mcp;
olg.iterlim = 8000;
* Save baseline welfare indices for computing equivalent
* variations in the subsequent counterfactuals:
w0(g) = welfare.l(g);
* -----------------------------------------------------------------------
* Scenario #1
* Reduce endowments proportionally by 10%. This
* improves welfare for net creditors (the young) and
* decreases welfare for net debtors (the old):
e0(g) = 0.90 * e0(g);
olg.iterlim = 8000;
$include olg.gen
solve olg using mcp;
scenario1(g,"ev") = 100 * (welfare.l(g)/w0(g) - 1);
scenario1(g,"r")$(not t(g)) = 100 * irate.l;
scenario1(g,"r")$(t(g)*t(g+1)) = 100 * (p.l(g)/p.l(g+1) - 1);
scenario1(tlast,"r") = na;
$setglobal gp_key 'top right'
$setglobal gp_row g
$setglobal gp_xl byage
$setglobal gp_grid no
$setglobal gp_xlabel generation or year
$setglobal gp_ylabel value in \%
$libinclude gnuplot scenario1
put ksol;
$libinclude gams2prm scenario1
* -----------------------------------------------------------------------
* Scenario #2
* Perform a random perturbation of initial assets:
e0(g) = e0(g) / 0.9;
e0(g) = uniform(0.9,1.1) * e0(g);
* Scale endowments so that the net value of initial
* assets is zero:
e0(g)$(e0(g) gt 0) = e0(g) * sum(gg$(e0(gg) lt 0), -e0(gg))
/ sum(gg$(e0(gg) gt 0), e0(gg));
$include olg.gen
solve olg using mcp;
scenario2(g,"ev") = 100 * (welfare.l(g)/w0(g) - 1);
scenario2(g,"r")$(not t(g)) = 100 * irate.l;
scenario2(g,"r")$(t(g)*t(g+1)) = 100 * (p.l(g)/p.l(g+1) - 1);
scenario2(tlast,"r") = na;
$setglobal gp_key 'top right'
$setglobal gp_row g
$setglobal gp_xl byage
$setglobal gp_grid no
$setglobal gp_xlabel generation or year
$setglobal gp_ylabel value in \%
$libinclude gnuplot scenario2
put ksol;
$libinclude gams2prm scenario2