Example #1
0
    def test_infinite_horizon(self):
        baseEx_inf = IndShockConsumerType(cycles=0, **self.base_params)

        baseEx_inf.solve()
        baseEx_inf.unpack("cFunc")

        m1 = np.linspace(
            1, baseEx_inf.solution[0].mNrmSS, 50
        )  # m1 defines the plot range on the left of target m value (e.g. m <= target m)
        c_m1 = baseEx_inf.cFunc[0](m1)

        self.assertAlmostEqual(c_m1[0], 0.8527887545025995)
        self.assertAlmostEqual(c_m1[-1], 1.0036279936408656)

        x1 = np.linspace(0, 25, 1000)
        cfunc_m = baseEx_inf.cFunc[0](x1)

        self.assertAlmostEqual(cfunc_m[500], 1.8902146173138235)
        self.assertAlmostEqual(cfunc_m[700], 2.1591451850267176)

        m = np.linspace(0.001, 8, 1000)

        # Use the HARK method derivative to get the derivative of cFunc, and the values are just the MPC
        MPC = baseEx_inf.cFunc[0].derivative(m)

        self.assertAlmostEqual(MPC[500], 0.08415000641504392)
        self.assertAlmostEqual(MPC[700], 0.07173144137912524)
    def setUp(self):
        """
        Prepare to compare the models by initializing and solving them
        """
        # Set up and solve infinite type

        # Define a test dictionary that should have the same solution in the
        # perfect foresight and idiosyncratic shocks models.
        test_dictionary = deepcopy(init_idiosyncratic_shocks)
        test_dictionary["LivPrb"] = [1.0]
        test_dictionary["DiscFac"] = 0.955
        test_dictionary["PermGroFac"] = [1.0]
        test_dictionary["PermShkStd"] = [0.0]
        test_dictionary["TranShkStd"] = [0.0]
        test_dictionary["UnempPrb"] = 0.0
        test_dictionary["T_cycle"] = 1
        test_dictionary["T_retire"] = 0
        test_dictionary["BoroCnstArt"] = None

        InfiniteType = IndShockConsumerType(**test_dictionary)
        InfiniteType.cycles = 0

        InfiniteType.update_income_process()
        InfiniteType.solve()
        InfiniteType.unpack("cFunc")

        # Make and solve a perfect foresight consumer type with the same parameters
        PerfectForesightType = PerfForesightConsumerType(**test_dictionary)
        PerfectForesightType.cycles = 0

        PerfectForesightType.solve()
        PerfectForesightType.unpack("cFunc")

        self.InfiniteType = InfiniteType
        self.PerfectForesightType = PerfectForesightType
Example #3
0
def makeConvergencePlot(DiscFac, CRRA, Rfree, PermShkStd):
    # Construct finite horizon agent with baseline parameters
    baseAgent_Fin = IndShockConsumerType(verbose=0, **base_params)
    baseAgent_Fin.DiscFac = DiscFac
    baseAgent_Fin.CRRA = CRRA
    baseAgent_Fin.Rfree = Rfree
    baseAgent_Fin.PermShkStd = [PermShkStd]
    baseAgent_Fin.cycles = 100
    baseAgent_Fin.updateIncomeProcess()
    baseAgent_Fin.solve()
    baseAgent_Fin.unpack('cFunc')

    # figure limits
    mMax = 6  # 11
    mMin = 0
    cMin = 0
    cMax = 4  # 7

    mPlotMin = 0
    mLocCLabels = 5.6  # 9.6 # Defines horizontal limit of figure
    mPlotTop = 3.5  # 6.5    # Defines maximum m value where functions are plotted
    mPts = 1000  # Number of points at which functions are evaluated

    plt.figure(figsize=(12, 8))
    plt.ylim([cMin, cMax])
    plt.xlim([mMin, mMax])

    mBelwLabels = np.linspace(mPlotMin, mLocCLabels - 0.1,
                              mPts)  # Range of m below loc of labels
    m_FullRange = np.linspace(mPlotMin, mPlotTop, mPts)  # Full plot range
    c_Tm0 = m_FullRange  # c_Tm0  defines the last period consumption rule (c=m)
    c_Tm1 = baseAgent_Fin.cFunc[-2](
        mBelwLabels
    )  # c_Tm1 defines the second-to-last period consumption rule
    c_Tm5 = baseAgent_Fin.cFunc[-6](
        mBelwLabels)  # c_Tm5 defines the T-5 period consumption rule
    c_Tm10 = baseAgent_Fin.cFunc[-11](
        mBelwLabels)  # c_Tm10 defines the T-10 period consumption rule
    c_Limt = baseAgent_Fin.cFunc[0](
        mBelwLabels
    )  # c_Limt defines limiting infinite-horizon consumption rule

    plt.plot(mBelwLabels, c_Limt, label="$c(m)$")
    plt.plot(mBelwLabels, c_Tm1, label="$c_{T-1}(m)$")
    plt.plot(mBelwLabels, c_Tm5, label="$c_{T-5}(m)$")
    plt.plot(mBelwLabels, c_Tm10, label="$c_{T-10}(m)$")
    plt.plot(m_FullRange, c_Tm0, label="$c_{T}(m) = 45$ degree line")
    plt.legend(fontsize='x-large')
    plt.tick_params(
        labelbottom=False,
        labelleft=False,
        left="off",
        right="off",
        bottom="off",
        top="off",
    )

    plt.show()
    return None
def makeTargetMfig(Rfree, DiscFac, CRRA, PermShkStd, TranShkStd):
    baseAgent_Inf = IndShockConsumerType(verbose=0, cycles=0, **base_params)
    baseAgent_Inf.Rfree = Rfree
    baseAgent_Inf.DiscFac = DiscFac
    baseAgent_Inf.CRRA = CRRA
    baseAgent_Inf.PermShkStd = [PermShkStd]
    baseAgent_Inf.TranShkStd = [TranShkStd]
    baseAgent_Inf.updateIncomeProcess()
    baseAgent_Inf.checkConditions()
    mPlotMin = 0
    mPlotMax = 250
    baseAgent_Inf.aXtraMax = mPlotMax
    baseAgent_Inf.solve()
    baseAgent_Inf.unpack('cFunc')
    cPlotMin = 0
    cPlotMax = baseAgent_Inf.cFunc[0](mPlotMax)

    if (baseAgent_Inf.GPFInd >= 1):
        baseAgent_Inf.checkGICInd(verbose=3)

    mBelwTrg = np.linspace(mPlotMin, mPlotMax, 1000)
    EPermGroFac = baseAgent_Inf.PermGroFac[0]
    EmDelEq0 = lambda m: (EPermGroFac / Rfree) + (1.0 - EPermGroFac / Rfree
                                                  ) * m
    cBelwTrg_Best = baseAgent_Inf.cFunc[0](mBelwTrg)  # "best" = optimal c
    cBelwTrg_Sstn = EmDelEq0(mBelwTrg)  # "sustainable" c
    mNrmTrg = baseAgent_Inf.solution[0].mNrmSS

    plt.figure(figsize=(12, 8))
    plt.plot(mBelwTrg, cBelwTrg_Best, label="$c(m_{t})$")
    plt.plot(mBelwTrg,
             cBelwTrg_Sstn,
             label="$\mathsf{E}_{t}[\Delta m_{t+1}] = 0$")
    plt.xlim(mPlotMin, mPlotMax)
    plt.ylim(cPlotMin, cPlotMax)
    plt.plot(
        [mNrmTrg, mNrmTrg],
        [0, 2.5],
        color="black",
        linestyle="--",
    )
    plt.tick_params(
        #        labelbottom=False,
        #        labelleft=False,
        #        left="off",
        right="off",
        #        bottom="off",
        top="off",
    )
    plt.text(0, 1.47, r"$c$", fontsize=26)
    plt.text(3.02, 0, r"$m$", fontsize=26)
    plt.text(mNrmTrg - 0.05, -0.1, "m̌", fontsize=26)
    plt.legend(fontsize='x-large')
    plt.show()
    return None
Example #5
0
    def test_GICFails(self):
        GIC_fail_dictionary = dict(self.base_params)
        GIC_fail_dictionary["Rfree"] = 1.08
        GIC_fail_dictionary["PermGroFac"] = [1.00]

        GICFailExample = IndShockConsumerType(
            cycles=0,  # cycles=0 makes this an infinite horizon consumer
            **GIC_fail_dictionary)

        GICFailExample.solve()
        GICFailExample.unpack("cFunc")
        m = np.linspace(0, 5, 1000)
        c_m = GICFailExample.cFunc[0](m)

        self.assertAlmostEqual(c_m[500], 0.7772637042393458)
        self.assertAlmostEqual(c_m[700], 0.8392649061916746)

        self.assertFalse(GICFailExample.conditions["GIC"])
Example #6
0
    def test_baseEx(self):
        baseEx = IndShockConsumerType(**self.base_params)
        baseEx.cycles = 100  # Make this type have a finite horizon (Set T = 100)

        baseEx.solve()
        baseEx.unpack("cFunc")

        m = np.linspace(0, 9.5, 1000)

        c_m = baseEx.cFunc[0](m)
        c_t1 = baseEx.cFunc[-2](m)
        c_t5 = baseEx.cFunc[-6](m)
        c_t10 = baseEx.cFunc[-11](m)

        self.assertAlmostEqual(c_m[500], 1.4008090582203356)
        self.assertAlmostEqual(c_t1[500], 2.9227437159255216)
        self.assertAlmostEqual(c_t5[500], 1.7350607327187664)
        self.assertAlmostEqual(c_t10[500], 1.4991390649979213)
        self.assertAlmostEqual(c_t10[600], 1.6101476268581576)
        self.assertAlmostEqual(c_t10[700], 1.7196531041366991)
Example #7
0
# c(m) = \lim_{n \uparrow \infty} c_{T-n}(m) \notag
# $$
#

# %%
# Create a buffer stock consumer instance by invoking the IndShockConsumerType class

# %% {"jupyter": {"source_hidden": true}, "tags": []}
# with the built-in parameter dictionary "base_params"

# Construct finite horizon agent with baseline parameters
baseAgent_Fin = IndShockConsumerType(**base_params)
baseAgent_Fin.cycles = 100   # Set finite horizon (T = 100)

baseAgent_Fin.solve(verbose=0)        # Solve the model
baseAgent_Fin.unpack('cFunc')  # Make the consumption function easily accessible


# %%
# Plot the different consumption rules for the different periods

# %% {"jupyter": {"source_hidden": true, "outputs_hidden": true}, "tags": []}

mPlotMin = 0
mLocCLabels = 9.6  # Defines horizontal limit of figure
mPlotTop = 6.5    # Defines maximum m value where functions are plotted
mPts = 1000      # Number of points at which functions are evaluated

mBelwLabels = np.linspace(mPlotMin, mLocCLabels-0.1, mPts)  # Range of m below loc of labels
m_FullRange = np.linspace(mPlotMin, mPlotTop, mPts)        # Full plot range
# c_Tm0  defines the last period consumption rule (c=m)
Example #8
0
def makeGrowthplot(PermGroFac, DiscFac):
    # cycles=0 tells the solver to find the infinite horizon solution
    baseAgent_Inf = IndShockConsumerType(verbose=0, cycles=0, **base_params)
    baseAgent_Inf.PermGroFac = [PermGroFac]
    baseAgent_Inf.DiscFac = DiscFac
    baseAgent_Inf.updateIncomeProcess()
    baseAgent_Inf.checkConditions()
    baseAgent_Inf.solve()
    baseAgent_Inf.unpack('cFunc')
    if (baseAgent_Inf.GPFInd >= 1):
        baseAgent_Inf.checkGICInd(verbose=3)
    elif baseAgent_Inf.solution[0].mNrmSS > 3.5:
        print('Solution exists but is outside the plot range.')
    else:

        def EcLev_tp1_Over_p_t(a):
            '''
            Taking end-of-period assets a as input, return ratio of expectation 
            of next period's consumption to this period's permanent income 

            Inputs:
               a: end-of-period assets
            Returns:
               EcLev_tp1_Over_p_{t}: next period's expected c level / current p
            '''
            # Extract parameter values to make code more readable
            permShkVals = baseAgent_Inf.PermShkDstn[0].X
            tranShkVals = baseAgent_Inf.TranShkDstn[0].X
            permShkPrbs = baseAgent_Inf.PermShkDstn[0].pmf
            tranShkPrbs = baseAgent_Inf.TranShkDstn[0].pmf
            Rfree = baseAgent_Inf.Rfree
            EPermGroFac = baseAgent_Inf.PermGroFac[0]

            PermGrowFac_tp1 = EPermGroFac * permShkVals  # Nonstochastic growth times idiosyncratic permShk
            RNrmFac_tp1 = Rfree / PermGrowFac_tp1  # Growth-normalized interest factor
            # 'bank balances' b = end-of-last-period assets times normalized return factor
            b_tp1 = RNrmFac_tp1 * a
            # expand dims of b_tp1 and use broadcasted sum of a column and a row vector
            # to obtain a matrix of possible market resources next period
            # because matrix mult is much much faster than looping to calc E
            m_tp1_GivenTranAndPermShks = np.expand_dims(b_tp1,
                                                        axis=1) + tranShkVals
            # List of possible values of $\mathbf{c}_{t+1}$ (Transposed by .T)
            cRat_tp1_GivenTranAndPermShks = baseAgent_Inf.cFunc[0](
                m_tp1_GivenTranAndPermShks).T
            cLev_tp1_GivenTranAndPermShks = cRat_tp1_GivenTranAndPermShks * PermGrowFac_tp1
            # compute expectation over perm shocks by right multiplying with probs
            EOverPShks_cLev_tp1_GivenTranShkShks = np.dot(
                cLev_tp1_GivenTranAndPermShks, permShkPrbs)
            # finish expectation over trans shocks by right multiplying with probs
            EcLev_tp1_Over_p_t = np.dot(EOverPShks_cLev_tp1_GivenTranShkShks,
                                        tranShkPrbs)
            # return expected consumption
            return EcLev_tp1_Over_p_t

        # Calculate the expected consumption growth factor
        # mBelwTrg defines the plot range on the left of target m value (e.g. m <= target m)
        mNrmTrg = baseAgent_Inf.solution[0].mNrmSS
        mBelwTrg = np.linspace(1, mNrmTrg, 50)
        c_For_mBelwTrg = baseAgent_Inf.cFunc[0](mBelwTrg)
        a_For_mBelwTrg = mBelwTrg - c_For_mBelwTrg
        EcLev_tp1_Over_p_t_For_mBelwTrg = [
            EcLev_tp1_Over_p_t(i) for i in a_For_mBelwTrg
        ]

        # mAbveTrg defines the plot range on the right of target m value (e.g. m >= target m)
        mAbveTrg = np.linspace(mNrmTrg, 3.5, 50)

        # EcGro_For_mAbveTrg: E [consumption growth factor] when m_{t} is below target m
        EcGro_For_mBelwTrg = np.array(
            EcLev_tp1_Over_p_t_For_mBelwTrg) / c_For_mBelwTrg

        c_For_mAbveTrg = baseAgent_Inf.cFunc[0](mAbveTrg)
        a_For_mAbveTrg = mAbveTrg - c_For_mAbveTrg
        EcLev_tp1_Over_p_t_For_mAbveTrg = [
            EcLev_tp1_Over_p_t(i) for i in a_For_mAbveTrg
        ]

        # EcGro_For_mAbveTrg: E [consumption growth factor] when m_{t} is bigger than target m_{t}
        EcGro_For_mAbveTrg = np.array(
            EcLev_tp1_Over_p_t_For_mAbveTrg) / c_For_mAbveTrg

        Rfree = 1.0
        EPermGroFac = 1.0
        mNrmTrg = baseAgent_Inf.solution[0].mNrmSS

        # Calculate Absolute Patience Factor Phi = lower bound of consumption growth factor
        APF = (Rfree * DiscFac)**(1.0 / CRRA)

        plt.figure(figsize=(12, 8))
        # Plot the Absolute Patience Factor line
        plt.plot([0, 3.5], [APF, APF],
                 label="\u03A6 = [(\u03B2 R)^(1/ \u03C1)]/R")

        # Plot the Permanent Income Growth Factor line
        plt.plot([0, 3.5], [EPermGroFac, EPermGroFac], label="\u0393")

        # Plot the expected consumption growth factor on the left side of target m
        plt.plot(mBelwTrg, EcGro_For_mBelwTrg, color="black")

        # Plot the expected consumption growth factor on the right side of target m
        plt.plot(mAbveTrg,
                 EcGro_For_mAbveTrg,
                 color="black",
                 label="$\mathsf{E}_{t}[c_{t+1}/c_{t}]$")

        # Plot the target m
        plt.plot(
            [mNrmTrg, mNrmTrg],
            [0, 3.5],
            color="black",
            linestyle="--",
            label="",
        )
        plt.xlim(1, 3.5)
        plt.ylim(0.94, 1.10)
        plt.text(2.105, 0.930, "$m_{t}$", fontsize=26, fontweight="bold")
        plt.text(
            mNrmTrg - 0.02,
            0.930,
            "m̌",
            fontsize=26,
            fontweight="bold",
        )
        plt.tick_params(
            labelbottom=False,
            labelleft=False,
            left="off",
            right="off",
            bottom="off",
            top="off",
        )
        plt.legend(fontsize='x-large')
        plt.show()
        return None
Example #9
0
def makeBoundsFigure(UnempPrb, PermShkStd, TranShkStd, DiscFac, CRRA):
    baseAgent_Inf = IndShockConsumerType(verbose=0, cycles=0, **base_params)
    baseAgent_Inf.UnempPrb = UnempPrb
    baseAgent_Inf.PermShkStd = [PermShkStd]
    baseAgent_Inf.TranShkStd = [TranShkStd]
    baseAgent_Inf.DiscFac = DiscFac
    baseAgent_Inf.CRRA = CRRA
    baseAgent_Inf.updateIncomeProcess()
    baseAgent_Inf.checkConditions()
    baseAgent_Inf.solve()
    baseAgent_Inf.unpack('cFunc')
    # Retrieve parameters (makes code readable)
    Rfree = baseAgent_Inf.Rfree
    CRRA = baseAgent_Inf.CRRA
    EPermGroFac = baseAgent_Inf.PermGroFac[0]
    mNrmTrg = baseAgent_Inf.solution[0].mNrmSS
    UnempPrb = baseAgent_Inf.UnempPrb

    κ_Min = 1.0 - (Rfree**(-1.0)) * (Rfree * DiscFac)**(1.0 / CRRA)
    h_inf = (1.0 / (1.0 - EPermGroFac / Rfree))
    cFunc_Uncnst = lambda m: (h_inf - 1) * κ_Min + κ_Min * m
    cFunc_TopBnd = lambda m: (1 - UnempPrb**(1.0 / CRRA) *
                              (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) * m
    cFunc_BotBnd = lambda m: (1 - (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) * m

    # Plot the consumption function and its bounds
    cMaxLabel = r"c̅$(m) = (m-1+h)κ̲$"  # Use unicode kludge
    cMinLabel = r"c̲$(m)= (1-\Phi_{R})m = κ̲ m$"

    mPlotMax = 25
    mPlotMin = 0
    # mKnk is point where the two upper bounds meet
    mKnk = ((h_inf - 1) * κ_Min) / (
        (1 - UnempPrb**(1.0 / CRRA) *
         (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) - κ_Min)
    mBelwKnkPts = 300
    mAbveKnkPts = 700
    mBelwKnk = np.linspace(mPlotMin, mKnk, mBelwKnkPts)
    mAbveKnk = np.linspace(mKnk, mPlotMax, mAbveKnkPts)
    mFullPts = np.linspace(mPlotMin, mPlotMax, mBelwKnkPts + mAbveKnkPts)

    plt.figure(figsize=(12, 8))
    plt.plot(mFullPts, baseAgent_Inf.cFunc[0](mFullPts), label=r'$c(m)$')
    plt.plot(mBelwKnk, cFunc_Uncnst(mBelwKnk), label=cMaxLabel, linestyle="--")
    plt.plot(
        mAbveKnk,
        cFunc_Uncnst(mAbveKnk),
        label=
        r'Upper Bound $ = $ Min $[\overline{\overline{c}}(m),\overline{c}(m)]$',
        linewidth=2.5,
        color='black')
    plt.plot(mBelwKnk, cFunc_TopBnd(mBelwKnk), linewidth=2.5, color='black')
    plt.plot(mAbveKnk,
             cFunc_TopBnd(mAbveKnk),
             linestyle="--",
             label=r"$\overline{\overline{c}}(m) = κ̅m = (1 - ℘^{1/ρ}Φᵣ)m$")
    plt.plot(mBelwKnk, cFunc_BotBnd(mBelwKnk), color='red', linewidth=2.5)
    plt.plot(mAbveKnk,
             cFunc_BotBnd(mAbveKnk),
             color='red',
             label=cMinLabel,
             linewidth=2.5)
    plt.tick_params(labelbottom=False,
                    labelleft=False,
                    left='off',
                    right='off',
                    bottom='off',
                    top='off')
    plt.xlim(mPlotMin, mPlotMax)
    plt.ylim(mPlotMin, 1.12 * cFunc_Uncnst(mPlotMax))
    plt.text(mPlotMin,
             1.12 * cFunc_Uncnst(mPlotMax) + 0.05,
             "$c$",
             fontsize=22)
    plt.text(mPlotMax + 0.1, mPlotMin, "$m$", fontsize=22)
    plt.legend(fontsize='x-large')
    plt.show()
    return None
Example #10
0
if do_simulation:
    PFexample.T_sim = 120  # Set number of simulation periods
    PFexample.track_vars = ["mNrmNow"]
    PFexample.initializeSim()
    PFexample.simulate()

# Make and solve an example consumer with idiosyncratic income shocks
IndShockExample = IndShockConsumerType()
IndShockExample.cycles = 0  # Make this type have an infinite horizon

start_time = time()
IndShockExample.solve()
end_time = time()
print("Solving a consumer with idiosyncratic shocks took " +
      mystr(end_time - start_time) + " seconds.")
IndShockExample.unpack('cFunc')

# Plot the consumption function and MPC for the infinite horizon consumer
print("Concave consumption function:")
plotFuncs(IndShockExample.cFunc[0], IndShockExample.solution[0].mNrmMin, 5)
print("Marginal consumption function:")
plotFuncsDer(IndShockExample.cFunc[0], IndShockExample.solution[0].mNrmMin, 5)

# Compare the consumption functions for the perfect foresight and idiosyncratic
# shock types.  Risky income cFunc asymptotically approaches perfect foresight cFunc.
print("Consumption functions for perfect foresight vs idiosyncratic shocks:")
plotFuncs(
    [PFexample.cFunc[0], IndShockExample.cFunc[0]],
    IndShockExample.solution[0].mNrmMin,
    100,
)
Example #11
0
def makeGICFailExample(DiscFac, PermShkStd, UnempPrb):

    # Construct the "GIC fails" example.

    GIC_fails_dictionary = dict(base_params)
    GIC_fails_dictionary['Rfree'] = 1.04
    GIC_fails_dictionary['PermGroFac'] = [1.00]
    GICFailsExample = IndShockConsumerType(
        verbose=0,
        cycles=0,  # cycles=0 makes this an infinite horizon consumer
        **GIC_fails_dictionary)
    GICFailsExample.DiscFac = DiscFac
    GICFailsExample.PermShkStd = [PermShkStd]
    GICFailsExample.UnempPrb = UnempPrb
    GICFailsExample.updateIncomeProcess()
    GICFailsExample.checkConditions()

    # Get calibrated parameters to make code more readable
    LivPrb = GICFailsExample.LivPrb[0]
    Rfree = GICFailsExample.Rfree
    DiscFac = GICFailsExample.DiscFac
    CRRA = GICFailsExample.CRRA

    permShkPrbs = GICFailsExample.PermShkDstn[0].pmf
    permShkVals = GICFailsExample.PermShkDstn[0].X
    EPermGroFac = GICFailsExample.PermGroFac[0]

    # np.dot multiplies vectors; probability times value for each outcome is expectation
    EpermShkInv = np.dot(permShkPrbs,
                         permShkVals**(-1))  # $   \Ex[\permShk^{-1}]      $
    InvEpermShkInv = (EpermShkInv)**(-1)  # $  (\Ex[\permShk^{-1}])^{-1}$
    PermGroFac = EPermGroFac * InvEpermShkInv  # Uncertainty-adjusted permanent growth factor
    ERNrmFac = Rfree / PermGroFac  # Interest factor normalized by uncertainty-adjusted growth
    ErNrmRte = ERNrmFac - 1  # Interest rate is interest factor - 1
    # "sustainable" C = P + (discounted) interest income
    # "sustainable" c = 1 + (discounted, normalized) interest income
    EmDelEq0 = lambda m: 1 + (m - 1) * (ErNrmRte / ERNrmFac
                                        )  # "sustainable" c where E[Δ m] = 0

    GICFailsExample.solve(
    )  # Above, we set up the problem but did not solve it
    GICFailsExample.unpack(
        'cFunc'
    )  # Make the consumption function easily accessible for plotting

    mPlotMin = 0
    mPts = 1000
    m = np.linspace(mPlotMin, 5, mPts)
    c_Limt = GICFailsExample.cFunc[0](m)
    c_Sstn = EmDelEq0(m)  # "sustainable" consumption

    plt.figure(figsize=(12, 8))
    plt.plot(m, c_Limt, label="$c(m_{t})$")
    plt.plot(m, c_Sstn, label="$\mathsf{E}_{t}[\Delta m_{t+1}] = 0$")
    plt.xlim(0, 5.5)
    plt.ylim(0, 1.6)
    plt.tick_params(
        labelbottom=False,
        labelleft=False,
        left="off",
        right="off",
        bottom="off",
        top="off",
    )
    plt.legend(fontsize='x-large')
    plt.show()
    print(f'Current Growth Impatience Factor is {GICFailsExample.GPFInd}')
    return None
Example #12
0
# -
# ## Counterclockwise Concavification
#

# + {"code_folding": [0]}
# This figure illustrates how both risks and constraints are examples of counterclockwise concavifications.
# It plots three lines: the linear consumption function of a perfect foresight consumer, the kinked consumption
# function of a consumer who faces a constraint, and the curved consumption function of a consumer that faces risk.

# load the three agents: unconstrained perfect foresight, constrained perfect foresight, unconstrained with risk

CCC_unconstr = IndShockConsumerType(**init_lifecycle)
CCC_unconstr.delFromTimeInv('BoroCnstArt')
CCC_unconstr.addToTimeVary('BoroCnstArt')
CCC_unconstr.solve()
CCC_unconstr.unpack("cFunc")

CCC_constraint = IndShockConsumerType(**init_lifecycle)
CCC_constraint.delFromTimeInv('BoroCnstArt')
CCC_constraint.addToTimeVary('BoroCnstArt')
CCC_constraint.BoroCnstArt = [
    None, -1, None, None, None, None, None, None, None, None
]
CCC_constraint.solve()
CCC_constraint.unpack("cFunc")

CCC_risk = IndShockConsumerType(**init_lifecycle_risk1)
CCC_risk.delFromTimeInv('BoroCnstArt')
CCC_risk.addToTimeVary('BoroCnstArt')
CCC_risk.solve()
CCC_risk.unpack("cFunc")
#
# $$
# c(m) = \lim_{n \uparrow \infty} c_{T-n}(m) \notag
# $$
#

# %%
# Create a buffer stock consumer instance by invoking the IndShockConsumerType class
# with the built-in parameter dictionary "base_params"

# Construct finite horizon agent with baseline parameters
baseAgent_Fin = IndShockConsumerType(**base_params)
baseAgent_Fin.cycles = 100   # Set finite horizon (T = 100)

baseAgent_Fin.solve()        # Solve the model
baseAgent_Fin.unpack('cFunc')  # Make the consumption function easily accessible


# %%
# Plot the different consumption rules for the different periods

mPlotMin  = 0
mLocCLabels = 9.6 # Defines horizontal limit of figure
mPlotTop = 6.5    # Defines maximum m value where functions are plotted
mPts  = 1000      # Number of points at which functions are evaluated

mBelwLabels    = np.linspace(mPlotMin,mLocCLabels-0.1,mPts) # Range of m below loc of labels
m_FullRange    = np.linspace(mPlotMin,mPlotTop,mPts)        # Full plot range 
c_Tm0  = m_FullRange                           # c_Tm0  defines the last period consumption rule (c=m)
c_Tm1  = baseAgent_Fin.cFunc[ -2](mBelwLabels) # c_Tm1 defines the second-to-last period consumption rule
c_Tm5  = baseAgent_Fin.cFunc[ -6](mBelwLabels) # c_Tm5 defines the T-5 period consumption rule
Example #14
0
def make_future_kink(in_BoroCnstArt):
    """
    This figure illustrates how a the introduction of a current constraint can hide/move a kink that was induced by a future constraint.

    To construct this figure, we plot two consumption functions:
    1) perfect foresight consumer that faces one constraint in period 2
    2) perfect foresight consumer that faces the same constraint as above plus one more constraint in period 3

    Both consumption functions first loads the parameter set of the perfect foresight lifecycle households with ten periods.
    We then change the parameter "BoroCnstArt" which corresponds to big Tau in the paper, i.e. the set of future constraints ordered by time.
    """

    # Make and solve the consumer with only one borrowing constraint
    Bcons1 = IndShockConsumerType(**init_lifecycle)
    Bcons1.delFromTimeInv("BoroCnstArt")
    Bcons1.addToTimeVary("BoroCnstArt")
    Bcons1.BoroCnstArt = [None, 0, None, None, None, None, None, None, None, None]
    Bcons1.solve()
    Bcons1.unpack("cFunc")

    # Make and solve the consumer with more than one binding borrowing constraint
    BCons2 = IndShockConsumerType(**init_lifecycle)
    BCons2.delFromTimeInv("BoroCnstArt")
    BCons2.addToTimeVary("BoroCnstArt")
    BCons2.BoroCnstArt = [
        None,
        0,
        in_BoroCnstArt,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
    ]
    BCons2.solve()
    BCons2.unpack("cFunc")

    x = np.linspace(1, 1.2, 500, endpoint=True)
    y_mod1 = Bcons1.cFunc[0](x)
    y_mod2 = BCons2.cFunc[0](x)

    where_close = np.isclose(y_mod1, y_mod2)
    x0 = x[where_close][0]
    y0 = y_mod1[where_close][0]

    y1dd = np.diff(y_mod1, n=2)
    ind1 = np.argmin(y1dd[:250]) + 1
    x1 = x[ind1]
    y1 = y_mod1[ind1]

    y2dd = np.diff(y_mod2, n=2)
    ind2 = np.argmin(y2dd[:250]) + 1
    x2 = x[ind2]
    y2 = y_mod2[ind2]

    # Display the figure
    # print('Figure 2: How a Current Constraint Can Hide a Future Kink')

    f = plt.figure()
    plt.plot(x, y_mod1, color="green", label="$c_{t,1}$")
    plt.plot(x, y_mod2, color="red", label="$\hat{c}_{t,2}$")
    # plt.text(1.15,1.01,"$\hat{c}_{t,2}$",fontsize=14)
    # plt.text(1.07,1.01,"$c_{t,1}$",fontsize=14)
    # plt.arrow(1.149,1.011,-0.01,0,head_width=0.001,width=0.0001,facecolor='black',length_includes_head='True')
    # plt.arrow(1.085,1.011,0.01,0,head_width=0.001,width=0.0001,facecolor='black',length_includes_head='True')

    plt.xlim(left=1.0, right=1.2)
    plt.ylim(0.98, 1.025)
    plt.tick_params(
        labelbottom=False,
        labelleft=False,
        left="off",
        right="off",
        bottom="off",
        top="off",
    )

    plt.text(0.99, 1.025, "$c$", fontsize=14)
    plt.text(1.20, 0.978, "$w$", fontsize=14)

    plt.text(0.988, y0, "$\hat{c}_{t,1}^{\#}$", fontsize=14)
    plt.text(0.988, y1 + 0.0015, "${c}_{t,1}^{\#}$", fontsize=14)
    plt.text(0.97, y2 - 0.0015, "$\hat{c}_{t,2}(w_{t,1})$", fontsize=14)

    plt.annotate(
        "kink that \n gets hidden",
        xy=(x1, y1),
        xytext=((x1 + 3) / 4, y1 + 0.005),
        arrowprops=dict(facecolor="black", headwidth=4, width=1, shrink=0.15),
    )

    plt.text(x0 - 0.005, 0.977, "$\hat{w}_{t,1}$", fontsize=14)
    plt.text(x1 - 0.005, 0.977, "$w_{t,1}$", fontsize=14)
    plt.text(x2 - 0.01, 0.975, "$\hat{w}_{t,2}$", fontsize=14)

    plt.plot([1, x0], [y0, y0], color="black", linestyle="--")
    plt.plot([1, x1], [y1, y1], color="black", linestyle="--")
    plt.plot([1, x2], [y2, y2], color="black", linestyle="--")

    plt.plot([x0, x0], [0.98, y0], color="black", linestyle="--")
    plt.plot([x1, x1], [0.98, y1], color="black", linestyle="--")
    plt.plot([x2, x2], [0.98, y2], color="black", linestyle="--")

    plt.legend()
    plt.show()
    return None
# %% [markdown]
# `# Create a buffer stock consumer instance:`

# %% {"jupyter": {"source_hidden": true}, "tags": []}
# Create a buffer stock consumer instance by invoking the IndShockConsumerType class
# with the parameter dictionary "base_params"

base_params['cycles'] = 100  # periods to solve from end
# Construct finite horizon agent with baseline parameters
baseAgent_Fin = \
    IndShockConsumerType(**base_params,
                         quietly=True)  # Don't say anything during setup

baseAgent_Fin.solve(quietly=True)  # Solve the model quietly

baseAgent_Fin.unpack('cFunc')  # Retrieve consumption functions
cFunc = baseAgent_Fin.cFunc    # Shorthand


# %% [markdown]
# `# Plot the consumption rules:`

# %% {"jupyter": {"source_hidden": true}, "tags": []}
# Plot the different consumption rules for the different periods

mPlotMin = 0
mLocCLabels = 9.6  # Defines horizontal limit of figure
mPlotTop = 6.5    # Defines maximum m value where functions are plotted
mPts = 1000      # Number of points at which functions are evaluated

mBelwLabels = np.linspace(mPlotMin, mLocCLabels-0.1, mPts)  # Range of m below loc of labels
Example #16
0
# -
# ## Counterclockwise Concavification
#

# + {"code_folding": [0]}
# This figure illustrates how both risks and constraints are examples of counterclockwise concavifications.
# It plots three lines: the linear consumption function of a perfect foresight consumer, the kinked consumption
# function of a consumer who faces a constraint, and the curved consumption function of a consumer that faces risk.

# load the three agents: unconstrained perfect foresight, constrained perfect foresight, unconstrained with risk

CCC_unconstr = IndShockConsumerType(**init_lifecycle)
CCC_unconstr.delFromTimeInv('BoroCnstArt')
CCC_unconstr.addToTimeVary('BoroCnstArt')
CCC_unconstr.solve()
CCC_unconstr.unpack('cFunc')

CCC_constraint = IndShockConsumerType(**init_lifecycle)
CCC_constraint.delFromTimeInv('BoroCnstArt')
CCC_constraint.addToTimeVary('BoroCnstArt')
CCC_constraint.BoroCnstArt = [
    None, -1, None, None, None, None, None, None, None, None
]
CCC_constraint.solve()
CCC_constraint.unpack('cFunc')

CCC_risk = IndShockConsumerType(**init_lifecycle_risk1)
CCC_risk.delFromTimeInv('BoroCnstArt')
CCC_risk.addToTimeVary('BoroCnstArt')
CCC_risk.solve()
CCC_risk.unpack('cFunc')
Example #17
0
def make_cons_func(in_BoroCnstArt, in_TranShkStd):
    """
    This figure illustrates how the effect of risk is greater if there already exists a constraint.

    Initialize four types: unconstrained perfect foresight, unconstrained with risk, constrained perfect foresight, and constrained with risk.
    """

    WwCR_unconstr = IndShockConsumerType(**init_lifecycle)
    WwCR_unconstr.delFromTimeInv("BoroCnstArt")
    WwCR_unconstr.addToTimeVary("BoroCnstArt")
    WwCR_unconstr.solve()
    WwCR_unconstr.unpack("cFunc")

    init_lifecycle_risk2["TranShkStd"] = [0, in_TranShkStd, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    WwCR_risk = IndShockConsumerType(**init_lifecycle_risk2)
    WwCR_risk.delFromTimeInv("BoroCnstArt")
    WwCR_risk.addToTimeVary("BoroCnstArt")
    WwCR_risk.solve()
    WwCR_risk.unpack("cFunc")

    WwCR_constr = IndShockConsumerType(**init_lifecycle)
    WwCR_constr.cycles = 1  # Make this consumer live a sequence of periods exactly once
    WwCR_constr.delFromTimeInv("BoroCnstArt")
    WwCR_constr.addToTimeVary("BoroCnstArt")
    WwCR_constr.BoroCnstArt = [
        None,
        None,
        in_BoroCnstArt,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
    ]
    WwCR_constr.solve()
    WwCR_constr.unpack("cFunc")

    WwCR_constr_risk = IndShockConsumerType(**init_lifecycle_risk2)
    WwCR_constr_risk.delFromTimeInv("BoroCnstArt")
    WwCR_constr_risk.addToTimeVary("BoroCnstArt")
    WwCR_constr_risk.BoroCnstArt = [
        None,
        None,
        in_BoroCnstArt,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
    ]
    WwCR_constr_risk.solve()
    WwCR_constr_risk.unpack("cFunc")

    x = np.linspace(-8, -4, 1000, endpoint=True)
    y = WwCR_unconstr.cFunc[1](x)
    y2 = WwCR_risk.cFunc[1](x)
    y3 = WwCR_constr.cFunc[1](x)
    y4 = WwCR_constr_risk.cFunc[1](x)

    where_close = np.isclose(y, y3, atol=1e-05)
    where_close_risk = np.isclose(y2, y4, atol=1e-05)
    x0 = x[where_close][0]
    x1 = x[where_close_risk][0]
    y0 = y[where_close][0]
    y1 = y2[where_close_risk][0]

    # Display the figure
    # print('Figure 3: Consumption Functions With and Without a Constraint and a Risk')

    f = plt.figure()
    plt.plot(x, y, color="black", linewidth=3, label="${c}_{t,0}$")
    plt.plot(
        x, y2, color="black", linestyle="--", linewidth=3, label=r"$\tilde{c}_{t,0}$"
    )
    plt.plot(x, y3, color="red", label="${c}_{t,1}$")
    plt.plot(x, y4, color="red", linestyle="--", label=r"$\tilde{c}_{t,1}$")
    plt.xlim(left=-8, right=-4.5)
    plt.ylim(0, 0.30)
    plt.text(-8.15, 0.305, "$c$", fontsize=14)
    plt.text(-4.5, -0.02, "$w$", fontsize=14)

    # plt.plot([-6.15,-6.15],[0,0.05],color="black",linestyle=":")
    plt.plot([x0, x0], [0, y0], color="black", linestyle=":")
    plt.plot([x1, x1], [0, y1], color="black", linestyle=":")

    # plt.text(-6.2,-0.02,r"$\underline{w}_{t,1}$",fontsize=14)
    plt.text(x0, -0.02, r"${w}_{t,1}$", fontsize=14)
    plt.text(x1, -0.02, r"$\bar{w}_{t,1}$", fontsize=14)

    plt.tick_params(
        labelbottom=False,
        labelleft=False,
        left="off",
        right="off",
        bottom="off",
        top="off",
    )
    plt.legend()
    plt.show()
    return None
Example #18
0
def make_concavification_figure(in_BoroCnstArt, in_UnempProb):
    """
    This figure illustrates how both risks and constraints are examples of counterclockwise concavifications.
    It plots three lines: the linear consumption function of a perfect foresight consumer, the kinked consumption
    function of a consumer who faces a constraint, and the curved consumption function of a consumer that faces risk.
    """

    # load the three agents: unconstrained perfect foresight, constrained perfect foresight, unconstrained with risk

    CCC_unconstr = IndShockConsumerType(**init_lifecycle)
    CCC_unconstr.delFromTimeInv("BoroCnstArt")
    CCC_unconstr.addToTimeVary("BoroCnstArt")
    CCC_unconstr.solve()
    CCC_unconstr.unpack("cFunc")

    CCC_constraint = IndShockConsumerType(**init_lifecycle)
    CCC_constraint.delFromTimeInv("BoroCnstArt")
    CCC_constraint.addToTimeVary("BoroCnstArt")
    CCC_constraint.BoroCnstArt = [
        None,
        in_BoroCnstArt,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
    ]
    CCC_constraint.solve()
    CCC_constraint.unpack("cFunc")

    init_lifecycle_risk1["UnempPrb"] = in_UnempProb

    CCC_risk = IndShockConsumerType(**init_lifecycle_risk1)
    CCC_risk.delFromTimeInv("BoroCnstArt")
    CCC_risk.addToTimeVary("BoroCnstArt")
    CCC_risk.solve()
    CCC_risk.unpack("cFunc")

    x = np.linspace(-1, 1, 500, endpoint=True)
    y = CCC_unconstr.cFunc[0](x)
    y2 = CCC_constraint.cFunc[0](x)
    y3 = CCC_risk.cFunc[0](x)

    where_close = np.isclose(y, y2, atol=1e-05)

    # Display the figure
    # print('Figure 1: Counterclockwise Concavifications')
    f = plt.figure()
    plt.plot(x, y, color="black")
    plt.plot(x, y2, color="green", label="Constraint", linestyle="--")
    plt.plot(x, y3, color="red", label="Risk", linestyle="--")
    plt.tick_params(
        labelbottom=False,
        labelleft=False,
        left="off",
        right="off",
        bottom="off",
        top="off",
    )

    if np.any(where_close):
        x0 = x[where_close][0]
        y0 = y[where_close][0]
        plt.text(x0 - 0.02, 0.42, "$w^{\#}$", fontsize=14)
        plt.plot([x0, x0], [0.45, y0], color="black", linestyle=":", linewidth=1)

    plt.text(-1.2, 1.0, "$c$", fontsize=14)
    plt.text(1.12, 0.42, "$w$", fontsize=14)
    plt.ylim(0.465, 1.0)

    plt.legend()
    plt.show()
    return None
LifecycleExample.solve()
print('First element of solution is', LifecycleExample.solution[0])
print('Solution has', len(LifecycleExample.solution), 'elements.')

# %% [markdown]
# This was supposed to be a *ten* period lifecycle model-- why does our consumer type have *eleven* elements in its $\texttt{solution}$?  It would be more precise to say that this specification has ten *non-terminal* periods. The solution to the 11th and final period in the model would be the same for every set of parameters: consume $c_t = m_t$, because there is no future.  In a lifecycle model, the terminal period is assumed to exist; the $\texttt{LivPrb}$ parameter does not need to end with a $0.0$ in order to guarantee that survivors die.
#
# We can quickly plot the consumption functions in each period of the model:

# %%
print('Consumption functions across the lifecycle:')
mMin = np.min([
    LifecycleExample.solution[t].mNrmMin
    for t in range(LifecycleExample.T_cycle)
])
LifecycleExample.unpack(
    'cFunc')  # This makes all of the cFuncs accessible in the attribute cFunc
plot_funcs(LifecycleExample.cFunc, mMin, 5)

# %% [markdown]
# ### "Cyclical" example
#
# We can also model consumers who face an infinite horizon, but who do *not* face the same problem in every period.  Consider someone who works as a ski instructor: they make most of their income for the year in the winter, and make very little money in the other three seasons.
#
# We can represent this type of individual as a four period, infinite horizon model in which expected "permanent" income growth varies greatly across seasons.

# %% {"code_folding": [0]}
CyclicalDict = {  # Click the arrow to expand this parameter dictionary
    # Parameters shared with the perfect foresight model
    "CRRA": 2.0,  # Coefficient of relative risk aversion
    "Rfree": 1.03,  # Interest factor on assets
    "DiscFac": 0.96,  # Intertemporal discount factor
Example #20
0
print("First element of solution is", LifecycleExample.solution[0])
print("Solution has", len(LifecycleExample.solution), "elements.")

# %% [markdown]
# This was supposed to be a *ten* period lifecycle model-- why does our consumer type have *eleven* elements in its $\texttt{solution}$?  It would be more precise to say that this specification has ten *non-terminal* periods. The solution to the 11th and final period in the model would be the same for every set of parameters: consume $c_t = m_t$, because there is no future.  In a lifecycle model, the terminal period is assumed to exist; the $\texttt{LivPrb}$ parameter does not need to end with a $0.0$ in order to guarantee that survivors die.
#
# We can quickly plot the consumption functions in each period of the model:

# %%
print("Consumption functions across the lifecycle:")
mMin = np.min([
    LifecycleExample.solution[t].mNrmMin
    for t in range(LifecycleExample.T_cycle)
])
# This makes all of the cFuncs accessible in the attribute cFunc
LifecycleExample.unpack("cFunc")
plotFuncs(LifecycleExample.cFunc, mMin, 5)

# %% [markdown]
# ### "Cyclical" example
#
# We can also model consumers who face an infinite horizon, but who do *not* face the same problem in every period.  Consider someone who works as a ski instructor: they make most of their income for the year in the winter, and make very little money in the other three seasons.
#
# We can represent this type of individual as a four period, infinite horizon model in which expected "permanent" income growth varies greatly across seasons.

# %% code_folding=[0]
CyclicalDict = {  # Click the arrow to expand this parameter dictionary
    # Parameters shared with the perfect foresight model
    "CRRA": 2.0,  # Coefficient of relative risk aversion
    "Rfree": 1.03,  # Interest factor on assets
    "DiscFac": 0.96,  # Intertemporal discount factor