$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