{ "cells": [ { "cell_type": "markdown", "id": "ca44cf8c", "metadata": {}, "source": [ "\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "id": "50406f91", "metadata": {}, "source": [ "# How to Pay for a War: Part 1" ] }, { "cell_type": "markdown", "id": "5f8568b2", "metadata": {}, "source": [ "## Contents\n", "\n", "- [How to Pay for a War: Part 1](#How-to-Pay-for-a-War:-Part-1) \n", " - [Reader’s Guide](#Reader’s-Guide) \n", " - [Public Finance Questions](#Public-Finance-Questions) \n", " - [Barro (1979) Model](#Barro-%281979%29-Model) \n", " - [Python Class to Solve Markov Jump Linear Quadratic Control Problems](#Python-Class-to-Solve-Markov-Jump-Linear-Quadratic-Control-Problems) \n", " - [Barro Model with a Time-varying Interest Rate](#Barro-Model-with-a-Time-varying-Interest-Rate) " ] }, { "cell_type": "markdown", "id": "b30104b2", "metadata": {}, "source": [ "In addition to what’s in Anaconda, this lecture will deploy quantecon:" ] }, { "cell_type": "code", "execution_count": null, "id": "97555482", "metadata": { "hide-output": false }, "outputs": [], "source": [ "!pip install --upgrade quantecon" ] }, { "cell_type": "markdown", "id": "345aa3de", "metadata": {}, "source": [ "## Reader’s Guide\n", "\n", "Let’s start with some standard imports:" ] }, { "cell_type": "code", "execution_count": null, "id": "8ddbf109", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import quantecon as qe\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "id": "0017d51e", "metadata": {}, "source": [ "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 [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)] 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 later suggested by Barro (1999 [[Bar99](https://python-advanced.quantecon.org/zreferences.html#id236)], 2003 [[BM03](https://python-advanced.quantecon.org/zreferences.html#id237)]).\n", "\n", "Barro’s original 1979 [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)] model 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 [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)] 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", "It is by doing these two things that we extend Barro’s 1979 [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)]\n", "model along lines he suggested in Barro (1999 [[Bar99](https://python-advanced.quantecon.org/zreferences.html#id236)], 2003 [[BM03](https://python-advanced.quantecon.org/zreferences.html#id237)]).\n", "\n", "Barro (1979) [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)] 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 the following measure of tax\n", " distortions: $ 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\n", "(1999) [[Bar99](https://python-advanced.quantecon.org/zreferences.html#id236)] and Barro (2003) [[BM03](https://python-advanced.quantecon.org/zreferences.html#id237)],\n", "our generalizations of Barro’s (1979) [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)] model 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": "40e63865", "metadata": {}, "source": [ "## Public Finance Questions\n", "\n", "Barro’s 1979 [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)] model 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’s 1999 [[Bar99](https://python-advanced.quantecon.org/zreferences.html#id236)] and 2003 [[BM03](https://python-advanced.quantecon.org/zreferences.html#id237)]\n", "models 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": "markdown", "id": "7cbcce61", "metadata": {}, "source": [ "## Barro (1979) Model\n", "\n", "We begin by solving a version of the Barro (1979) [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)] model 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 $ T_t $ denote tax collections, $ \\beta $ a discount factor,\n", "$ b_{t,t+1} $ time $ t+1 $ goods that the government promises to\n", "pay at $ t $, $ G_t $ government purchases, $ p_{t,t+1} $\n", "the number of time $ t $ goods received per time $ t+1 $ goods\n", "promised.\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) [[Bar79](https://python-advanced.quantecon.org/zreferences.html#id136)], 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": "b6566a5d", "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": "c1189b97", "metadata": {}, "source": [ "We can now create an instance of `LQ`:" ] }, { "cell_type": "code", "execution_count": null, "id": "db3e0e32", "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": "41d01683", "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": "00071615", "metadata": { "hide-output": false }, "outputs": [], "source": [ "S - M @ F, (S - M @ F) @ (A - B @ F)" ] }, { "cell_type": "markdown", "id": "e8e0eb26", "metadata": {}, "source": [ "This explains the fanning out of the conditional empirical distribution of taxation across time, computing\n", "by simulation the\n", "Barro model a large number of times:" ] }, { "cell_type": "code", "execution_count": null, "id": "e9ee2203", "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": "5823af3a", "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": "13aff0c0", "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": "558db6f6", "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” for simulating the model." ] }, { "cell_type": "markdown", "id": "d6d703c2", "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. The simplest way to extend the model\n", "is to allow the interest rate to take two possible values. 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 also need to 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", "(so each Markov state is persistent, and there is an equal chance\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": "e56c2435", "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": "13524548", "metadata": {}, "source": [ "The decision rules are now dependent on the Markov state:" ] }, { "cell_type": "code", "execution_count": null, "id": "907c10d5", "metadata": { "hide-output": false }, "outputs": [], "source": [ "lqm.Fs[0]" ] }, { "cell_type": "code", "execution_count": null, "id": "90bf793f", "metadata": { "hide-output": false }, "outputs": [], "source": [ "lqm.Fs[1]" ] }, { "cell_type": "markdown", "id": "f5acec83", "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": "b175a757", "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": 1705369587.656913, "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 }