This notebooks presents simple computational tools to solve Lucas' asset-pricing model when the logarithm of the asset's dividend follows an autoregressive process of order 1.
\begin{equation*} \ln d_{t+1} = \alpha \ln d_t + \varepsilon_{t+1} \end{equation*}A presentation of this model can be found in Christopher D. Carroll's lecture notes. The pricing equation is:
\begin{equation*} P^*(d_t) = E_{t}\left[ \frac{u(d_{t+1})}{u(d_t)} (P^*(d_{t+1}) + d_{t+1}) \right] \end{equation*}import numpy as np
import matplotlib.pyplot as plt
from copy import copy
from HARK.utilities import CRRAutilityP
from HARK.distribution import Normal
from HARK.interpolation import LinearInterp, ConstantFunction
class DivProcess:
def __init__(self, alpha, shock_sd, nApprox = 7):
self.alpha = alpha
self.shock_sd = shock_sd
self.nApprox = nApprox
# Create a discrete approximation to the random shock
self.ShkAppDstn = Normal(sigma = shock_sd).approx(N = nApprox)
class LucasEconomy:
def __init__(self, CRRA, DiscFac, DivProcess):
self.CRRA = CRRA
self.DiscFac = DiscFac
self.DivProcess = DivProcess
self.uP = lambda c: CRRAutilityP(c, self.CRRA)
def priceOnePeriod(self, Pfunc_next, logDGrid):
# Create 'tiled arrays' rows are state today, columns are value of
# tomorrow's shock
dGrid_N = len(logDGrid)
shock_N = self.DivProcess.nApprox
# Today's dividends
logD_now = np.tile(np.reshape(logDGrid, (dGrid_N,1)),
(1,shock_N))
d_now = np.exp(logD_now)
# Tomorrow's dividends
Shk_next = np.tile(self.DivProcess.ShkAppDstn.X,
(dGrid_N, 1))
Shk_next_pmf = np.tile(self.DivProcess.ShkAppDstn.pmf,
(dGrid_N, 1))
logD_next = self.DivProcess.alpha * logD_now + Shk_next
d_next = np.exp(logD_next)
# Tomorrow's prices
P_next = Pfunc_next(logD_next)
# Compute the RHS of the pricing equation, pre-expectation
SDF = self.DiscFac * self.uP(d_next / d_now)
Payoff_next = P_next + d_next
# Take expectation and discount
P_now = np.sum(SDF*Payoff_next*Shk_next_pmf, axis = 1, keepdims=True)
# Create new interpolating price function
Pfunc_now = LinearInterp(logDGrid, P_now.flatten(), lower_extrap=True)
return(Pfunc_now)
def solve(self, Pfunc_0 = None, logDGrid = None, tol = 1e-5, maxIter = 500, disp = False):
# Initialize the norm
norm = tol + 1
# Initialize Pfunc if initial guess is not provided
if Pfunc_0 is None:
Pfunc_0 = ConstantFunction(0.0)
# Create a grid for log-dividends if one is not provided
if logDGrid is None:
uncond_sd = self.DivProcess.shock_sd / np.sqrt(1 - self.DivProcess.alpha**2)
logDGrid = np.linspace(-5*uncond_sd, 5*uncond_sd, 100)
# Initialize function and compute prices on the grid
Pf_0 = copy(Pfunc_0)
P_0 = Pf_0(logDGrid)
it = 0
while norm > tol and it < maxIter:
# Apply the pricing equation
Pf_next = self.priceOnePeriod(Pf_0, logDGrid)
# Find new prices on the grid
P_next = Pf_next(logDGrid)
# Measure the change between price vectors
norm = np.linalg.norm(P_0 - P_next)
# Update price function and vector
Pf_0 = Pf_next
P_0 = P_next
it = it + 1
# Print iteration information
if disp:
print('Iter:' + str(it) + ' Norm = '+ str(norm))
if disp:
if norm <= tol:
print('Price function converged!')
else:
print('Maximum iterations exceeded!')
self.EqlogPfun = Pf_0
self.EqPfun = lambda d: self.EqlogPfun(np.log(d))
An economy is fully specified by:
# Create a log-AR1 process for dividends
DivProc = DivProcess(alpha = 0.90, shock_sd = 0.1)
# Create an example economy
economy = LucasEconomy(CRRA = 2, DiscFac = 0.95, DivProcess = DivProc)
Once created, the economy can be 'solved', which means finding the equilibrium price function. The distribution of dividends at period $t+1$ depends on the value of dividends at $t$. Thus, $d_t$ is a state variable for the economy. The pricing function gives the price of trees that equates their demand and supply at every level of current dividends $d_t$.
# Solve the economy
economy.solve(disp = True)
# After the economy is solved, we can use its Equilibrium price function
d = 1
print('P({}) = {}'.format(d, economy.EqPfun(d)))
Iter:1 Norm = 15.078492707888971 Iter:2 Norm = 15.364187550629122 Iter:3 Norm = 15.574184260513519 Iter:4 Norm = 15.705321834094176 Iter:5 Norm = 15.758153638835239 Iter:6 Norm = 15.73588081854969 Iter:7 Norm = 15.643515942992448 Iter:8 Norm = 15.487249547338951 Iter:9 Norm = 15.273939284634384 Iter:10 Norm = 15.010720323462312 Iter:11 Norm = 14.704712752277215 Iter:12 Norm = 14.362808402479406 Iter:13 Norm = 13.991522607681395 Iter:14 Norm = 13.59689781058941 Iter:15 Norm = 13.18444788932241 Iter:16 Norm = 12.759133681902245 Iter:17 Norm = 12.325361778696157 Iter:18 Norm = 11.887000083698242 Iter:19 Norm = 11.447404920433039 Iter:20 Norm = 11.009455566257232 Iter:21 Norm = 10.575593039092091 Iter:22 Norm = 10.147860743036276 Iter:23 Norm = 9.727945217684864 Iter:24 Norm = 9.317215747420896 Iter:25 Norm = 8.916761989301403 Iter:26 Norm = 8.527429088845741 Iter:27 Norm = 8.149849988184098 Iter:28 Norm = 7.784474805011756 Iter:29 Norm = 7.4315972860846085 Iter:30 Norm = 7.0913784261129065 Iter:31 Norm = 6.7638674006095245 Iter:32 Norm = 6.449019996648295 Iter:33 Norm = 6.14671474430672 Iter:34 Norm = 5.856766958330836 Iter:35 Norm = 5.578940897797847 Iter:36 Norm = 5.312960243979353 Iter:37 Norm = 5.0585170852813786 Iter:38 Norm = 4.815279584591967 Iter:39 Norm = 4.582898489725015 Iter:40 Norm = 4.3610126327120255 Iter:41 Norm = 4.1492535490197655 Iter:42 Norm = 3.9472493337338275 Iter:43 Norm = 3.7546278385768024 Iter:44 Norm = 3.5710193014570693 Iter:45 Norm = 3.396058489127927 Iter:46 Norm = 3.2293864234827776 Iter:47 Norm = 3.0706517529885966 Iter:48 Norm = 2.919511822717988 Iter:49 Norm = 2.775633489310917 Iter:50 Norm = 2.638693720909024 Iter:51 Norm = 2.5083800165800216 Iter:52 Norm = 2.3843906749157835 Iter:53 Norm = 2.2664349372679156 Iter:54 Norm = 2.1542330274153847 Iter:55 Norm = 2.0475161062743097 Iter:56 Norm = 1.9460261575025615 Iter:57 Norm = 1.84951581747116 Iter:58 Norm = 1.757748161020183 Iter:59 Norm = 1.6704964526515995 Iter:60 Norm = 1.5875438712918462 Iter:61 Norm = 1.5086832154568137 Iter:62 Norm = 1.4337165945370702 Iter:63 Norm = 1.362455110968488 Iter:64 Norm = 1.2947185372413987 Iter:65 Norm = 1.23033499100836 Iter:66 Norm = 1.1691406109627087 Iter:67 Norm = 1.1109792356593937 Iter:68 Norm = 1.0557020870281593 Iter:69 Norm = 1.0031674599693072 Iter:70 Norm = 0.9532404191223034 Iter:71 Norm = 0.9057925036428145 Iter:72 Norm = 0.8607014406123662 Iter:73 Norm = 0.8178508675250673 Iter:74 Norm = 0.777130064149846 Iter:75 Norm = 0.7384336939430914 Iter:76 Norm = 0.7016615550855273 Iter:77 Norm = 0.6667183411342025 Iter:78 Norm = 0.6335134112141001 Iter:79 Norm = 0.6019605696177373 Iter:80 Norm = 0.5719778546400012 Iter:81 Norm = 0.5434873364404882 Iter:82 Norm = 0.5164149236987929 Iter:83 Norm = 0.4906901788103252 Iter:84 Norm = 0.4662461413552101 Iter:85 Norm = 0.4430191595627692 Iter:86 Norm = 0.4209487294896927 Iter:87 Norm = 0.3999773416260161 Iter:88 Norm = 0.3800503346438185 Iter:89 Norm = 0.36111575600511053 Iter:90 Norm = 0.3431242291491914 Iter:91 Norm = 0.32602882698451596 Iter:92 Norm = 0.3097849514162512 Iter:93 Norm = 0.294350218648084 Iter:94 Norm = 0.27968435000273195 Iter:95 Norm = 0.26574906801566756 Iter:96 Norm = 0.2525079975627075 Iter:97 Norm = 0.23992657179175733 Iter:98 Norm = 0.22797194263737228 Iter:99 Norm = 0.21661289570420109 Iter:100 Norm = 0.20581976931505658 Iter:101 Norm = 0.19556437752756273 Iter:102 Norm = 0.18581993693056242 Iter:103 Norm = 0.17656099703984054 Iter:104 Norm = 0.1677633741217996 Iter:105 Norm = 0.15940408827906893 Iter:106 Norm = 0.15146130364147728 Iter:107 Norm = 0.1439142715113105 Iter:108 Norm = 0.13674327631975033 Iter:109 Norm = 0.12992958425762588 Iter:110 Norm = 0.12345539444965622 Iter:111 Norm = 0.11730379254805946 Iter:112 Norm = 0.1114587066266214 Iter:113 Norm = 0.10590486526291548 Iter:114 Norm = 0.10062775770001436 Iter:115 Norm = 0.09561359598672066 Iter:116 Norm = 0.09084927899739298 Iter:117 Norm = 0.08632235823979646 Iter:118 Norm = 0.08202100536185937 Iter:119 Norm = 0.07793398127349448 Iter:120 Norm = 0.07405060680421076 Iter:121 Norm = 0.07036073481929397 Iter:122 Norm = 0.06685472372353021 Iter:123 Norm = 0.06352341228279501 Iter:124 Norm = 0.06035809569867241 Iter:125 Norm = 0.057350502873534576 Iter:126 Norm = 0.05449277480729317 Iter:127 Norm = 0.05177744406948195 Iter:128 Norm = 0.04919741529334438 Iter:129 Norm = 0.04674594664087607 Iter:130 Norm = 0.04441663219091813 Iter:131 Norm = 0.04220338520417634 Iter:132 Norm = 0.04010042222165487 Iter:133 Norm = 0.03810224795504113 Iter:134 Norm = 0.036203640929377674 Iter:135 Norm = 0.03439963984120001 Iter:136 Norm = 0.0326855305960183 Iter:137 Norm = 0.031056833991241317 Iter:138 Norm = 0.029509294013048384 Iter:139 Norm = 0.02803886671595934 Iter:140 Norm = 0.02664170965637178 Iter:141 Norm = 0.025314171852987212 Iter:142 Norm = 0.024052784246501993 Iter:143 Norm = 0.02285425063543841 Iter:144 Norm = 0.02171543906304843 Iter:145 Norm = 0.020633373633658535 Iter:146 Norm = 0.01960522673650031 Iter:147 Norm = 0.018628311656877516 Iter:148 Norm = 0.017700075556095977 Iter:149 Norm = 0.01681809280034165 Iter:150 Norm = 0.015980058622359784 Iter:151 Norm = 0.01518378309922698 Iter:152 Norm = 0.014427185429405995 Iter:153 Norm = 0.013708288495860104 Iter:154 Norm = 0.013025213699242175 Iter:155 Norm = 0.012376176049185275 Iter:156 Norm = 0.011759479499690126 Iter:157 Norm = 0.011173512517372195 Iter:158 Norm = 0.010616743870051496 Iter:159 Norm = 0.010087718625645793 Iter:160 Norm = 0.009585054350193944 Iter:161 Norm = 0.009107437495073919 Iter:162 Norm = 0.008653619965116741 Iter:163 Norm = 0.008222415856479134 Iter:164 Norm = 0.007812698358082112 Iter:165 Norm = 0.0074233968070428 Iter:166 Norm = 0.007053493890810302 Iter:167 Norm = 0.006702022988676632 Iter:168 Norm = 0.006368065646018529 Iter:169 Norm = 0.006050749174048002 Iter:170 Norm = 0.005749244369611467 Iter:171 Norm = 0.005462763348030211 Iter:172 Norm = 0.005190557484364176 Iter:173 Norm = 0.004931915457112754 Iter:174 Norm = 0.004686161389500017 Iter:175 Norm = 0.004452653083105882 Iter:176 Norm = 0.004230780340025857 Iter:177 Norm = 0.004019963367865433 Iter:178 Norm = 0.0038196512649842566 Iter:179 Norm = 0.003629320580780694 Iter:180 Norm = 0.003448473947869851 Iter:181 Norm = 0.0032766387823187086 Iter:182 Norm = 0.0031133660487141146 Iter:183 Norm = 0.0029582290868419873 Iter:184 Norm = 0.002810822496598419 Iter:185 Norm = 0.0026707610786803736 Iter:186 Norm = 0.0025376788281412537 Iter:187 Norm = 0.0024112279776201634 Iter:188 Norm = 0.0022910780889947324 Iter:189 Norm = 0.0021769151894216144 Iter:190 Norm = 0.0020684409512630505 Iter:191 Norm = 0.001965371912341053 Iter:192 Norm = 0.0018674387351128349 Iter:193 Norm = 0.001774385503059461 Iter:194 Norm = 0.0016859690517595238 Iter:195 Norm = 0.0016019583334339167 Iter:196 Norm = 0.0015221338134622437 Iter:197 Norm = 0.0014462868962516382 Iter:198 Norm = 0.0013742193805968913 Iter:199 Norm = 0.001305742941326569 Iter:200 Norm = 0.001240678637559162 Iter:201 Norm = 0.0011788564448671581 Iter:202 Norm = 0.0011201148109929524 Iter:203 Norm = 0.0010643002336428481 Iter:204 Norm = 0.0010112668597027931 Iter:205 Norm = 0.0009608761035358945 Iter:206 Norm = 0.0009129962852601468 Iter:207 Norm = 0.0008675022865696877 Iter:208 Norm = 0.0008242752235950647 Iter:209 Norm = 0.000783202136514188 Iter:210 Norm = 0.0007441756940859759 Iter:211 Norm = 0.000707093913338775 Iter:212 Norm = 0.000671859893111979 Iter:213 Norm = 0.0006383815607183245 Iter:214 Norm = 0.0006065714313622345 Iter:215 Norm = 0.0005763463796863215 Iter:216 Norm = 0.0005476274222568175 Iter:217 Norm = 0.0005203395113877266 Iter:218 Norm = 0.0004944113389892669 Iter:219 Norm = 0.0004697751502526029 Iter:220 Norm = 0.00044636656641791644 Iter:221 Norm = 0.00042412441676137097 Iter:222 Norm = 0.0004029905786897142 Iter:223 Norm = 0.00038290982569547 Iter:224 Norm = 0.0003638296833351196 Iter:225 Norm = 0.00034570029175126654 Iter:226 Norm = 0.0003284742757549766 Iter:227 Norm = 0.0003121066206805196 Iter:228 Norm = 0.00029655455495021315 Iter:229 Norm = 0.00028177743838430193 Iter:230 Norm = 0.00026773665573606747 Iter:231 Norm = 0.0002543955159406151 Iter:232 Norm = 0.00024171915628376633 Iter:233 Norm = 0.00022967445117304619 Iter:234 Norm = 0.00021822992580876867 Iter:235 Norm = 0.00020735567350390417 Iter:236 Norm = 0.0001970232779252552 Iter:237 Norm = 0.0001872057387810324 Iter:238 Norm = 0.00017787740111104093 Iter:239 Norm = 0.00016901388830792538 Iter:240 Norm = 0.00016059203848669895 Iter:241 Norm = 0.00015258984384671046 Iter:242 Norm = 0.00014498639323542832 Iter:243 Norm = 0.00013776181753150983 Iter:244 Norm = 0.00013089723762664616 Iter:245 Norm = 0.0001243747151673472 Iter:246 Norm = 0.00011817720564092735 Iter:247 Norm = 0.00011228851398188839 Iter:248 Norm = 0.0001066932518749241 Iter:249 Norm = 0.00010137679801445978 Iter:250 Norm = 9.632525943205395e-05 Iter:251 Norm = 9.152543572425052e-05 Iter:252 Norm = 8.696478403278947e-05 Iter:253 Norm = 8.263138658783529e-05 Iter:254 Norm = 7.851391944320142e-05 Iter:255 Norm = 7.460162298074915e-05 Iter:256 Norm = 7.088427361592918e-05 Iter:257 Norm = 6.735215737352282e-05 Iter:258 Norm = 6.399604404087815e-05 Iter:259 Norm = 6.080716368004633e-05 Iter:260 Norm = 5.7777183045776195e-05 Iter:261 Norm = 5.489818440711308e-05 Iter:262 Norm = 5.216264430161164e-05 Iter:263 Norm = 4.956341437834568e-05 Iter:264 Norm = 4.709370236453343e-05 Iter:265 Norm = 4.474705443520412e-05 Iter:266 Norm = 4.2517338421445116e-05 Iter:267 Norm = 4.039872767403319e-05 Iter:268 Norm = 3.838568590126034e-05 Iter:269 Norm = 3.647295264578699e-05 Iter:270 Norm = 3.4655529659061604e-05 Iter:271 Norm = 3.292866758577782e-05 Iter:272 Norm = 3.128785394014937e-05 Iter:273 Norm = 2.9728800983237223e-05 Iter:274 Norm = 2.8247434525698872e-05 Iter:275 Norm = 2.683988365650665e-05 Iter:276 Norm = 2.5502470072273455e-05 Iter:277 Norm = 2.4231698898470055e-05 Iter:278 Norm = 2.3024249440011007e-05 Iter:279 Norm = 2.187696637957304e-05 Iter:280 Norm = 2.0786851663575015e-05 Iter:281 Norm = 1.9751056650159408e-05 Iter:282 Norm = 1.8766874624519344e-05 Iter:283 Norm = 1.78317337223524e-05 Iter:284 Norm = 1.6943190286867308e-05 Iter:285 Norm = 1.609892234645736e-05 Iter:286 Norm = 1.5296723737510196e-05 Iter:287 Norm = 1.4534498154511558e-05 Iter:288 Norm = 1.3810253713081922e-05 Iter:289 Norm = 1.3122098001368902e-05 Iter:290 Norm = 1.2468232533587619e-05 Iter:291 Norm = 1.1846948762596811e-05 Iter:292 Norm = 1.1256623186719781e-05 Iter:293 Norm = 1.0695713117563068e-05 Iter:294 Norm = 1.016275285571779e-05 Iter:295 Norm = 9.656349631538816e-06 Price function converged! P(1) = 19.46757396451111
# Create two economies with different risk aversion
Disc = 0.95
LowCrraEcon = LucasEconomy(CRRA = 2, DiscFac = Disc, DivProcess = DivProc)
HighCrraEcon = LucasEconomy(CRRA = 4, DiscFac = Disc, DivProcess = DivProc)
# Solve both
LowCrraEcon.solve()
HighCrraEcon.solve()
# Plot the pricing functions for both
dGrid = np.linspace(0.5,2.5,30)
plt.plot(dGrid, LowCrraEcon.EqPfun(dGrid), label = 'Low CRRA')
plt.plot(dGrid, HighCrraEcon.EqPfun(dGrid), label = 'High CRRA')
plt.legend()
plt.xlabel('$d_t$')
plt.ylabel('$P_t$')
Text(0, 0.5, '$P_t$')