$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