{
"cells": [
{
"cell_type": "markdown",
"id": "9aa0fb1d",
"metadata": {},
"source": [
"\n",
"\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"id": "6c69185c",
"metadata": {},
"source": [
"# How to Pay for a War: Part 1\n",
"\n",
"In addition to what’s in Anaconda, this lecture will deploy quantecon:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8cb70e42",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"!pip install --upgrade quantecon"
]
},
{
"cell_type": "markdown",
"id": "c0ec1c11",
"metadata": {},
"source": [
"## Reader’s Guide\n",
"\n",
"Let’s start with some standard imports:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dcea766c",
"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": "e8459035",
"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 [[Barro, 1979](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 [[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id236)], 2003 [[Barro and McCleary, 2003](https://python-advanced.quantecon.org/zreferences.html#id237)]).\n",
"\n",
"Barro’s original 1979 [[Barro, 1979](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 [[Barro, 1979](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 [[Barro, 1979](https://python-advanced.quantecon.org/zreferences.html#id136)]\n",
"model along lines he suggested in Barro (1999 [[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id236)], 2003 [[Barro and McCleary, 2003](https://python-advanced.quantecon.org/zreferences.html#id237)]).\n",
"\n",
"Barro (1979) [[Barro, 1979](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) [[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id236)] and Barro (2003) [[Barro and McCleary, 2003](https://python-advanced.quantecon.org/zreferences.html#id237)],\n",
"our generalizations of Barro’s (1979) [[Barro, 1979](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": "0dbcd868",
"metadata": {},
"source": [
"## Public Finance Questions\n",
"\n",
"Barro’s 1979 [[Barro, 1979](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 [[Barro, 1999](https://python-advanced.quantecon.org/zreferences.html#id236)] and 2003 [[Barro and McCleary, 2003](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": "9dbc3899",
"metadata": {},
"source": [
"## Barro (1979) Model\n",
"\n",
"We begin by solving a version of the Barro (1979) [[Barro, 1979](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) [[Barro, 1979](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": "f7be7991",
"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": "9aad1a9d",
"metadata": {},
"source": [
"We can now create an instance of `LQ`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b09212f4",
"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": "d7860354",
"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": "f2dbebd9",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"S - M @ F, (S - M @ F) @ (A - B @ F)"
]
},
{
"cell_type": "markdown",
"id": "758e1048",
"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": "4ff2dcfb",
"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": "5fb35d6a",
"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": "5fbcfaa2",
"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": "ae9a469a",
"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": "845883ea",
"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": "2b184e0d",
"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": "c012c61f",
"metadata": {},
"source": [
"The decision rules are now dependent on the Markov state:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e48a7587",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"lqm.Fs[0]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "090134fc",
"metadata": {
"hide-output": false
},
"outputs": [],
"source": [
"lqm.Fs[1]"
]
},
{
"cell_type": "markdown",
"id": "c0b1a9ee",
"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": "1465d977",
"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": 1724218396.1672735,
"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
}