├── Figures
├── log_wealth_1.jpg
├── log_wealth_1.pdf
├── log_wealth_1.png
├── target_wealth.jpg
├── target_wealth.pdf
├── target_wealth.png
├── savings_function.jpg
├── savings_function.pdf
├── savings_function.png
├── aggregate_savings.jpg
├── aggregate_savings.pdf
├── aggregate_savings.png
├── log_wealth_3_types.jpg
├── log_wealth_3_types.pdf
├── log_wealth_3_types.png
├── consumption_function.jpg
├── consumption_function.pdf
├── consumption_function.png
├── wealth_distribution_1.jpg
├── wealth_distribution_1.pdf
├── wealth_distribution_1.png
├── wealth_distribution_2.jpg
├── wealth_distribution_2.pdf
├── wealth_distribution_2.png
├── aggregate_savings.svg
├── savings_function.svg
├── consumption_function.svg
├── target_wealth.svg
└── wealth_distribution_1.svg
├── reproduce.sh
├── binder
└── environment.yml
├── KrusellSmith.bib
├── REMARK.md
├── CITATION.cff
├── README.md
├── .gitignore
└── Code
└── Python
└── KrusellSmith.py
/Figures/log_wealth_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/log_wealth_1.jpg
--------------------------------------------------------------------------------
/Figures/log_wealth_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/log_wealth_1.pdf
--------------------------------------------------------------------------------
/Figures/log_wealth_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/log_wealth_1.png
--------------------------------------------------------------------------------
/Figures/target_wealth.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/target_wealth.jpg
--------------------------------------------------------------------------------
/Figures/target_wealth.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/target_wealth.pdf
--------------------------------------------------------------------------------
/Figures/target_wealth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/target_wealth.png
--------------------------------------------------------------------------------
/Figures/savings_function.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/savings_function.jpg
--------------------------------------------------------------------------------
/Figures/savings_function.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/savings_function.pdf
--------------------------------------------------------------------------------
/Figures/savings_function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/savings_function.png
--------------------------------------------------------------------------------
/Figures/aggregate_savings.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/aggregate_savings.jpg
--------------------------------------------------------------------------------
/Figures/aggregate_savings.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/aggregate_savings.pdf
--------------------------------------------------------------------------------
/Figures/aggregate_savings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/aggregate_savings.png
--------------------------------------------------------------------------------
/Figures/log_wealth_3_types.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/log_wealth_3_types.jpg
--------------------------------------------------------------------------------
/Figures/log_wealth_3_types.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/log_wealth_3_types.pdf
--------------------------------------------------------------------------------
/Figures/log_wealth_3_types.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/log_wealth_3_types.png
--------------------------------------------------------------------------------
/Figures/consumption_function.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/consumption_function.jpg
--------------------------------------------------------------------------------
/Figures/consumption_function.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/consumption_function.pdf
--------------------------------------------------------------------------------
/Figures/consumption_function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/consumption_function.png
--------------------------------------------------------------------------------
/Figures/wealth_distribution_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/wealth_distribution_1.jpg
--------------------------------------------------------------------------------
/Figures/wealth_distribution_1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/wealth_distribution_1.pdf
--------------------------------------------------------------------------------
/Figures/wealth_distribution_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/wealth_distribution_1.png
--------------------------------------------------------------------------------
/Figures/wealth_distribution_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/wealth_distribution_2.jpg
--------------------------------------------------------------------------------
/Figures/wealth_distribution_2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/wealth_distribution_2.pdf
--------------------------------------------------------------------------------
/Figures/wealth_distribution_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/econ-ark/KrusellSmith/HEAD/Figures/wealth_distribution_2.png
--------------------------------------------------------------------------------
/reproduce.sh:
--------------------------------------------------------------------------------
1 | # execute the script to create figures
2 | cd Code/Python
3 | ipython --classic --matplotlib=agg KrusellSmith.py
4 |
--------------------------------------------------------------------------------
/binder/environment.yml:
--------------------------------------------------------------------------------
1 | channels:
2 | - conda-forge
3 | - defaults
4 | dependencies:
5 | - python=3.8
6 | - econ-ark=0.10.8
7 | - ipython
8 |
--------------------------------------------------------------------------------
/KrusellSmith.bib:
--------------------------------------------------------------------------------
1 | @article{krusell1998income,
2 | title={Income and wealth heterogeneity in the macroeconomy},
3 | author={Krusell, Per and Smith, Jr, Anthony A},
4 | journal={Journal of political Economy},
5 | volume={106},
6 | number={5},
7 | pages={867--896},
8 | year={1998},
9 | publisher={The University of Chicago Press}
10 | }
--------------------------------------------------------------------------------
/REMARK.md:
--------------------------------------------------------------------------------
1 | ---
2 | # Econ-ARK website fields
3 | remark-version: "1.0"
4 | remark-name: KrusellSmith
5 | notebooks:
6 | - Code/Python/KrusellSmith.ipynb
7 |
8 | tags: # Use the relavent tags
9 | - REMARK
10 | - Notebook
11 |
12 | ---
13 |
14 |
15 |
16 | # KrusellSmith
17 |
18 | [](https://mybinder.org/v2/gh/econ-ark/KrusellSmith/HEAD)
19 |
20 | This is a Replication of Krusell and Smith, 1998.
21 |
22 |
23 | ## References
24 |
25 | Krusell, P., & Smith, Jr, A. A. (1998). Income and wealth heterogeneity in the macroeconomy. Journal of political Economy, 106(5), 867-896.
26 |
27 |
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | cff-version: "1.2.0"
2 | message: "If you use this software, please cite it as below."
3 | authors:
4 | - family-names: "Carroll"
5 | given-names: "Christopher D."
6 | orcid: "https://orcid.org/0000-0003-3732-9312"
7 | title: "Income and Wealth Heterogeneity in the Macroeconomy"
8 | abstract: "Income and wealth heterogeneity in the macroeconomy"
9 |
10 | references:
11 | - type: article
12 | authors:
13 | - family-names: "Krusell"
14 | given-names: "Per"
15 | - family-names: "Smith, Jr."
16 | given-names: "Anthony A."
17 | title: "Income and Wealth Heterogeneity in the Macroeconomy"
18 | doi: "10.1086/250034"
19 | date-released: 1998-10-01
20 | publisher:
21 | name: "Journal of Political Economy"
22 |
23 | repository-code: https://github.com/econ-ark/KrusellSmith
24 |
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KrusellSmith
2 |
3 | [](https://mybinder.org/v2/gh/econ-ark/KrusellSmith/HEAD)
4 |
5 | This is a Replication of Krusell and Smith, 1998.
6 |
7 | To reproduces all the results of the paper, you can
8 |
9 | ##### Use [nbreproduce](https://github.com/econ-ark/nbreproduce) (requires Docker to be installed on the machine).
10 |
11 | ```
12 | # Clone this repository
13 | $ git clone https://github.com/econ-ark/KrusellSmith
14 |
15 | # Change working directory to KrusellSmith
16 | $ cd KrusellSmith
17 |
18 | # Install nbreproduce
19 | $ pip install nbreproduce
20 |
21 | # Reproduce all results using nbreproduce
22 | $ nbreproduce
23 | ```
24 |
25 | ##### Install a local conda environment and execute the Jupyter notebook.
26 |
27 | ```
28 | $ conda env create -f environment.yml
29 | $ conda activate krusellsmith
30 | # execute the script to create figures
31 | $ cd Code/Python
32 | $ ipython KrusellSmith.py
33 | ```
34 |
35 | ## References
36 |
37 | Krusell, P., & Smith, Jr, A. A. (1998). Income and wealth heterogeneity in the macroeconomy. Journal of political Economy, 106(5), 867-896.
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Byte-compiled / optimized / DLL files
3 | __pycache__/
4 | *.py[cod]
5 | *$py.class
6 |
7 | # C extensions
8 | *.so
9 |
10 | # Distribution / packaging
11 | .Python
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 | cover/
54 |
55 | # Translations
56 | *.mo
57 | *.pot
58 |
59 | # Django stuff:
60 | *.log
61 | local_settings.py
62 | db.sqlite3
63 | db.sqlite3-journal
64 |
65 | # Flask stuff:
66 | instance/
67 | .webassets-cache
68 |
69 | # Scrapy stuff:
70 | .scrapy
71 |
72 | # Sphinx documentation
73 | docs/_build/
74 |
75 | # PyBuilder
76 | .pybuilder/
77 | target/
78 |
79 | # Jupyter Notebook
80 | .ipynb_checkpoints
81 |
82 | # IPython
83 | profile_default/
84 | ipython_config.py
85 |
86 | # pyenv
87 | # For a library or package, you might want to ignore these files since the code is
88 | # intended to run in multiple environments; otherwise, check them in:
89 | # .python-version
90 |
91 | # pipenv
92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
95 | # install all needed dependencies.
96 | #Pipfile.lock
97 |
98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
99 | __pypackages__/
100 |
101 | # Celery stuff
102 | celerybeat-schedule
103 | celerybeat.pid
104 |
105 | # SageMath parsed files
106 | *.sage.py
107 |
108 | # Environments
109 | .env
110 | .venv
111 | env/
112 | venv/
113 | ENV/
114 | env.bak/
115 | venv.bak/
116 |
117 | # Spyder project settings
118 | .spyderproject
119 | .spyproject
120 |
121 | # Rope project settings
122 | .ropeproject
123 |
124 | # mkdocs documentation
125 | /site
126 |
127 | # mypy
128 | .mypy_cache/
129 | .dmypy.json
130 | dmypy.json
131 |
132 | # Pyre type checker
133 | .pyre/
134 |
135 | # pytype static type analyzer
136 | .pytype/
137 |
138 | # Cython debug symbols
139 | cython_debug/
140 |
141 | condaenv/
142 |
--------------------------------------------------------------------------------
/Figures/aggregate_savings.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
476 |
--------------------------------------------------------------------------------
/Figures/savings_function.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
690 |
--------------------------------------------------------------------------------
/Figures/consumption_function.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
837 |
--------------------------------------------------------------------------------
/Figures/target_wealth.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
893 |
--------------------------------------------------------------------------------
/Code/Python/KrusellSmith.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # ---
3 | # jupyter:
4 | # jupytext:
5 | # formats: ipynb,py:percent
6 | # notebook_metadata_filter: all
7 | # text_representation:
8 | # extension: .py
9 | # format_name: percent
10 | # format_version: '1.3'
11 | # jupytext_version: 1.6.0
12 | # kernelspec:
13 | # display_name: Python 3
14 | # language: python
15 | # name: python3
16 | # language_info:
17 | # codemirror_mode:
18 | # name: ipython
19 | # version: 3
20 | # file_extension: .py
21 | # mimetype: text/x-python
22 | # name: python
23 | # nbconvert_exporter: python
24 | # pygments_lexer: ipython3
25 | # version: 3.7.3
26 | # ---
27 |
28 | # %% [markdown]
29 | # # [Krusell Smith (1998)](https://www.journals.uchicago.edu/doi/pdf/10.1086/250034)
30 | #
31 | # - Original version by Tim Munday
32 | # - Comments and extensions by Tao Wang
33 | # - Further edits by Chris Carroll
34 |
35 | # %% [markdown]
36 | # [](https://mybinder.org/v2/gh/econ-ark/DemARK/master?filepath=notebooks%2FKrusellSmith.ipynb)
37 | #
38 |
39 | # %% [markdown]
40 | # ### Overview
41 | #
42 | # The benchmark Krusell-Smith model has the following broad features:
43 | # * The aggregate state switches between "good" and "bad" with known probabilities
44 | # * All consumers experience the same aggregate state for the economy (good or bad)
45 | # * _ex ante_ there is only one type of consumer, which is infinitely lived
46 | # * _ex post_ heterogeneity arises from uninsurable idiosyncratic income shocks
47 | # * Specifically, individuals are at risk of spells of unemployment
48 | # * In a spell of unemployment, their income is zero
49 | #
50 | # Thus, each agent faces two types of uncertainty: About their employment state, and about the income they will earn when employed. And the values of income and unemployment risk depend on the aggregate state.
51 | #
52 |
53 | # %% [markdown]
54 | # ### Details
55 | #
56 | # #### Idiosyncratic
57 | # Each agent _attempts_ to supply an amount of productive labor $\ell$ in each period. (Here and below we mostly follow the notation of Krusell and Smith (1998)).
58 | #
59 | # However, whether they _succeed_ in supplying that labor (and earning a corresponding wage) is governed by the realization of the stochastic variable $\epsilon$. If the agent is unlucky, $\epsilon$ is zero and the agent is unemployed. The amount of labor they succeed in supplying is thus $\epsilon\ell$.
60 | #
61 | # #### Aggregate
62 | # Aggregate output ($\bar{y}$) is produced using a Cobb-Douglas production function using capital and labor. (Bars over variables indicate the aggregate value of a variable that has different values across different idiosyncratic consumers).
63 | #
64 | # $z$ denotes the aggregate shock to productivity. $z$ can take two values, either $z_g$ -- the "good" state, or $z_b < z_g$ -- the "bad" state. Consumers gain income from providing labor, and from the rental return on any capital they own. Labor and capital markets are perfectly efficient so both factors are both paid their marginal products.
65 | #
66 | # The agent can choose to save by buying capital $k$ which is bounded below at the borrowing constraint of 0.
67 | #
68 | #
69 | # Putting all of this together, aggregate output is given by:
70 | # \begin{eqnarray}
71 | # \bar{y} & = & z\bar{k}^\alpha \bar{\ell}^{1-\alpha}
72 | # \end{eqnarray}
73 | #
74 |
75 | # %% [markdown]
76 | # The aggregate shocks $z$ follow first-order Markov chains with the transition probability of moving from state $s$ to state $s'$ denoted by $\pi_{ss'}$. The aggregate shocks and individual shocks are correlated: The probability of being unemployed is higher in bad times, when aggregate productivity is low, than in good times, when aggregate productivity is high.
77 | #
78 | # #### Idiosyncratic and Aggregate Together
79 | #
80 | # The individual shocks satisfy the law of large numbers, and the model is constructed so that the number of agents who are unemployed in the good state always equals $u_g$, and is always $u_b$ in the bad state. Given the aggregate state, individual shocks are independent from each other.
81 | #
82 | # For the individual, the probability of moving between a good state and employment to a bad state and unemployment is denoted $\pi_{gb10}$ with similar notation for the other transition probabilities.
83 | #
84 | # (Krusell and Smith allow for serially correlated unemployment at the idiosyncratic level. Here we will simplify this and have unemployment be serially uncorrelated.)
85 |
86 | # %% [markdown]
87 | # Finally, $\Gamma$ denotes the current distribution of consumers over capital and employment status, and $H$ denotes the law of motion of this distribution.
88 |
89 | # %% [markdown]
90 | # #### The Idiosyncratic Individual's Problem Given the Aggregate State
91 | #
92 | # The individual's problem is:
93 | # \begin{eqnarray*}
94 | # V(k, \epsilon; \Gamma, z) &=& \max_{k'}\{U(c) + \beta \mathbb{E}[V(k' ,\epsilon'; \Gamma', z')|z, \epsilon]\} \\
95 | # c + k' &=& r(\bar{k}, \bar{\ell}, z)k + w(\bar{k}, \bar{\ell}, z)\ell\epsilon + (1-\delta)k \\
96 | # \Gamma' &=& H(\Gamma, z, z') \\
97 | # k' &\geq& 0 \\
98 | # \end{eqnarray*}
99 |
100 | # %% [markdown]
101 | # Krusell and Smith define an equilibrium as a law of motion $H$, a value function $V$, a rule for updating capital $f$ and pricing functions $r$ and $w$, such that $V$ and $f$ solve the consumers problem, $r$ and $w$ denote the marginal products of capital and labour, and $H$ is consistent with $f$ (i.e. if we add up all of the individual agents capital choices we get the correct distribution of capital).
102 |
103 | # %% [markdown]
104 | # ##### Discussion of the KS Algorithm
105 | #
106 | # In principle, $\Gamma$ is a high-dimensional object because it includes the whole distribution of individuals' wealth and employment states. Because the optimal amount to save is a nonlinear function of the level of idiosyncratic $k$, next period's aggregate capital stock $\bar{k}'$ depends on the distribution of the holdings of idiosyncratic $k$ across the population of consumers. Therefore the law of motion $H$ is not a trivial function of the $\Gamma$.
107 | #
108 | # KS simplified this problem by noting the following.
109 | #
110 | # 1. The agent cares about the future aggregate aggregate state only insofar as that state affects their own personal value of $c$
111 | # 1. Future values of $c$ depend on the aggregate state only through the budget constraint
112 | # 1. The channels by which the budget constraint depends on the aggregate state are:
113 | # * The probability distributions of $\epsilon$ and $z$ are affected by the aggregate state
114 | # * Interest rates and wages depend on the future values of $\bar{k}$ and $\bar{\ell}$
115 | # 1. The probability distributions for the future values of $\{\epsilon, z\}$ are known
116 | # * They are fully determined by the Markov transition matrices
117 | # 1. But the values of $r$ and $w$ are both determined by the future value of $\bar{k}$ (in combination with the exogenous value of $\bar{\ell}$)
118 | # * So the only _endogenous_ object that the agent needs to form expectations about, in order to have a complete rational expectation about everything affecting them, is $\bar{k}'$
119 | #
120 | # The key result in Krusell and Smith is the discovery that a very simple linear rule does an extraordinarily good job (though not quite perfect) in forecasting $\bar{k'}$
121 | #
122 | # They then argue that, since rationality is surely bounded to some degree, the solution that an agent obtains using a good forecasting rule for $\bar{k}'$ is "good enough" to compute an "approximate" solution to the consumer's optimization problem.
123 | #
124 | # They define a generic algorithm to find a forecasting rule for $\bar{k}$ as follows
125 | #
126 | # 1. Choose the number of moments $n$ of the distribution of $k$ to be included in the set of variables to forecast $\bar{k}'$. In the simplest case, $n=1$, the only forecasting variable for next period's $\bar{k}'$ is the mean (the first moment, $n=1$)) of current capital, $\bar{k}$.
127 | # 2. Each individual adopts the same belief about the law motion of these moments, $H_I$ and finds the optimal decision policy, $f_I$, contingent on that guess.
128 | # 3. Use the optimal policy to simulate a history of aggregate capital with a large number of agents.
129 | # 4. Characterize the realized law of motion using the same number of moments $n$
130 | # 5. Compare it with the $H_I$, what is taken as given by individuals.
131 | # 6. Iterate until the two converge.
132 | #
133 | # In the end, the solution to the original problem is well approximated by the following simplified problem:
134 | #
135 | # \begin{eqnarray*}
136 | # V(k, \epsilon; \bar k, z) &=& max_{c, k'}\{U(c) + \beta E[V(k' ,\epsilon'; \bar k', z')|z, \epsilon]\} \\
137 | # c + k' &=& r(\bar{k}, \bar{\ell}, z)k + w(\bar{k}, \bar{\ell}, z)l\epsilon + (1-\delta)k \\
138 | # \text{When }~ z=z_g, \quad \mathbb{E}[\log\bar{k}'] & = & a_0 + a_1 \log\bar k \\
139 | # \text{When }~ z=z_b, \quad \mathbb{E}[\log\bar{k}'] & = & b_0 + b_1 \log\bar k \\
140 | # k' &\geq& 0 \\
141 | # \end{eqnarray*}
142 |
143 | # %% [markdown]
144 | # ## Implementation Using the HARK Toolkit
145 |
146 | # %% [markdown]
147 | # #### The Consumer
148 |
149 | # %% code_folding=[0, 6]
150 | # Import generic setup tools
151 |
152 | # This is a jupytext paired notebook that autogenerates KrusellSmith.py
153 | # which can be executed from a terminal command line via "ipython KrusellSmith.py"
154 | # But a terminal does not permit inline figures, so we need to test jupyter vs terminal
155 | # Google "how can I check if code is executed in the ipython notebook"
156 | def in_ipynb():
157 | try:
158 | if str(type(get_ipython())) == "":
159 | return True
160 | else:
161 | return False
162 | except NameError:
163 | return False
164 |
165 | # Determine whether to make the figures inline (for spyder or jupyter)
166 | # vs whatever is the automatic setting that will apply if run from the terminal
167 | if in_ipynb():
168 | # %matplotlib inline generates a syntax error when run from the shell
169 | # so do this instead
170 | get_ipython().run_line_magic('matplotlib', 'inline')
171 | else:
172 | get_ipython().run_line_magic('matplotlib', 'auto')
173 |
174 | # Import the plot-figure library matplotlib
175 |
176 | import matplotlib.pyplot as plt
177 | import numpy as np
178 |
179 | from copy import deepcopy
180 | from HARK.utilities import plotFuncs, plotFuncsDer, make_figs
181 | from HARK.distribution import DiscreteDistribution
182 |
183 | # %% code_folding=[0]
184 | # Markov consumer type that allows aggregate shocks
185 | from HARK.ConsumptionSaving.ConsAggShockModel import AggShockMarkovConsumerType
186 |
187 | # %% code_folding=[0]
188 | # Define a dictionary to make an 'instance' of our Krusell-Smith consumer.
189 |
190 | # The folded dictionary below contains many parameters to the
191 | # AggShockMarkovConsumerType agent that are not needed for the KS model
192 | KSAgentDictionary = {
193 | "LivPrb" : [1.0], # Survival probability
194 | "AgentCount" : 10000, # Number of agents of this type (only matters for simulation)
195 | "aNrmInitMean" : 0.0, # Mean of log initial assets (only matters for simulation)
196 | "aNrmInitStd" : 0.0, # Standard deviation of log initial assets (only for simulation)
197 | "pLvlInitMean" : 0.0, # Mean of log initial permanent income (only matters for simulation)
198 | "pLvlInitStd" : 0.0, # Standard deviation of log initial permanent income (only matters for simulation)
199 | "PermGroFacAgg" : 1.0, # Aggregate permanent income growth factor (only matters for simulation)
200 | "T_age" : None, # Age after which simulated agents are automatically killed
201 | "T_cycle" : 1, # Number of periods in the cycle for this agent type
202 | # Parameters for constructing the "assets above minimum" grid
203 | "aXtraMin" : 0.001, # Minimum end-of-period "assets above minimum" value
204 | "aXtraMax" : 20, # Maximum end-of-period "assets above minimum" value
205 | "aXtraExtra" : [None], # Some other value of "assets above minimum" to add to the grid
206 | "aXtraNestFac" : 3, # Exponential nesting factor when constructing "assets above minimum" grid
207 | "aXtraCount" : 24, # Number of points in the grid of "assets above minimum"
208 | # Parameters describing the income process
209 | "PermShkCount" : 1, # Number of points in discrete approximation to permanent income shocks - no shocks of this kind!
210 | "TranShkCount" : 1, # Number of points in discrete approximation to transitory income shocks - no shocks of this kind!
211 | "PermShkStd" : [0.], # Standard deviation of log permanent income shocks - no shocks of this kind!
212 | "TranShkStd" : [0.], # Standard deviation of log transitory income shocks - no shocks of this kind!
213 | "UnempPrb" : 0.0, # Probability of unemployment while working - no shocks of this kind!
214 | "UnempPrbRet" : 0.00, # Probability of "unemployment" while retired - no shocks of this kind!
215 | "IncUnemp" : 0.0, # Unemployment benefits replacement rate
216 | "IncUnempRet" : 0.0, # "Unemployment" benefits when retired
217 | "tax_rate" : 0.0, # Flat income tax rate
218 | "T_retire" : 0, # Period of retirement (0 --> no retirement)
219 | "BoroCnstArt" : 0.0, # Artificial borrowing constraint; imposed minimum level of end-of period assets
220 | "PermGroFac" : [1.0], # Permanent income growth factor
221 | # New Parameters that we need now
222 | 'MgridBase': np.array([0.1,0.3,0.6,
223 | 0.8,0.9,0.98,
224 | 1.0,1.02,1.1,
225 | 1.2,1.6,2.0,
226 | 3.0]), # Grid of capital-to-labor-ratios (factors)
227 | 'PermShkAggStd' : [0.0,0.0], # Standard deviation of log aggregate permanent shocks by state. No continous shocks in a state.
228 | 'TranShkAggStd' : [0.0,0.0], # Standard deviation of log aggregate transitory shocks by state. No continuous shocks in a state.
229 | 'PermGroFacAgg' : 1.0
230 | }
231 |
232 | # Here we state just the "interesting" parts of the consumer's specification
233 |
234 | KSAgentDictionary['CRRA'] = 1.0 # Relative risk aversion
235 | KSAgentDictionary['DiscFac'] = 0.99 # Intertemporal discount factor
236 | KSAgentDictionary['cycles'] = 0 # cycles=0 means consumer is infinitely lived
237 |
238 | # KS assume that 'good' and 'bad' times are of equal expected duration
239 | # The probability of a change in the aggregate state is p_change=0.125
240 | p_change=0.125
241 | p_remain=1-p_change
242 |
243 | # Now we define macro transition probabilities for AggShockMarkovConsumerType
244 | # [i,j] is probability of being in state j next period conditional on being in state i this period.
245 | # In both states, there is 0.875 chance of staying, 0.125 chance of switching
246 | AggMrkvArray = \
247 | np.array([[p_remain,p_change], # Probabilities of states 0 and 1 next period if in state 0
248 | [p_change,p_remain]]) # Probabilities of states 0 and 1 next period if in state 1
249 | KSAgentDictionary['MrkvArray'] = AggMrkvArray
250 |
251 | # %%
252 | # Create the Krusell-Smith agent as an instance of AggShockMarkovConsumerType
253 | KSAgent = AggShockMarkovConsumerType(**KSAgentDictionary)
254 |
255 | # %% [markdown]
256 | # Now we need to specify the income distribution.
257 | #
258 | # The HARK toolkit allows for two components of labor income: Persistent (or permanent), and transitory.
259 | #
260 | # Using the KS notation above, a HARK consumer's income is
261 | # \begin{eqnarray}
262 | # y & = & w p \ell \epsilon
263 | # \end{eqnarray}
264 | # where $p$ is the persistent component of income. Krusell and Smith did not incorporate a persistent component of income, however, so we will simply calibrate $p=1$ for all states.
265 | #
266 | # For each of the two aggregate states we need to specify:
267 | # * The _proportion_ of consumers in the $e$ and the $u$ states
268 | # * The level of persistent/permanent productivity $p$ (always 1)
269 | # * The ratio of actual to permanent productivity in each state $\{e,u\}$
270 | # * In the KS notation, this is $\epsilon\ell$
271 | #
272 |
273 | # %% code_folding=[]
274 | # Construct the income distribution for the Krusell-Smith agent
275 | prb_eg = 0.96 # Probability of employment in the good state
276 | prb_ug = 1-prb_eg # Probability of unemployment in the good state
277 | prb_eb = 0.90 # Probability of employment in the bad state
278 | prb_ub = 1-prb_eb # Probability of unemployment in the bad state
279 | p_ind = 1 # Persistent component of income is always 1
280 | ell_ug = ell_ub = 0 # Labor supply is zero for unemployed consumers in either agg state
281 | ell_eg = 1.0/prb_eg # Labor supply for employed consumer in good state
282 | ell_eb = 1.0/prb_eb # 1=pe_g*ell_ge+pu_b*ell_gu=pe_b*ell_be+pu_b*ell_gu
283 |
284 | # IncomeDstn is a list of lists, one for each aggregate Markov state
285 | # Each contains three arrays of floats, representing a discrete approximation to the income process.
286 | # Order:
287 | # state probabilities
288 | # idiosyncratic persistent income level by state (KS have no persistent shocks p_ind is always 1.0)
289 | # idiosyncratic transitory income level by state
290 |
291 | KSAgent.IncomeDstn[0] = [
292 | DiscreteDistribution(np.array([prb_eg,prb_ug]),
293 | [np.array([p_ind,p_ind]),
294 | np.array([ell_eg,ell_ug])]), # Agg state good
295 | DiscreteDistribution(np.array([prb_eb,prb_ub]),
296 | [np.array([p_ind,p_ind]),
297 | np.array([ell_eb,ell_ub])]) # Agg state bad
298 | ]
299 |
300 | # %% [markdown]
301 | # Up to this point, individual agents do not have enough information to solve their decision problem yet. What is missing are beliefs about the endogenous macro variables $r$ and $w$, both of which are functions of $\bar{k}$.
302 |
303 | # %% [markdown]
304 | # #### The Aggregate Economy
305 |
306 | # %% code_folding=[]
307 | from HARK.ConsumptionSaving.ConsAggShockModel import CobbDouglasMarkovEconomy
308 |
309 | KSEconomyDictionary = {
310 | 'PermShkAggCount': 1,
311 | 'TranShkAggCount': 1,
312 | 'PermShkAggStd': [0.0,0.0],
313 | 'TranShkAggStd': [0.0,0.0],
314 | 'DeprFac': 0.025, # Depreciation factor
315 | 'DiscFac': 0.99,
316 | 'CRRA': 1.0,
317 | 'PermGroFacAgg': [1.0,1.0],
318 | 'AggregateL':1.0, # Fix aggregate labor supply at 1.0 - makes interpretation of z easier
319 | 'act_T':1200, # Number of periods for economy to run in simulation
320 | 'intercept_prev': [0.0,0.0], # Make some initial guesses at linear savings rule intercepts for each state
321 | 'slope_prev': [1.0,1.0], # Make some initial guesses at linear savings rule slopes for each state
322 | 'MrkvNow_init': 0 # Pick a state to start in (we pick the first state)
323 | }
324 |
325 | # The 'interesting' parts of the CobbDouglasMarkovEconomy
326 | KSEconomyDictionary['CapShare'] = 0.36
327 | KSEconomyDictionary['MrkvArray'] = AggMrkvArray
328 |
329 | KSEconomy = CobbDouglasMarkovEconomy(agents = [KSAgent], **KSEconomyDictionary) # Combine production and consumption sides into an "Economy"
330 |
331 | # %% [markdown]
332 | # We have now populated the $\texttt{KSEconomy}$ with $\texttt{KSAgents}$ defined before. That is basically telling the agents to take the macro state from the $\texttt{KSEconomy}$.
333 | #
334 | # Now we construct the $\texttt{AggShkDstn}$ that specifies the evolution of the dynamics of the $\texttt{KSEconomy}$.
335 | #
336 | # The structure of the inputs for $\texttt{AggShkDstn}$ follows the same logic as for $\texttt{IncomeDstn}$. Now there is only one possible outcome for each aggregate state (the KS aggregate states are very simple), therefore, each aggregate state has only one possible condition which happens with probability 1.
337 |
338 | # %% code_folding=[]
339 | # Calibrate the magnitude of the aggregate shocks
340 |
341 | Tran_g = 1.01 # Productivity z in the good aggregate state
342 | Tran_b = 0.99 # and the bad state
343 |
344 | # The HARK framework allows permanent shocks
345 | Perm_g = Perm_b = 1.0 # KS assume there are no aggregate permanent shocks
346 |
347 | # Aggregate productivity shock distribution by state.
348 | # First element is probabilities of different outcomes, given the state you are in.
349 | # Second element is agg permanent shocks (here we don't have any, so just they are just 1.).
350 | # Third element is agg transitory shocks, which are calibrated the same as in Krusell Smith.
351 |
352 | KSAggShkDstn = [
353 | DiscreteDistribution(np.array([1.0]), [np.array([Perm_g]), np.array([Tran_g])]), # Aggregate good
354 | DiscreteDistribution(np.array([1.0]), [np.array([Perm_b]), np.array([Tran_b])]) # Aggregate bad
355 | ]
356 |
357 | KSEconomy.AggShkDstn = KSAggShkDstn
358 |
359 | # %% [markdown]
360 | # #### Summing Up
361 | #
362 | # The combined idiosyncratic and aggregate assumptions can be summarized mathematically as follows.
363 | #
364 | # $\forall \{s,s'\}=\{g,b\}\times\{g,b\}$, the following two conditions hold:
365 | #
366 | # $$\underbrace{\pi_{ss'01}}_{p(s \rightarrow s',u \rightarrow e)}+\underbrace{\pi_{ss'00}}_{p(s \rightarrow s', u \rightarrow u)} = \underbrace{\pi_{ss'11}}_{p(s\rightarrow s', e \rightarrow e) } + \underbrace{\pi_{ss'10}}_{p(s \rightarrow s', e \rightarrow u)} = \underbrace{\pi_{ss'}}_{p(s\rightarrow s')}$$
367 | #
368 | # $$u_s \frac{\pi_{ss'00}}{\pi_{ss'}}+ (1-u_s) \frac{\pi_{ss'10}}{\pi_{ss'}} = u_{s'}$$
369 |
370 | # %% [markdown]
371 | # ### Solving the Model
372 | # Now, we have fully defined all of the elements of the macroeconomy, and we are in postion to construct an object that represents the economy and to construct a rational expectations equilibrium.
373 |
374 | # %% code_folding=[]
375 | # Construct the economy, make an initial history, then solve
376 |
377 | KSAgent.getEconomyData(KSEconomy) # Makes attributes of the economy, attributes of the agent
378 |
379 | KSEconomy.makeAggShkHist() # Make a simulated history of the economy
380 |
381 | # Set tolerance level.
382 |
383 | KSEconomy.tolerance = 0.01
384 |
385 | # Solve macro problem by finding a fixed point for beliefs
386 |
387 | KSEconomy.solve() # Solve the economy using the market method.
388 | # i.e. guess the saving function, and iterate until a fixed point
389 |
390 | # %% [markdown]
391 | # The last line above is the converged aggregate saving rule for good and bad times, respectively.
392 |
393 | # %% code_folding=[]
394 | # Plot some key results
395 |
396 | print('Aggregate savings as a function of aggregate market resources:')
397 | bottom = 0.1
398 | top = 2 * KSEconomy.kSS
399 | x = np.linspace(bottom, top, 1000, endpoint=True)
400 | y0 = KSEconomy.AFunc[0](x)
401 | y1 = KSEconomy.AFunc[1](x)
402 | plt.plot(x, y0)
403 | plt.plot(x, y1)
404 | plt.xlim([bottom, top])
405 | make_figs('aggregate_savings', True, False, '../../Figures')
406 | plt.show()
407 | plt.clf()
408 |
409 | print('Consumption function at each aggregate market resources gridpoint (in general equilibrium):')
410 | KSAgent.unpackcFunc()
411 | m_grid = np.linspace(0,10,200)
412 | KSAgent.unpackcFunc()
413 | for M in KSAgent.Mgrid:
414 | c_at_this_M = KSAgent.solution[0].cFunc[0](m_grid,M*np.ones_like(m_grid)) #Have two consumption functions, check this
415 | plt.plot(m_grid,c_at_this_M)
416 | make_figs('consumption_function', True, False, '../../Figures')
417 | plt.show()
418 | plt.clf()
419 |
420 | print('Savings at each individual market resources gridpoint (in general equilibrium):')
421 | KSAgent.unpackcFunc()
422 | m_grid = np.linspace(0,10,200)
423 | KSAgent.unpackcFunc()
424 | for M in KSAgent.Mgrid:
425 | s_at_this_M = m_grid-KSAgent.solution[0].cFunc[1](m_grid,M*np.ones_like(m_grid))
426 | c_at_this_M = KSAgent.solution[0].cFunc[1](m_grid,M*np.ones_like(m_grid)) #Have two consumption functions, check this
427 | plt.plot(m_grid,s_at_this_M)
428 | make_figs('savings_function', True, False, '../../Figures')
429 | plt.show()
430 |
431 | # %% [markdown]
432 | # ### The Wealth Distribution in KS
433 | #
434 | # #### Benchmark Model
435 | #
436 |
437 | # %%
438 | sim_wealth = KSEconomy.reap_state['aLvlNow'][0]
439 |
440 |
441 | print("The mean of individual wealth is "+ str(sim_wealth.mean()) + ";\n the standard deviation is "
442 | + str(sim_wealth.std())+";\n the median is " + str(np.median(sim_wealth)) +".")
443 |
444 | # %% code_folding=[]
445 | # Get some tools for plotting simulated vs actual wealth distributions
446 | from HARK.utilities import getLorenzShares, getPercentiles
447 |
448 | # The cstwMPC model conveniently has data on the wealth distribution
449 | # from the U.S. Survey of Consumer Finances
450 | from HARK.datasets import load_SCF_wealth_weights
451 | SCF_wealth, SCF_weights = load_SCF_wealth_weights()
452 |
453 | # %% code_folding=[]
454 | # Construct the Lorenz curves and plot them
455 |
456 | pctiles = np.linspace(0.001,0.999,15)
457 | SCF_Lorenz_points = getLorenzShares(SCF_wealth,weights=SCF_weights,percentiles=pctiles)
458 | sim_Lorenz_points = getLorenzShares(sim_wealth,percentiles=pctiles)
459 |
460 | # Plot
461 | plt.figure(figsize=(5,5))
462 | plt.title('Wealth Distribution')
463 | plt.plot(pctiles,SCF_Lorenz_points,'--k',label='SCF')
464 | plt.plot(pctiles,sim_Lorenz_points,'-b',label='Benchmark KS')
465 | plt.plot(pctiles,pctiles,'g-.',label='45 Degree')
466 | plt.xlabel('Percentile of net worth')
467 | plt.ylabel('Cumulative share of wealth')
468 | plt.legend(loc=2)
469 | plt.ylim([0,1])
470 | make_figs('wealth_distribution_1', True, False, '../../Figures')
471 | plt.show()
472 |
473 | # %%
474 | # Calculate a measure of the difference between the simulated and empirical distributions
475 | lorenz_distance = np.sqrt(np.sum((SCF_Lorenz_points - sim_Lorenz_points)**2))
476 | print("The Euclidean distance between simulated wealth distribution and the estimates from the SCF data is "+str(lorenz_distance) )
477 |
478 | # %% [markdown]
479 | # #### Heterogeneous Time Preference Rates
480 | #
481 | # As the figures show, the distribution of wealth that the baseline KS model produces is very far from matching the empirical degree of inequality in the US data.
482 | #
483 | # This could matter for macroeconomic purposes. For example, the SCF data indicate that many agents are concentrated at low values of wealth where the MPC is very large. We might expect, therefore, that a fiscal policy "stimulus" that gives a fixed amount of money to every agent would have a large effect on the consumption of the low-wealth households who have a high Marginal Propensity to Consume.
484 | #
485 | # KS attempt to address this problem by assuming that an individual agent's time preference rate can change over time.
486 | #
487 | # The rationale is that this represents a generational transition: The "agent" is really a "dynasty" and the time preference rate of the "child" dynast may differ from that of the "parent."
488 | #
489 | # Specifically, KS assume that $\beta$ can take on three values, 0.9858, 0.9894, and 0.9930, and that the transition probabilities are such that
490 | # - The invariant distribution for $\beta$’s has 80 percent of the population at the middle $\beta$ and 10 percent at each of the other $\beta$’s.
491 | # - Immediate transitions between the extreme values of $\beta$ occur with probability zero.
492 | # - The average duration of the highest and lowest $\beta$’s is 50 years.
493 | #
494 | # The HARK toolkit is not natively set up to accommodate stochastic time preference factors (though an extension to accommodate this would be easy).
495 | #
496 | # Here, instead, we assume that different agents have different values of $\beta$ that are uniformly distributed over some range. We approximate the uniform distribution by three points. The agents are heterogeneous _ex ante_ (and permanently).
497 |
498 | # %% code_folding=[]
499 | # Construct the distribution of types
500 | from HARK.distribution import Uniform
501 |
502 |
503 | # Specify the distribution of the discount factor
504 | num_types = 3 # number of types we want;
505 | DiscFac_mean = 0.9858 # center of beta distribution
506 | DiscFac_spread = 0.0085 # spread of beta distribution
507 | DiscFac_dstn = Uniform(bot=DiscFac_mean-DiscFac_spread, top=DiscFac_mean+DiscFac_spread).approx(num_types).X
508 |
509 | BaselineType = deepcopy(KSAgent)
510 |
511 | MyTypes = [] # initialize an empty list to hold our consumer types
512 | for nn in range(len(DiscFac_dstn)):
513 | # Now create the types, and append them to the list MyTypes
514 | NewType = deepcopy(BaselineType)
515 | NewType.DiscFac = DiscFac_dstn[nn]
516 | NewType.seed = nn # give each consumer type a different RNG seed
517 | MyTypes.append(NewType)
518 |
519 | # %% code_folding=[]
520 | # Put all agents into the economy
521 | KSEconomy_sim = CobbDouglasMarkovEconomy(agents = MyTypes, **KSEconomyDictionary)
522 | KSEconomy_sim.AggShkDstn = KSAggShkDstn # Agg shocks are the same as defined earlier
523 |
524 | for ThisType in MyTypes:
525 | ThisType.getEconomyData(KSEconomy_sim) # Makes attributes of the economy, attributes of the agent
526 |
527 | KSEconomy_sim.makeAggShkHist() # Make a simulated prehistory of the economy
528 | KSEconomy_sim.solve() # Solve macro problem by getting a fixed point dynamic rule
529 |
530 | # %% code_folding=[]
531 | # Get the level of end-of-period assets a for all types of consumers
532 | aLvl_all = np.concatenate([KSEconomy_sim.reap_state['aLvlNow'][i] for i in range(len(MyTypes))])
533 |
534 | print('Aggregate capital to income ratio is ' + str(np.mean(aLvl_all)))
535 |
536 | # %% code_folding=[]
537 | # Plot the distribution of wealth across all agent types
538 | sim_3beta_wealth = aLvl_all
539 | pctiles = np.linspace(0.001,0.999,15)
540 | sim_Lorenz_points = getLorenzShares(sim_wealth,percentiles=pctiles)
541 | SCF_Lorenz_points = getLorenzShares(SCF_wealth,weights=SCF_weights,percentiles=pctiles)
542 | sim_3beta_Lorenz_points = getLorenzShares(sim_3beta_wealth,percentiles=pctiles)
543 |
544 | ## Plot
545 | plt.figure(figsize=(5,5))
546 | plt.title('Wealth Distribution')
547 | plt.plot(pctiles,SCF_Lorenz_points,'--k',label='SCF')
548 | plt.plot(pctiles,sim_Lorenz_points,'-b',label='Benchmark KS')
549 | plt.plot(pctiles,sim_3beta_Lorenz_points,'-*r',label='3 Types')
550 | plt.plot(pctiles,pctiles,'g-.',label='45 Degree')
551 | plt.xlabel('Percentile of net worth')
552 | plt.ylabel('Cumulative share of wealth')
553 | plt.legend(loc=2)
554 | plt.ylim([0,1])
555 | make_figs('wealth_distribution_2', True, False, '../../Figures')
556 | plt.show()
557 |
558 | # %% code_folding=[]
559 | # The mean levels of wealth for the three types of consumer are
560 | [np.mean(KSEconomy_sim.reap_state['aLvlNow'][0]),np.mean(KSEconomy_sim.reap_state['aLvlNow'][1]),np.mean(KSEconomy_sim.reap_state['aLvlNow'][2])]
561 |
562 | # %% code_folding=[]
563 | # Plot the distribution of wealth
564 | for i in range(len(MyTypes)):
565 | if i<=2:
566 | plt.hist(np.log(KSEconomy_sim.reap_state['aLvlNow'][i])\
567 | ,label=r'$\beta$='+str(round(DiscFac_dstn[i],4))\
568 | ,bins=np.arange(-2.,np.log(max(aLvl_all)),0.05))
569 | plt.yticks([])
570 | plt.legend(loc=2)
571 | plt.title('Log Wealth Distribution of 3 Types')
572 | make_figs('log_wealth_3_types', True, False, '../../Figures')
573 | plt.show()
574 |
575 | # %% code_folding=[]
576 | # Distribution of wealth in original model with one type
577 | plt.hist(np.log(sim_wealth),bins=np.arange(-2.,np.log(max(aLvl_all)),0.05))
578 | plt.yticks([])
579 | plt.title('Log Wealth Distribution of Original Model with One Type')
580 | make_figs('log_wealth_1', True, False, '../../Figures')
581 | plt.show()
582 |
583 | # %% [markdown]
584 | # ### Target Wealth is Nonlinear in Time Preference Rate
585 | #
586 | # Note the nonlinear relationship between wealth and time preference in the economy with three types. Although the three groups are uniformly spaced in $\beta$ values, there is a lot of overlap in the distribution of wealth of the two impatient types, who are both separated from the most patient type by a large gap.
587 | #
588 | # A model of buffer stock saving that has simplified enough to be [tractable](http://econ.jhu.edu/people/ccarroll/public/lecturenotes/Consumption/TractableBufferStock) yields some insight. If $\sigma$ is a measure of income risk, $r$ is the interest rate, and $\theta$ is the time preference rate, then for an 'impatient' consumer (for whom $\theta > r$), in the logarithmic utility case an approximate formula for the target level of wealth is:
589 | #
590 | #
591 | #
592 | # \begin{eqnarray}
593 | # a & \approx & \left(\frac{1}{ \theta(1+(\theta-r)/\sigma)-r}\right)
594 | # \end{eqnarray}
595 | #
596 | # Conceptually, this reflects the fact that the only reason any of these agents holds positive wealth is the precautionary motive. (If there is no uncertainty, $\sigma=0$ and thus $a=0$).
597 | #
598 | # For positive uncertainty $\sigma>0$, as the degree of impatience (given by $\theta-r$) approaches zero, the target level of wealth approaches infinity.
599 | #
600 | # A plot of $a$ as a function of $\theta$ for a particular parameterization is shown below.
601 |
602 | # %% code_folding=[]
603 | # Plot target wealth as a function of time preference rate for calibrated tractable model
604 | fig = plt.figure()
605 | ax = plt.axes()
606 | sigma = 0.01
607 | r = 0.02
608 | theta = np.linspace(0.023,0.10,100)
609 | plt.plot(theta,1/(theta*(1+(theta-r)/sigma)-r))
610 | plt.xlabel(r'$\theta$')
611 | plt.ylabel('Target wealth')
612 | make_figs('target_wealth', True, False, '../../Figures')
613 | plt.show()
614 |
615 | # %% [markdown]
616 | # ## New and Improved Krusell-Smith Model
617 | #
618 | # The figures above were generated from a model that is very similar to, but not exactly like, the model presented in Krusell & Smith (1998), using tools that were already in HARK and could be adapted for this purpose. This model lacks serially correlated employment states for individual agents, but is otherwise identical to the KS model.
619 | #
620 | # More recently, we have added a model to HARK that exactly replicates the Krusell-Smith model (without dynastic discount factor heterogeneity). In the cells below, we present a basic example of using this model. The default parameters are taken directly from Krusell & Smith (1998) and their results are replicated almost exactly.
621 |
622 | # %%
623 | # Import Krusell-Smith model
624 | from HARK.ConsumptionSaving.ConsAggShockModel import KrusellSmithType, KrusellSmithEconomy
625 | from time import time
626 | from scipy.stats import linregress
627 |
628 | # %%
629 | # Make default KS agent type and economy
630 | KSeconomy = KrusellSmithEconomy()
631 | KSeconomy.verbose = False
632 | KStype = KrusellSmithType()
633 | KStype.cycles = 0
634 | KStype.getEconomyData(KSeconomy)
635 | KSeconomy.agents = [KStype]
636 | KSeconomy.makeMrkvHist()
637 |
638 | # %%
639 | # Solve the Krusell-Smith economy
640 | t0 = time()
641 | print("Now solving for the equilibrium of the Krusell-Smith (1998) model. This might take a few minutes...")
642 | KSeconomy.solve()
643 | t1 = time()
644 | print('Solving the Krusell-Smith model took ' + str(t1-t0) + ' seconds.')
645 |
646 | # %%
647 | # Plot the consumption function for each discrete state
648 | state_names = ['bad economy, unemployed', 'bad economy, employed',
649 | 'good economy, unemployed', 'good economy, employed']
650 |
651 | for j in range(4):
652 | plt.xlabel(r'Idiosyncratic market resources $m$')
653 | plt.ylabel(r'Consumption $c$')
654 | plt.title('Consumption function by aggregate market resources: ' + state_names[j])
655 | plotFuncs(KStype.solution[0].cFunc[j].xInterpolators, 0., 50.)
656 |
657 | # %%
658 | # Extract history of aggregate capital and run a serial autoregression
659 | mystr = lambda x : '{:.4f}'.format(x)
660 | mystr2 = lambda x : '{:.7f}'.format(x)
661 | K_hist = np.array(KSeconomy.history['Aprev'])[KSeconomy.T_discard:]
662 | Mrkv_hist = KSeconomy.MrkvNow_hist[KSeconomy.T_discard:]
663 | bad = Mrkv_hist[:-1] == 0
664 | good = Mrkv_hist[:-1] == 1
665 | logK_t = np.log(K_hist[:-1])
666 | logK_tp1 = np.log(K_hist[1:])
667 | results_bad = linregress(logK_t[bad], logK_tp1[bad])
668 | results_good = linregress(logK_t[good], logK_tp1[good])
669 | print('')
670 | print('Equilibrium dynamics of aggregate capital:')
671 | print("Bad state: log k' = " + mystr(results_bad[1]) + ' + ' + mystr(results_bad[0]) + ' log k (r-sq = ' + mystr2(results_bad[2]**2) + ')')
672 | print("Good state: log k' = " + mystr(results_good[1]) + ' + ' + mystr(results_good[0]) + ' log k (r-sq = ' + mystr2(results_good[2]**2) + ')')
673 | print('')
674 | print("Krusell & Smith's published results (p877):")
675 | print("Bad state: log k' = 0.085 + 0.965 log k (r-sq = 0.999998)")
676 | print("Good state: log k' = 0.095 + 0.962 log k (r-sq = 0.999998)")
677 |
678 | # %%
679 |
--------------------------------------------------------------------------------
/Figures/wealth_distribution_1.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
1202 |
--------------------------------------------------------------------------------