# %% [markdown] {"hidden": true}
# After solving the model, we can examine an element of this type's $\texttt{solution}$:

# %% {"hidden": true}
print(vars(IndShockExample.solution[0]))

# %% [markdown] {"hidden": true}
# The single-period solution to an idiosyncratic shocks consumer's problem has all of the same attributes as in the perfect foresight model, with a couple additions.  The solution can include the marginal marginal value of market resources function $\texttt{vPPfunc}$, but this is only constructed if $\texttt{CubicBool}$ is `True`, so that the MPC can be accurately computed; when it is `False`, then $\texttt{vPPfunc}$ merely returns `NaN` everywhere.
#
#
# Let's take a look at the consumption function by plotting it, along with its derivative (the MPC):

# %% {"hidden": true}
print('Consumption function for an idiosyncratic shocks consumer type:')
plot_funcs(IndShockExample.solution[0].cFunc,
           IndShockExample.solution[0].mNrmMin, 5)
print(
    'Marginal propensity to consume for an idiosyncratic shocks consumer type:'
)
plot_funcs_der(IndShockExample.solution[0].cFunc,
               IndShockExample.solution[0].mNrmMin, 5)

# %% [markdown] {"hidden": true}
# The lower part of the consumption function is linear with a slope of 1, representing the *constrained* part of the consumption function where the consumer *would like* to consume more by borrowing-- his marginal utility of consumption exceeds the marginal value of assets-- but he is prevented from doing so by the artificial borrowing constraint.
#
# The MPC is a step function, as the $\texttt{cFunc}$ itself is a piecewise linear function; note the large jump in the MPC where the borrowing constraint begins to bind.
#
# If you want to look at the interpolation nodes for the consumption function, these can be found by "digging into" attributes of $\texttt{cFunc}$:

# %% {"hidden": true}
print('mNrmGrid for unconstrained cFunc is ',
Beispiel #2
0
# Which variables do we want to track
LifeCyclePop.track_vars = ['aNrm', 'pLvl', 'mNrm', 'cNrm', 'TranShk']

LifeCyclePop.T_sim = 120  # Nobody lives to be older than 145 years (=25+120)
LifeCyclePop.initialize_sim(
)  # Construct the age-25 distribution of income and assets
LifeCyclePop.simulate(
)  # Simulate a population behaving according to this model

# %% {"code_folding": [0]}
# Plot the consumption functions during working life

print('Consumption as a function of market resources while working:')
mMin = min(
    [LifeCyclePop.solution[t].mNrmMin for t in range(LifeCyclePop.T_cycle)])
plot_funcs(LifeCyclePop.cFunc[:LifeCyclePop.T_retire], mMin, 5)


# %% {"code_folding": [0]}
# Define the saving rate function
def savingRateFunc(SomeType, m):
    """
    Parameters:
    ----------
        SomeType: 
             Agent type that has been solved and simulated.
        
        
    Returns:
    --------
        SavingRate: float
    "aNrmInitMean": -6.0,  # Mean of log initial assets
    "aNrmInitStd": 1.0,  # Standard deviation of log initial assets
    "pLvlInitMean": 0.0,  # Mean of log initial permanent income
    "pLvlInitStd": 0.0,  # Standard deviation of log initial permanent income
    "PermGroFacAgg": 1.0,  # Aggregate permanent income growth factor
    "T_age": None,  # Age after which simulated agents are automatically killed
}

# %% slideshow={"slide_type": "slide"}
from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType

IndShockSimExample = IndShockConsumerType(**IdiosyncDict)
IndShockSimExample.cycles = 0  # Make this type have an infinite horizon
IndShockSimExample.solve()

plot_funcs(IndShockSimExample.solution[0].cFunc,
           IndShockSimExample.solution[0].mNrmMin, 5)

# simulation
IndShockSimExample.track_vars = ['aNrm', 'mNrm', 'cNrm', 'pLvl']
IndShockSimExample.initialize_sim()
IndShockSimExample.simulate()

# %% slideshow={"slide_type": "slide"}
# distribution of cash on hand
density = np.histogram(IndShockSimExample.history['mNrm'],
                       density=True)  #print(density)
n, bins, patches = plt.hist(IndShockSimExample.history['mNrm'], density=True)

# %% slideshow={"slide_type": "slide"}
df1 = pd.DataFrame(IndShockSimExample.history['mNrm'],
                   columns=['beta = 0.9941'
Beispiel #4
0
i = 0

for UnempPrb in UnempPrbList:
    TwoPerAgentNow = deepcopy(TwoPerAgent)
    TwoPerAgentNow.UnempPrb = UnempPrb
    TwoPerAgentNow.update_income_process()  # After changing parameters, recompute distn
    TwoPerAgentNow.solve()
    TwoPerAgentNow.unpack('cFunc')
    cFuncList.append(TwoPerAgentNow.cFunc[-2])  # Get the T-1 c function
    i += 1

# Zoom in on consumption function in a region near the BoroCnstArt kink point
RangeAroundPermInc = 0.5
PermIncNorm = 1
plot_funcs(cFuncList, PermIncNorm-RangeAroundPermInc, PermIncNorm+RangeAroundPermInc)

print('Drawing and storing solution')
if drawFigs:
    plt.show()
plt.close()

# %% [markdown] {"jupyter": {"source_hidden": true}, "tags": []}
# ## Factors and Conditions
#
# ### [The Finite Human Wealth Condition](http://econ-ark.github.io/BufferStockTheory/#Human-Wealth)
#
# Human wealth for a perfect foresight consumer is the present discounted value of future income:
#
# \begin{eqnarray}\notag
# \hLev_{t} & = & \Ex_{t}[\pLev_{t} + \Rfree^{-1} \pLev_{t+1} + \Rfree^{2} \pLev_{t+2} ... ] \\ \notag
# First, we define a standard lifecycle model, solve it and then

# %%
from HARK.ConsumptionSaving.ConsIndShockModel import IndShockConsumerType, init_lifecycle
import numpy as np
import matplotlib.pyplot as plt
LifecycleExample = IndShockConsumerType(**init_lifecycle)
LifecycleExample.cycles = 1  # Make this consumer live a sequence of periods exactly once
LifecycleExample.solve()

# %% [markdown]
# Let's have a look at the solution in time period second period. We should then be able to

# %%
from HARK.utilities import plot_funcs
plot_funcs([LifecycleExample.solution[0].cFunc],
           LifecycleExample.solution[0].mNrmMin, 10)

# %% [markdown]
# Let us then create a solver for the first period.

# %%
from HARK.ConsumptionSaving.ConsIndShockModel import ConsIndShockSolverBasic
solver = ConsIndShockSolverBasic(
    LifecycleExample.solution[1], LifecycleExample.IncShkDstn[0],
    LifecycleExample.LivPrb[0], LifecycleExample.DiscFac,
    LifecycleExample.CRRA, LifecycleExample.Rfree,
    LifecycleExample.PermGroFac[0], LifecycleExample.BoroCnstArt,
    LifecycleExample.aXtraGrid, LifecycleExample.vFuncBool,
    LifecycleExample.CubicBool)

# %%
Beispiel #6
0
# w = (1/1.025)
# N = (.9*(Inc*mho)+G)/ (w*t)
# r = (1.05)**.25 -1
# print(N)
#
# N1 = (.9*(.08*.05)+.01)/ (w*t)
#
#
# q = ((1-w)*N)/r
#
# print(N)
# print(N1-N)
# print(q)
#
# =============================================================================
'''
funcs=[]
list_mLvl = []
list_mNrm = []
for i in range(num_consumer_types):
    list_mLvl.append(consumers_ss[i].state_now['mNrm']*consumers_ss[i].state_now['pLvl'] )
    list_mNrm.append(consumers_ss[i].state_now['mNrm'])
    funcs.append(consumers_ss[i].solution[0].cFunc)

mNrm = np.concatenate(list_mNrm)   
mLvl = np.concatenate(list_mLvl)
plot_funcs(funcs,0,1.4)
plt.hist(mNrm, bins=np.linspace(0,1.4,num=1000))
plt.show()

plt.hist(mLvl, bins=np.linspace(0,1.2,num=1000))
#
# The cell below creates an infinite horizon instance of `KinkedRconsumerType` and solves its model by calling its `solve` method.

# %%
KinkyExample = KinkedRconsumerType(**KinkedRdict)
KinkyExample.cycles = 0  # Make the example infinite horizon
KinkyExample.solve()

# %% [markdown]
# An element of a `KinkedRconsumerType`'s solution will have all the same attributes as that of a `IndShockConsumerType`; see that notebook for details.
#
# We can plot the consumption function of our "kinked R" example, as well as the MPC:

# %%
print("Kinked R consumption function:")
plot_funcs(KinkyExample.solution[0].cFunc, KinkyExample.solution[0].mNrmMin, 5)

print("Kinked R marginal propensity to consume:")
plot_funcs_der(KinkyExample.solution[0].cFunc,
               KinkyExample.solution[0].mNrmMin, 5)

# %% [markdown]
# ## Simulating the "kinked R" model
#
# In order to generate simulated data, an instance of `KinkedRconsumerType` needs to know how many agents there are that share these particular parameters (and are thus *ex ante* homogeneous), the distribution of states for newly "born" agents, and how many periods to simulated.  These simulation parameters are described in the table below, along with example values.
#
# | Description | Code | Example value |
# | :---: | --- | --- |
# | Number of consumers of this type | $\texttt{AgentCount}$ | $10000$ |
# | Number of periods to simulate | $\texttt{T_sim}$ | $500$ |
# | Mean of initial log (normalized) assets | $\texttt{aNrmInitMean}$ | $-6.0$ |
Beispiel #8
0
mNrmGrid = np.linspace(0, 20, 300)
for p in pLvlGrid:
    M_temp = mNrmGrid * p + ExplicitExample.solution[0].mLvlMin(p)
    C = ExplicitExample.solution[0].cFunc(M_temp, p * np.ones_like(M_temp))
    plt.plot(M_temp / p, C / p)

plt.xlim(0., 20.)
plt.xlabel('Normalized market resources mNrm')
plt.ylabel('Normalized consumption cNrm')
plt.show()

print(
    'Consumption function for normalized problem (without explicit permanent income):'
)
mNrmMin = NormalizedExample.solution[0].mNrmMin
plot_funcs(NormalizedExample.solution[0].cFunc, mNrmMin, mNrmMin + 20.)

# %% [markdown]
# The figures above show that the normalized consumption function for the "explicit permanent income" consumer is almost identical for every permanent income level (and the same as the normalized problem's $\texttt{cFunc}$), but is less accurate due to extrapolation outside the bounds of $\texttt{pLvlGrid}$.
#
# The "explicit permanent income" solution deviates from the solution to the normalized problem because of errors from extrapolating beyond the bounds of the $\texttt{pLvlGrid}$. The error is largest for $\texttt{pLvl}$ values near the upper and lower bounds, and propagates toward the center of the distribution.
#

# %%
# Plot the value function at various permanent income levels
if ExplicitExample.vFuncBool:
    pGrid = np.linspace(0.1, 3.0, 24)
    M = np.linspace(0.001, 5, 300)
    for p in pGrid:
        M_temp = M + ExplicitExample.solution[0].mLvlMin(p)
        C = ExplicitExample.solution[0].vFunc(M_temp, p * np.ones_like(M_temp))
num_points = 10  # number of parameter values to plot in graphs. More=slower

# First change the variance of the permanent income shock
perm_ratio_max = 2.5  # Put whatever value in you want!  maximum number to multiply var of perm income shock by

perm_min = BaselineType.PermShkStd[0] * ratio_min
perm_max = BaselineType.PermShkStd[0] * perm_ratio_max

plt.ylabel('% Change in Consumption')
plt.xlabel('Std. Dev. of Perm. Income Shock (Baseline = ' +
           str(round(BaselineType.PermShkStd[0], 2)) + ')')
plt.title('Change in Cons. Following Increase in Perm. Income Uncertainty')
plt.ylim(-40., 5.)
plt.hlines(TargetChangeInC, perm_min, perm_max)
# The expression below shows the power of python
plot_funcs([calcConsChangeAfterPermShkChange],
           perm_min,
           perm_max,
           N=num_points)

# %%

# %% [markdown]
# The figure shows that if people's beliefs about the standard deviation of permanent shocks to their incomes had changed from 0.06 (the default value) to about 0.012, the model would predict an immediate drop in consumption spending of about the magnitude seen in 2008.
#
# The question is whether this is a reasonable or an unreasonable magnitude for a change in uncertainty.  Some perspective on that question is offered by the large literature that attempts to estimate the magnitude of persistent or permanent shocks to household income.  The answer varies substantially across household types, countries, and time periods, but our sense of the literature is that the whole span of the territory between 0.04 and ranging nearly up to 0.20 is well populated (in the sense that substantial populations of people or countries have been estimated to experience shocks of this magnitude).
#
# The conclusion is that, in order for an increase in permanent income uncertainty to explain the entire drop in consumption spending, uncertainty in permanent income would have to have roughly doubled between Q2 and Q4 of 2008.  While this seems rather a large increase in uncertainty, it is by no means an absurdly large increase.  And, there is no reason to rule out the possibility that people perceived a likely change in the _level_ of their permanent income as well, which of course would translate one-for-one into a change in the appropriate level of consumption.
#
# The point is that it is not at all implausible, as a quantitative proposition, that an increase in uncertainty could have been responsible for a substantial portion of the decline in nondurable expenditures in the Great Recesssion.  (And it is even easier for an increase in uncertainty to induce a decline in durable goods purchases.
Beispiel #10
0
# Running the $\texttt{solve}$ method creates the **attribute** of $\texttt{PFexample}$ named $\texttt{solution}.$  In fact, every subclass of $\texttt{AgentType}$ works the same way: The class definition contains the abstract algorithm that knows how to solve the model, but to obtain the particular solution for a specific instance (paramterization/configuration), that instance must be instructed to $\texttt{solve()}$ its problem.
#
# The $\texttt{solution}$ attribute is always a _list_ of solutions to a sequence of single period solutions of the problem. In the case of an infinite horizon model like the one here, there is just one element in that list -- the solution to all periods of the infinite horizon problem.  (In a life cycle model, there would be a list of solutions, one for each age).  The consumption function stored as the first element (element 0) of the solution list can be retrieved by:

# %%
PFexample.solution[0].cFunc

# %% [markdown]
# One of the results proven in the associated [the lecture notes](http://econ.jhu.edu/people/ccarroll/public/lecturenotes/consumption/PerfForesightCRRA/) is that, for the specific problem defined above, there is a solution in which the _ratio_ $c = C/P$ is a linear function of the _ratio_ of market resources to permanent income, $m = M/P$.
#
# This is why $\texttt{cFunc}$ can be represented by a linear interpolation.  It can be plotted using the command below:
#

# %%
mPlotTop = 10
plot_funcs(PFexample.solution[0].cFunc, 0., mPlotTop)

# %% [markdown]
# The figure illustrates one of the surprising features of the perfect foresight model: A person with zero money should be spending at a rate more than double their income ($\texttt{cFunc}(0.) \approx 2.08$). What gives?
#
# The answer is that we have not incorporated any constraint that would prevent the agent from borrowing against the entire PDV of future earnings -- human wealth.
#
# How much is that?  An equivalent question is: What's the minimum value of $m_t$ where the consumption function is defined (that is, where the consumer has a positive expected _total wealth_ (the sum of human and nonuman wealth)?  Let's check:

# %%
humanWealth = PFexample.solution[0].hNrm
mMinimum = PFexample.solution[0].mNrmMin
print("This agent's human wealth is " + str(humanWealth) +
      ' times his current income level.')
print("This agent's consumption function is defined down to m_t = " +
      str(mMinimum))
# %% [markdown]
# Each element of `solution` has a few attributes. To see all of them, we can use the \texttt{vars} built in function:
#
# the consumption functions reside in the attribute $\texttt{cFunc}$ of each element of `ConsumerType.solution`.  This method creates a (time varying) attribute $\texttt{cFunc}$ that contains a list of consumption functions.

# %%
print(vars(PFexample.solution[0]))

# %% [markdown]
# The two most important attributes of a single period solution of this model are the (normalized) consumption function $\texttt{cFunc}$ and the (normalized) value function $\texttt{vFunc}$.  Let's plot those functions near the lower bound of the permissible state space (the attribute $\texttt{mNrmMin}$ tells us the lower bound of $m_t$ where the consumption function is defined).

# %%
print("Linear perfect foresight consumption function:")
mMin = PFexample.solution[0].mNrmMin
plot_funcs(PFexample.solution[0].cFunc, mMin, mMin + 10.0)

# %%
print("Perfect foresight value function:")
plot_funcs(PFexample.solution[0].vFunc, mMin + 0.1, mMin + 10.1)

# %% [markdown]
# An element of `solution` also includes the (normalized) marginal value function $\texttt{vPfunc}$, and the lower and upper bounds of the marginal propensity to consume (MPC) $\texttt{MPCmin}$ and $\texttt{MPCmax}$.  Note that with a linear consumption function, the MPC is constant, so its lower and upper bound are identical.
#
# ### Liquidity constrained perfect foresight example
#
# Without an artificial borrowing constraint, a perfect foresight consumer is free to borrow against the PDV of his entire future stream of labor income-- his "human wealth" $\texttt{hNrm}$-- and he will consume a constant proportion of his total wealth (market resources plus human wealth).  If we introduce an artificial borrowing constraint, both of these features vanish.  In the cell below, we define a parameter dictionary that prevents the consumer from borrowing *at all*, create and solve a new instance of `PerfForesightConsumerType` with it, and then plot its consumption function.

# %% {"pycharm": {"name": "#%%\n"}}
LiqConstrDict = copy(PerfForesightDict)
LiqConstrDict[
# %%
# Make and solve an example portfolio choice consumer type
print('Now solving an example portfolio choice problem; this might take a moment...')
MyType = PortfolioConsumerType()
MyType.cycles = 0
t0 = time()
MyType.solve()
t1 = time()
MyType.cFunc = [MyType.solution[t].cFuncAdj for t in range(MyType.T_cycle)]
MyType.ShareFunc = [MyType.solution[t].ShareFuncAdj for t in range(MyType.T_cycle)]
print('Solving an infinite horizon portfolio choice problem took ' + str(t1-t0) + ' seconds.')

# %%
# Plot the consumption and risky-share functions
print('Consumption function over market resources:')
plot_funcs(MyType.cFunc[0], 0., 20.)
print('Risky asset share as a function of market resources:')
print('Optimal (blue) versus Theoretical Limit (orange)')
plt.xlabel('Normalized Market Resources')
plt.ylabel('Portfolio Share')
plt.ylim(0.0,1.0)
# Since we are using a discretization of the lognormal distribution,
# the limit is numerically computed and slightly different from 
# the analytical limit obtained by Merton and Samuelson for infinite wealth
plot_funcs([MyType.ShareFunc[0]
#           ,lambda m: RiskyShareMertSamLogNormal(MyType.RiskPrem,MyType.CRRA,MyType.RiskyVar)*np.ones_like(m)
           ,lambda m: MyType.ShareLimit*np.ones_like(m)
          ] , 0., 200.)

# %%
# Now simulate this consumer type
Beispiel #13
0
# Create an instance of the type of consumer we are interested in
KinkyExample = KinkedRconsumerType()

# Make the example infinite horizon (not a life cycle model)
KinkyExample.cycles = 0

# The consumer cannot borrow more than 0.4 times their permanent income
KinkyExample.BoroCnstArt = -0.4

# Solve the consumer's problem
KinkyExample.solve()

# Plot the results
plt.ylabel('Consumption c')
plt.xlabel('Market Resources m')
plot_funcs([KinkyExample.solution[0].cFunc], KinkyExample.solution[0].mNrmMin,
           5)

# %% [markdown]
# 'Market Resources' $M$ is the total amount of money (assets plus current income) available to the consumer when the consumption decision is made.  Lower case $m = M/P$ is the ratio of $M$ to permanent income.  Likewise, $c = C/P$ is the ratio of consumption to permanent income.
#
# The line segment near $m=1$ captures the interval over which the consumer spends all of their market resources, because it's not worth it to borrow at the high credit card interest rate, but also not worth it to save at the low bank account interest rate.
#
# The bottommost point on the consumption function is at $m=-0.4$, where consumption is zero.  This consumer would like to borrow to finance spending out of future income, but is already at the maximum borrowing limit.
#
# The consumption function has a linear portion with a slope of 45 degrees along which the marginal propensity to consume out of extra market resources is 1.  But eventually resources get high enough that the consumer is willing to spend less than the maximum possible amount; this concave part of the consumption function terminates at the point where the consumer's desired borrowing reaches zero: The bottommost point on the line segment discussed above.

# %% [markdown]
# ### Solution With A Tighter Constraint
#
# We are now interested in the solution to the problem when the constraint is tighter; concretely, the maximum amount of borrowing allowed is now 0.2, rather than 0.4.
#
# Note that plot_funcs takes four arguments: (1) a list of the arguments to plot,
# (2) the lower bound for the plots, (3) the upper bound for the plots, and (4) keywords to pass
# to the legend for the plot.

# Plot the consumption functions to compare them
# The only difference is that the XtraCredit function has a credit limit that is looser
# by a tiny amount
print(
    'The XtraCredit consumption function allows the consumer to spend a tiny bit more'
)
print(
    'The difference is so small that the baseline is obscured by the XtraCredit solution'
)
plot_funcs(
    [BaselineExample.solution[0].cFunc, XtraCreditExample.solution[0].cFunc],
    BaselineExample.solution[0].mNrmMin,
    x_max,
    legend_kwds={
        'loc': 'upper left',
        'labels': ["Baseline", "XtraCredit"]
    })

# Plot the MPCs to compare them
print('MPC out of Credit v MPC out of Income')
plt.ylim([0., 1.2])
plot_funcs([FirstDiffMPC_Credit, FirstDiffMPC_Income],
           BaselineExample.solution[0].mNrmMin,
           x_max,
           legend_kwds={'labels': ["MPC out of Credit", "MPC out of Income"]})
Beispiel #15
0
t1 = time()
MyType.cFunc = [MyType.solution[t].cFuncAdj for t in range(MyType.T_cycle)]
MyType.ShareFunc = [MyType.solution[t].ShareFuncAdj for t in range(MyType.T_cycle)]
MyType.SequentialShareFunc = [
    MyType.solution[t].SequentialShareFuncAdj for t in range(MyType.T_cycle)
]
print(
    "Solving an infinite horizon portfolio choice problem took "
    + str(t1 - t0)
    + " seconds."
)

# %%
# Plot the consumption and risky-share functions
print("Consumption function over market resources:")
plot_funcs(MyType.cFunc[0], 0.0, 20.0)

# %%
# Since we are using a discretization of the lognormal distribution,
# the limit is numerically computed and slightly different from
# the analytical limit obtained by Merton and Samuelson for infinite wealth
print("Risky asset share as a function of liquid assets:")
print("Optimal (blue/orange) versus Theoretical Limit (green)")
plt.xlabel("Normalized Liquid Assets")
plt.ylabel("Portfolio Share")
plt.ylim(0.0, 1.0)
plt.xlim(0.0, 200.0)
mgrid = np.linspace(0.0, 300.0, 300)
cgrid = MyType.cFunc[0](mgrid)
shares = MyType.ShareFunc[0](mgrid)
agrid = mgrid - cgrid