{ "cells": [ { "cell_type": "markdown", "id": "429ad82a", "metadata": {}, "source": [ "$$\n", "\\newcommand{\\argmax}{arg\\,max}\n", "\\newcommand{\\argmin}{arg\\,min}\n", "\\newcommand{\\col}{col}\n", "\\newcommand{\\Span}{span}\n", "\\newcommand{\\epsilon}{\\varepsilon}\n", "\\newcommand{\\EE}{\\mathbb{E}}\n", "\\newcommand{\\PP}{\\mathbb{P}}\n", "\\newcommand{\\RR}{\\mathbb{R}}\n", "\\newcommand{\\NN}{\\mathbb{N}}\n", "\\newcommand{\\ZZ}{\\mathbb{Z}}\n", "\\newcommand{\\aA}{\\mathcal{A}}\n", "\\newcommand{\\bB}{\\mathcal{B}}\n", "\\newcommand{\\cC}{\\mathcal{C}}\n", "\\newcommand{\\dD}{\\mathcal{D}}\n", "\\newcommand{\\eE}{\\mathcal{E}}\n", "\\newcommand{\\fF}{\\mathcal{F}}\n", "\\newcommand{\\gG}{\\mathcal{G}}\n", "\\newcommand{\\hH}{\\mathcal{H}}\n", "$$" ] }, { "cell_type": "markdown", "id": "939604a2", "metadata": {}, "source": [ "\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "id": "61841373", "metadata": {}, "source": [ "# How to Pay for a War: Part 1" ] }, { "cell_type": "markdown", "id": "e0b1bd3d", "metadata": {}, "source": [ "## Overview\n", "\n", "This lecture uses the method of **Markov jump linear quadratic dynamic programming** that is described in lecture\n", "[Markov Jump LQ dynamic programming](https://python-advanced.quantecon.org/markov_jump_lq.html)\n", "to extend the [[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)] model of optimal tax-smoothing and government debt in a\n", "particular direction.\n", "\n", "This lecture has two sequels that offer further extensions of the Barro model\n", "\n", "1. [How to Pay for a War: Part 2](https://python-advanced.quantecon.org/tax_smoothing_2.html) \n", "1. [How to Pay for a War: Part 3](https://python-advanced.quantecon.org/tax_smoothing_3.html) \n", "\n", "\n", "The extensions are modified versions of\n", "his 1979 model suggested by [[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id242)] and [[Barro and McCleary, 2003](https://python-advanced.quantecon.org/zreferences.html#id243)]).\n", "\n", "[[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)] m is about a government that borrows and lends\n", "in order to minimize an intertemporal measure of distortions\n", "caused by taxes.\n", "\n", "Technical tractability induced [[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)] to assume that\n", "\n", "- the government trades only one-period risk-free debt, and \n", "- the one-period risk-free interest rate is constant \n", "\n", "\n", "By using *Markov jump linear quadratic dynamic\n", "programming* we can allow interest rates to move over time in\n", "empirically interesting ways.\n", "\n", "Also, by expanding the dimension of the\n", "state, we can add a maturity composition decision to the government’s\n", "problem.\n", "\n", "By doing these two things we extend [[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)]\n", "along lines he suggested in [[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id242)] and [[Barro and McCleary, 2003](https://python-advanced.quantecon.org/zreferences.html#id243)]).\n", "\n", "[[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)] assumed\n", "\n", "- that a government faces an **exogenous sequence** of expenditures\n", " that it must finance by a tax collection sequence whose expected\n", " present value equals the initial debt it owes plus the expected\n", " present value of those expenditures. \n", "- that the government wants to minimize a measure of tax\n", " distortions that is proportional to $ E_0 \\sum_{t=0}^{\\infty} \\beta^t T_t^2 $, where $ T_t $ are total tax collections and $ E_0 $\n", " is a mathematical expectation conditioned on time $ 0 $\n", " information. \n", "- that the government trades only one asset, a risk-free one-period\n", " bond. \n", "- that the gross interest rate on the one-period bond is constant and\n", " equal to $ \\beta^{-1} $, the reciprocal of the factor\n", " $ \\beta $ at which the government discounts future tax distortions. \n", "\n", "\n", "Barro’s model can be mapped into a discounted linear quadratic dynamic\n", "programming problem.\n", "\n", "Partly inspired by [[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id242)] and [[Barro and McCleary, 2003](https://python-advanced.quantecon.org/zreferences.html#id243)],\n", "our generalizations of [[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)], assume\n", "\n", "- that the government borrows or saves in the form of risk-free bonds\n", " of maturities $ 1, 2, \\ldots , H $. \n", "- that interest rates on those bonds are time-varying and in particular,\n", " governed by a jointly stationary stochastic process. \n", "\n", "\n", "Our generalizations are designed to fit within a generalization of an\n", "ordinary linear quadratic dynamic programming problem in which matrices\n", "that define the quadratic objective function and the state transition\n", "function are **time-varying** and **stochastic**.\n", "\n", "This generalization, known as a **Markov jump linear quadratic dynamic\n", "program**, combines\n", "\n", "- the computational simplicity of **linear quadratic dynamic\n", " programming**, and \n", "- the ability of **finite state Markov chains** to represent\n", " interesting patterns of random variation. \n", "\n", "\n", "We want the stochastic time variation in the matrices defining the\n", "dynamic programming problem to represent variation over time in\n", "\n", "- interest rates \n", "- default rates \n", "- roll over risks \n", "\n", "\n", "As described in [Markov Jump LQ dynamic programming](https://python-advanced.quantecon.org/markov_jump_lq.html),\n", "the idea underlying **Markov jump linear quadratic dynamic programming**\n", "is to replace the constant matrices defining a **linear quadratic\n", "dynamic programming problem** with matrices that are fixed functions of\n", "an $ N $ state Markov chain.\n", "\n", "For infinite horizon problems, this leads to $ N $ interrelated\n", "matrix Riccati equations that pin down $ N $ value functions and\n", "$ N $ linear decision rules, applying to the $ N $ Markov\n", "states." ] }, { "cell_type": "markdown", "id": "c29c51c1", "metadata": {}, "source": [ "## Public finance questions\n", "\n", "[[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)] is designed to answer questions such as\n", "\n", "- Should a government finance an exogenous surge in government\n", " expenditures by raising taxes or borrowing? \n", "- How does the answer to that first question depend on the exogenous\n", " stochastic process for government expenditures, for example, on\n", " whether the surge in government expenditures can be expected to be\n", " temporary or permanent? \n", "\n", "\n", "[[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id242)] and [[Barro and McCleary, 2003](https://python-advanced.quantecon.org/zreferences.html#id243)] are designed to answer more fine-grained\n", "questions such as\n", "\n", "- What determines whether a government wants to issue short-term or\n", " long-term debt? \n", "- How do roll-over risks affect that decision? \n", "- How does the government’s long-short *portfolio management* decision\n", " depend on features of the exogenous stochastic process for government\n", " expenditures? \n", "\n", "\n", "Thus, both the simple and the more fine-grained versions of Barro’s\n", "models are ways of precisely formulating the classic issue of *How to\n", "pay for a war*.\n", "\n", "This lecture describes:\n", "\n", "- An application of Markov jump LQ dynamic programming to a model in\n", " which a government faces exogenous time-varying interest rates for\n", " issuing one-period risk-free debt. \n", "\n", "\n", "A [sequel to this lecture](https://python-advanced.quantecon.org/tax_smoothing_2.html)\n", "describes applies Markov LQ control to settings in which a government\n", "issues risk-free debt of different maturities." ] }, { "cell_type": "code", "execution_count": null, "id": "c5883c9a", "metadata": { "hide-output": false }, "outputs": [], "source": [ "!pip install --upgrade quantecon" ] }, { "cell_type": "markdown", "id": "32a8ff59", "metadata": {}, "source": [ "Let’s start with some standard imports:" ] }, { "cell_type": "code", "execution_count": null, "id": "9955a6f2", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import quantecon as qe\n", "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "id": "be2a9d32", "metadata": {}, "source": [ "## Barro (1979) model\n", "\n", "We begin by solving a version of [[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)] by mapping it\n", "into the original LQ framework.\n", "\n", "As mentioned [in this lecture](https://python-intro.quantecon.org/perm_income_cons.html), the\n", "Barro model is mathematically isomorphic with the LQ permanent income\n", "model.\n", "\n", "Let\n", "\n", "- $ T_t $ denote tax collections \n", "- $ \\beta $ be a discount factor \n", "- $ b_{t,t+1} $ be time $ t+1 $ goods that at $ t $ the government promises to\n", " deliver to time $ t $ buyers of one-period government bonds \n", "- $ G_t $ be government purchases \n", "- $ p_{t,t+1} $ the number of time $ t $ goods received per time $ t+1 $ goods\n", " promised to one-period bond purchasers. \n", "\n", "\n", "Evidently, $ p_{t, t+1} $ is inversely related to\n", "appropriate corresponding gross interest rates on government debt.\n", "\n", "In the spirit of [[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id142)], the stochastic process of government\n", "expenditures is exogenous.\n", "\n", "The government’s problem is to choose a plan\n", "for taxation and borrowing $ \\{b_{t+1}, T_t\\}_{t=0}^\\infty $ to\n", "minimize\n", "\n", "$$\n", "E_0 \\sum_{t=0}^\\infty \\beta^t T_t^2\n", "$$\n", "\n", "subject to the constraints\n", "\n", "$$\n", "T_t + p_{t,t+1} b_{t,t+1} = G_t + b_{t-1,t}\n", "$$\n", "\n", "$$\n", "G_t = U_{g} z_t\n", "$$\n", "\n", "$$\n", "z_{t+1} = A_{22} z_t + C_{2} w_{t+1}\n", "$$\n", "\n", "where $ w_{t+1} \\sim {\\cal N}(0,I) $\n", "\n", "The variables\n", "$ T_t, b_{t, t+1} $ are *control* variables chosen at $ t $,\n", "while $ b_{t-1,t} $ is an endogenous state variable inherited from\n", "the past at time $ t $ and $ p_{t,t+1} $ is an exogenous state\n", "variable at time $ t $.\n", "\n", "To begin, we assume that\n", "$ p_{t,t+1} $ is constant (and equal to $ \\beta $)\n", "\n", "- later we will extend the model to allow $ p_{t,t+1} $ to vary over time \n", "\n", "\n", "To map into the LQ framework, we use\n", "$ x_t = \\begin{bmatrix} b_{t-1,t} \\\\ z_t \\end{bmatrix} $ as the\n", "state vector, and $ u_t = b_{t,t+1} $ as the control variable.\n", "\n", "Therefore, the $ (A, B, C) $ matrices are defined by the state-transition law:\n", "\n", "$$\n", "x_{t+1} = \\begin{bmatrix} 0 & 0 \\\\ 0 & A_{22} \\end{bmatrix} x_t + \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} u_t + \\begin{bmatrix} 0 \\\\ C_2 \\end{bmatrix} w_{t+1}\n", "$$\n", "\n", "To find the appropriate $ (R, Q, W) $ matrices, we note that $ G_t $ and\n", "$ b_{t-1,t} $ can be written as appropriately defined functions of\n", "the current state:\n", "\n", "$$\n", "G_t = S_G x_t \\hspace{2mm}, \\hspace{2mm} b_{t-1,t} = S_1 x_t\n", "$$\n", "\n", "If we define $ M_t = - p_{t,t+1} $, and let $ S = S_G + S_1 $, then\n", "we can write taxation as a function of the states and control using the\n", "government’s budget constraint:\n", "\n", "$$\n", "T_t = S x_t + M_t u_t\n", "$$\n", "\n", "It follows that the $ (R, Q, W) $ matrices are implicitly defined by:\n", "\n", "$$\n", "T_t^2 = x_t'S'Sx_t + u_t'M_t'M_tu_t + 2 u_t'M_t'S x_t\n", "$$\n", "\n", "If we assume that $ p_{t,t+1} = \\beta $, then $ M_t \\equiv M = -\\beta $.\n", "\n", "In this case, none of\n", "the LQ matrices are time varying, and we can use the original LQ\n", "framework.\n", "\n", "We will implement this constant interest-rate version first, assuming\n", "that $ G_t $ follows an AR(1) process:\n", "\n", "$$\n", "G_{t+1} = \\bar G + \\rho G_t + \\sigma w_{t+1}\n", "$$\n", "\n", "To do this, we set\n", "$ z_t = \\begin{bmatrix} 1 \\\\ G_t \\end{bmatrix} $, and consequently:\n", "\n", "$$\n", "A_{22} = \\begin{bmatrix} 1 & 0 \\\\ \\bar G & \\rho \\end{bmatrix} \\hspace{2mm} ,\n", "\\hspace{2mm} C_2 = \\begin{bmatrix} 0 \\\\ \\sigma \\end{bmatrix}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "id": "bc06e85d", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# Model parameters\n", "β, Gbar, ρ, σ = 0.95, 5, 0.8, 1\n", "\n", "# Basic model matrices\n", "A22 = np.array([[1, 0],\n", " [Gbar, ρ],])\n", "\n", "C2 = np.array([[0],\n", " [σ]])\n", "\n", "Ug = np.array([[0, 1]])\n", "\n", "# LQ framework matrices\n", "A_t = np.zeros((1, 3))\n", "A_b = np.hstack((np.zeros((2, 1)), A22))\n", "A = np.vstack((A_t, A_b))\n", "\n", "B = np.zeros((3, 1))\n", "B[0, 0] = 1\n", "\n", "C = np.vstack((np.zeros((1, 1)), C2))\n", "\n", "Sg = np.hstack((np.zeros((1, 1)), Ug))\n", "S1 = np.zeros((1, 3))\n", "S1[0, 0] = 1\n", "S = S1 + Sg\n", "\n", "M = np.array([[-β]])\n", "\n", "R = S.T @ S\n", "Q = M.T @ M\n", "W = M.T @ S\n", "\n", "# Small penalty on the debt required to implement the no-Ponzi scheme\n", "R[0, 0] = R[0, 0] + 1e-9" ] }, { "cell_type": "markdown", "id": "5cf1943d", "metadata": {}, "source": [ "We can now create an instance of `LQ`:" ] }, { "cell_type": "code", "execution_count": null, "id": "8e24b9f2", "metadata": { "hide-output": false }, "outputs": [], "source": [ "LQBarro = qe.LQ(Q, R, A, B, C=C, N=W, beta=β)\n", "P, F, d = LQBarro.stationary_values()\n", "x0 = np.array([[100, 1, 25]])" ] }, { "cell_type": "markdown", "id": "0b2af51f", "metadata": {}, "source": [ "We can see the isomorphism by noting that consumption is a martingale in\n", "the permanent income model and that taxation is a martingale in Barro’s\n", "model.\n", "\n", "We can check this using the $ F $ matrix of the LQ model.\n", "\n", "Because $ u_t = -F x_t $, we have\n", "\n", "$$\n", "T_t = S x_t + M u_t = (S - MF) x_t\n", "$$\n", "\n", "and\n", "\n", "$$\n", "T_{t+1} = (S-MF)x_{t+1} = (S-MF)(Ax_t + B u_t + C w_{t+1}) = (S-MF)((A-BF)x_t + C w_{t+1})\n", "$$\n", "\n", "Therefore, the mathematical expectation of $ T_{t+1} $ conditional on time\n", "$ t $ information is\n", "\n", "$$\n", "E_t T_{t+1} = (S-MF)(A-BF)x_t\n", "$$\n", "\n", "Consequently, taxation is a martingale ($ E_t T_{t+1} = T_t $) if\n", "\n", "$$\n", "(S-MF)(A-BF) = (S-MF) ,\n", "$$\n", "\n", "which holds in this case:" ] }, { "cell_type": "code", "execution_count": null, "id": "ad92cd25", "metadata": { "hide-output": false }, "outputs": [], "source": [ "S - M @ F, (S - M @ F) @ (A - B @ F)" ] }, { "cell_type": "markdown", "id": "d4e1def6", "metadata": {}, "source": [ "This explains the fanning out of the conditional empirical distribution of taxation across time, computed by simulating the\n", "Barro model many times and averaging over simulated paths:" ] }, { "cell_type": "code", "execution_count": null, "id": "91628a7c", "metadata": { "hide-output": false }, "outputs": [], "source": [ "T = 500\n", "for i in range(250):\n", " x, u, w = LQBarro.compute_sequence(x0, ts_length=T)\n", " plt.plot(list(range(T+1)), ((S - M @ F) @ x)[0, :])\n", "plt.xlabel('Time')\n", "plt.ylabel('Taxation')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "3351fd43", "metadata": {}, "source": [ "We can see a similar, but a smoother pattern, if we plot government debt\n", "over time." ] }, { "cell_type": "code", "execution_count": null, "id": "d709aead", "metadata": { "hide-output": false }, "outputs": [], "source": [ "T = 500\n", "for i in range(250):\n", " x, u, w = LQBarro.compute_sequence(x0, ts_length=T)\n", " plt.plot(list(range(T+1)), x[0, :])\n", "plt.xlabel('Time')\n", "plt.ylabel('Govt Debt')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "f3241c80", "metadata": {}, "source": [ "## Python class to solve Markov jump linear quadratic control problems\n", "\n", "To implement the extension to the Barro model in which $ p_{t,t+1} $\n", "varies over time, we must allow the M matrix to be time-varying.\n", "\n", "Our $ Q $ and $ W $ matrices must also vary over time.\n", "\n", "We can solve such a\n", "model using the `LQMarkov` class that solves Markov jump linear\n", "quandratic control problems as described above.\n", "\n", "The code for the class can be viewed\n", "[here](https://github.com/QuantEcon/QuantEcon.py/blob/master/quantecon/_lqcontrol.py).\n", "\n", "The class takes lists of matrices that corresponds to $ N $ Markov states.\n", "\n", "The value and policy functions are then found by iterating on a coupled system of matrix Riccati difference\n", "equations.\n", "\n", "Optimal $ P_s,F_s,d_s $ are stored as attributes.\n", "\n", "The class also contains a method that simulates a model." ] }, { "cell_type": "markdown", "id": "215c18e4", "metadata": {}, "source": [ "## Barro model with a time-varying interest rate\n", "\n", "We can use the above class to implement a version of the Barro model\n", "with a time-varying interest rate.\n", "\n", "A simple way to extend the model\n", "is to allow the interest rate to take two possible values.\n", "\n", "We set:\n", "\n", "$$\n", "p^1_{t,t+1} = \\beta + 0.02 = 0.97\n", "$$\n", "\n", "$$\n", "p^2_{t,t+1} = \\beta - 0.017 = 0.933\n", "$$\n", "\n", "Thus, the first Markov state has a low interest rate and the\n", "second Markov state has a high interest rate.\n", "\n", "We must also specify a transition matrix for the Markov state.\n", "\n", "We use:\n", "\n", "$$\n", "\\Pi = \\begin{bmatrix} 0.8 & 0.2 \\\\ 0.2 & 0.8 \\end{bmatrix}\n", "$$\n", "\n", "Here, each Markov state is persistent, and there is are equal chances\n", "of moving from one state to the other.\n", "\n", "The choice of parameters means that the unconditional expectation of\n", "$ p_{t,t+1} $ is 0.9515, higher than $ \\beta (=0.95) $.\n", "\n", "If we\n", "were to set $ p_{t,t+1} = 0.9515 $ in the version of the model with\n", "a constant interest rate, government debt would explode." ] }, { "cell_type": "code", "execution_count": null, "id": "119d159a", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# Create list of matrices that corresponds to each Markov state\n", "Π = np.array([[0.8, 0.2],\n", " [0.2, 0.8]])\n", "\n", "As = [A, A]\n", "Bs = [B, B]\n", "Cs = [C, C]\n", "Rs = [R, R]\n", "\n", "M1 = np.array([[-β - 0.02]])\n", "M2 = np.array([[-β + 0.017]])\n", "\n", "Q1 = M1.T @ M1\n", "Q2 = M2.T @ M2\n", "Qs = [Q1, Q2]\n", "W1 = M1.T @ S\n", "W2 = M2.T @ S\n", "Ws = [W1, W2]\n", "\n", "# create Markov Jump LQ DP problem instance\n", "lqm = qe.LQMarkov(Π, Qs, Rs, As, Bs, Cs=Cs, Ns=Ws, beta=β)\n", "lqm.stationary_values();" ] }, { "cell_type": "markdown", "id": "27f7d7c0", "metadata": {}, "source": [ "The decision rules are now dependent on the Markov state:" ] }, { "cell_type": "code", "execution_count": null, "id": "41bf3574", "metadata": { "hide-output": false }, "outputs": [], "source": [ "lqm.Fs[0]" ] }, { "cell_type": "code", "execution_count": null, "id": "c3c3f406", "metadata": { "hide-output": false }, "outputs": [], "source": [ "lqm.Fs[1]" ] }, { "cell_type": "markdown", "id": "d26d4572", "metadata": {}, "source": [ "Simulating a large number of such economies over time reveals\n", "interesting dynamics.\n", "\n", "Debt tends to stay low and stable but\n", "recurrently surges." ] }, { "cell_type": "code", "execution_count": null, "id": "d0f7d8e0", "metadata": { "hide-output": false }, "outputs": [], "source": [ "T = 2000\n", "x0 = np.array([[1000, 1, 25]])\n", "for i in range(250):\n", " x, u, w, s = lqm.compute_sequence(x0, ts_length=T)\n", " plt.plot(list(range(T+1)), x[0, :])\n", "plt.xlabel('Time')\n", "plt.ylabel('Govt Debt')\n", "plt.show()" ] } ], "metadata": { "date": 1769597376.1524727, "filename": "tax_smoothing_1.md", "kernelspec": { "display_name": "Python", "language": "python3", "name": "python3" }, "title": "How to Pay for a War: Part 1" }, "nbformat": 4, "nbformat_minor": 5 }