Skip to content

Commit

Permalink
Merge pull request #104 from ccjeremylo/102-hull-white-analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
ccjeremylo committed Nov 22, 2023
2 parents bf2c28c + acd28a2 commit 430bd1a
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 47 deletions.
150 changes: 108 additions & 42 deletions src/python/Lecture6/hull_white_model.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"\n",
"The Hull White short rate model is defined as:\n",
"\\begin{align}\n",
"dr_t = k (\\theta(t) - r_t) \\, dt + \\sigma(t) \\, dW_t\n",
"dr_t = k \\big( \\theta(t) - r_t \\big) \\, dt + \\sigma(t) \\, dW_t\n",
"\\end{align}\n",
"i.e. it is identical to the Vasicek model, but the long term mean $\\theta(t)$ and short rate vol $\\sigma(t)$ are now functions of time. \n",
"\n",
Expand All @@ -59,14 +59,14 @@
"id": "f3d60e42-30e4-493a-b9e7-799b68d13068",
"metadata": {},
"source": [
"The HW model implied ZCB pricing derivation follows almost exactly as the that of the Vasicek model. Let $X_t \\equiv \\int_t^T r_u \\, du$, then the ZCB price at time $t$ is given as:\n",
"The HW model implied ZCB price derivation follows almost exactly as that of the Vasicek model. Let $X_t \\equiv \\int_t^T r_u \\, du$, then the ZCB price at time $t$ is given as:\n",
"\\begin{align}\n",
"B(t, T) &= \\mathbb{E}^{\\mathbb{Q}}_t \\big[\\exp \\big( -X_t \\big) \\big] \\\\\n",
" &= \\exp \\bigg( -\\mathbb{E}^{\\mathbb{Q}}_t[X_t] + \\frac{1}{2} \\mathbb{V}ar[X_t] \\bigg)\n",
"\\end{align}\n",
"with the mean and variance of $X_t \\equiv \\int_t^T r_u \\, du$ given as\n",
"\\begin{align}\n",
"\\mathbb{E} [X_t] &= r_t \\, G(t, T \\,|\\, k) + \\int_t^T \\tilde{\\theta}(u) \\, G(u, T \\,|\\, k) \\, du \\\\\n",
"\\mathbb{E} [X_t] &= r_t \\, G(t, T) + \\int_t^T \\tilde{\\theta}(u) \\, G(u, T) \\, du \\\\\n",
"\\mathbb{V}ar [X_T] &= \\int_t^T \\sigma^2(u) \\, G^2(u, T \\,|\\, k) \\, du\n",
"\\end{align}\n",
"where the $G(0, T \\,|\\, k)$ is the same as the one used in the Vasicek analysis:\n",
Expand All @@ -76,10 +76,10 @@
"\\end{align}\n",
"Putting everything together, the HW implied ZCB is given as\n",
"\\begin{align}\n",
"\\boxed{B(t,T) = \\exp \\bigg( -r_t \\, G(t,T \\,|\\, k) - \\int_t^T \\tilde{\\theta}(u) \\, G(u,T \\,|\\, k) \\, du + \\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T \\,|\\, k) \\, du \\bigg)}\n",
"\\boxed{B(t,T) = \\exp \\bigg( -r_t \\, G(t,T) - \\int_t^T \\tilde{\\theta}(u) \\, G(u,T) \\, du + \\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du \\bigg)}\n",
"\\end{align}\n",
"\n",
"The goal here is to extract $\\tilde{\\theta}(u)$ and calibrate it such that it fits the initial discount curve $T \\mapsto B(0,T)$ exactly. We shall proceed by assuming constant short rate vol $\\sigma$."
"The goal here is to extract $\\tilde{\\theta}(u)$ and calibrate it such that it fits the initial discount curve $T \\mapsto B(0,T)$ exactly. We shall proceed by assuming a known (calibrated) short rate vol $\\sigma$."
]
},
{
Expand All @@ -92,23 +92,59 @@
},
{
"cell_type": "markdown",
"id": "9bf6dacc-dac9-410b-b7b3-2060f76beaa4",
"id": "d8a464db-8664-4fe0-9795-2c6f46ba2d45",
"metadata": {},
"source": [
"In order to calibrate $\\tilde{\\theta}(u)$ to the day-0 discount curve, we need to be able to express the second integral $\\int_t^T \\tilde{\\theta}(u) \\, G(u,T \\,|\\, k) \\, du$ with day-0 market quantities. To start, we have\n",
"$\\tilde{\\theta}(u)$ can be calibrated numerically using the day-0 discount curve, $T \\mapsto B(0,T)$:\n",
"\n",
"\\begin{align}\n",
"\\ln B(0,T) &= -r_0 \\, G(0,T) - \\int_0^T \\tilde{\\theta}(u) \\, G(u,T) \\, du + \\frac{1}{2} \\int_0^T \\sigma^2(u) \\, G^2(u,T) \\, du \\\\\n",
"\\ln B(0,t) &= -r_0 \\, G(0,t) - \\int_0^t \\tilde{\\theta}(u) \\, G(u,t) \\, du + \\frac{1}{2} \\int_0^t \\sigma^2(u) \\, G^2(u,t) \\, du \n",
"B(0,T) = \\exp \\bigg( -r_0 \\, G(0,T \\,|\\, k) - \\int_0^T \\tilde{\\theta}(u) \\, G(u,T \\,|\\, k) \\, du + \\frac{1}{2} \\int_0^T \\sigma^2(u) \\, G^2(u,T \\,|\\, k) \\, du \\bigg)\n",
"\\end{align}\n",
"\n",
"\\begin{align}\n",
"\\implies \\int_0^T \\tilde{\\theta}(u) \\, G(u,T \\,|\\, k) \\, du = -\\ln B(0,T) + \\frac{1}{2} \\int_0^T \\sigma^2(u) \\, G^2(u,T \\,|\\, k) \\, du - r_0 \\, G(0,T \\,|\\, k) \n",
"\\end{align}\n",
"\n",
"Taking the difference of the two equations will give us the term $\\int_t^T \\tilde{\\theta}(u) \\, G(u,T \\,|\\, k) \\, du$. Specifically, we look at the difference between the second term (first integral) in the equations above:\n",
"If we assume piecewise constant $\\tilde{\\theta}(u)$, then:\n",
"\\begin{align}\n",
"& \\;\\;\\;\\;\\;\\; \\int_0^T \\tilde{\\theta}(u) \\, G(u,T) \\, du - \\int_0^t \\tilde{\\theta}(u) \\, G(u,t) \\, du \\\\\n",
"&= \n",
"\\sum_{i=1}^{N-1} \\bigg( \\tilde{\\theta}(t_{i}) \\int_{t_{i}}^{t_{i+1}} G(u,T \\,|\\, k) \\, du\\bigg) = -\\ln B(0,T) + \\frac{1}{2} \\int_0^T \\sigma^2(u) \\, G^2(u,T \\,|\\, k) \\, du - r_0 \\, G(0,T \\,|\\, k) \n",
"\\end{align}\n",
"where $t_0=0$ and $t_N=T$. The function $\\tilde{\\theta}(u)$ can now be bootstrapped using the day-0 discount curve, $T \\mapsto B(0,T)$."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e9df4dc6-96f4-46e6-a040-0981dd774d3c",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "9bf6dacc-dac9-410b-b7b3-2060f76beaa4",
"metadata": {},
"source": [
"We are also interested in calibrating $\\tilde{\\theta}(u)$ analytically. More directly, we aim to express the integral $\\int_t^T \\tilde{\\theta}(u) \\, G(u,T) \\, du$ as a function of day-0 market quantities. To start, we have\n",
"\n",
"\\begin{align}\n",
"\\ln B(0,T) &= -r_0 \\, G(0,T) - \\int_0^T \\tilde{\\theta}(u) \\, G(u,T) \\, du + \\frac{1}{2} \\int_0^T \\sigma^2(u) \\, G^2(u,T) \\, du \\\\\n",
"\\ln B(0,t) &= -r_0 \\, G(0,t) - \\underbrace{\\int_0^t \\tilde{\\theta}(u) \\, G(u,t) \\, du}_{\\color{red}{\\text{A}}} + \\underbrace{\\frac{1}{2} \\int_0^t \\sigma^2(u) \\, G^2(u,t) \\, du}_{\\color{blue}{\\text{B}}}\n",
"\\end{align}"
]
},
{
"cell_type": "markdown",
"id": "16bc08f3-3528-40f5-8146-56619cfb43fa",
"metadata": {},
"source": [
"Taking the difference of the two equations will give us the term we wanted: $\\int_t^T \\tilde{\\theta}(u) \\, G(u,T) \\, du$. Specifically focusing on the second terms ($\\color{red}{\\text{A}}$), we have:\n",
"\\begin{align}\n",
"&\\int_0^T \\tilde{\\theta}(u) \\, G(u,T) \\, du - \\int_0^t \\tilde{\\theta}(u) \\, G(u,t) \\, du \\\\\n",
"&\\;\\;\\;\\;\\;\\;\\; = \n",
"\\int_t^T \\tilde{\\theta}(u) \\, G(u,T) \\, du + \\int_0^t \\tilde{\\theta}(u) \\, \\big( \\underbrace{G(u,T ) - G(u,t)}_{\\partial_t G(u,t) \\, G(t,T)} \\big) \\, du \\\\\n",
"&=\n",
"\\int_t^T \\tilde{\\theta}(u) \\, G(u,T) \\, du + G(t,T) \\int_0^t \\tilde{\\theta}(u) \\, \\partial_t G(u,t) \\, du\n",
"&\\;\\;\\;\\;\\;\\;\\; =\n",
"\\underbrace{\\int_t^T \\tilde{\\theta}(u) \\, G(u,T) \\, du}_{\\text{what we want}} + \\underbrace{G(t,T) \\int_0^t \\tilde{\\theta}(u) \\, \\partial_t G(u,t) \\, du}_{\\text{extra term}}\n",
"\\end{align}\n",
"\n",
"The extra term $G(t,T) \\int_0^t \\tilde{\\theta}(u) \\, \\partial_t G(u,t) \\, du$ can be eliminated by noting that:\n",
Expand All @@ -125,43 +161,73 @@
},
{
"cell_type": "markdown",
"id": "399e561b-9906-4f0d-9712-824c95a9f8ba",
"id": "3200ddf9-8325-4811-8efe-5a62635633a2",
"metadata": {},
"source": [
"tbc..."
"Focusing on the third terms ($\\color{blue}{\\text{B}}$), we have:\n",
"\\begin{align}\n",
"&\\frac{1}{2} \\int_0^T \\sigma^2(u) \\, G^2(u,T) \\, du - \\frac{1}{2} \\int_0^t \\sigma^2(u) \\, G^2(u,t) \\, du \\\\\n",
"&\\;\\;\\;\\;\\;\\;\\; = \n",
"\\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du + \\frac{1}{2} \\int_0^t \\sigma^2(u) \\big( G^2(u,T) - G^2(u,t) \\big) \\, du \\\\\n",
"&\\;\\;\\;\\;\\;\\;\\; = \n",
"\\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du + \\frac{1}{2} \\int_0^t \\sigma^2(u) \\partial_t G(u,t) G(t,T) \\bigg( G(u,T) + G(u,t) \\bigg) \\, du \\\\\n",
"&\\;\\;\\;\\;\\;\\;\\; = \n",
"\\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du + G(t,T) \\int_0^t \\sigma^2(u) \\, G(u,t) \\, \\partial_t G(u,t) \\, du + \\frac{1}{2} G^2(t,T) \\int_0^t \\sigma^2(u) \\, \\partial_t G^2(u,t) \\, du\n",
"\\end{align}\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "df1b2534-0bc0-4167-a9b8-d73d099562d1",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "2b4bb982-d31e-4b51-ae2d-ff3bf12829a0",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "b435487e-a19e-46f1-8b9c-d8dc8c763f83",
"cell_type": "markdown",
"id": "e6c7c274-c026-4e53-be95-fe06e76b003f",
"metadata": {},
"outputs": [],
"source": []
"source": [
"Putting everything together, we have $\\ln B(0,T) - \\ln B(0,t)$ given as:\n",
"\\begin{align}\n",
"\\ln \\frac{B(0,T)}{B(0,t)} \n",
"&= - \\underbrace{\\int_t^T \\tilde{\\theta}(u) G(u,T) \\, du}_{\\text{what we want (from ($\\color{red}{\\text{A}}$))}} \\\\\n",
"& \\;\\;\\;\\;\\;\\;\\; \\underbrace{-f(0,t) G(t,T) + r_0 \\big(G(0,T) - G(0,t)\\big) - G(t,T) \\int_0^t \\sigma^2 G(u, t) \\, \\partial_t G(u,t) \\, du}_{\\text{eliminating extra term (from ($\\color{red}{\\text{A}}$))}} \\\\\n",
"& \\;\\;\\;\\;\\;\\;\\; + \\underbrace{\\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du + G(t,T) \\int_0^t \\sigma^2(u) \\, G(u,t) \\, \\partial_t G(u,t) \\, du + \\frac{1}{2} G^2(t,T) \\int_0^t \\sigma^2(u) \\, \\partial_t G^2(u,t) \\, du}_{\\text{from ($\\color{blue}{\\text{B}}$)}} \\\\\n",
"&= -f(0,t) G(t,T) \n",
"+ r_0 \\big(G(0,T) - G(0,t)\\big)\n",
"-\\underbrace{\\int_t^T \\tilde{\\theta}(u) G(u,T) \\, du}_{\\text{what we want}}\n",
"+ \\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du\n",
"+ \\frac{1}{2} G^2(t,T) \\int_0^t \\sigma^2(u) \\, \\partial_t G^2(u,t) \\, du\n",
"\\end{align}\n",
"Rearranging, we now have an analytical expression of the integral $\\int_t^T \\tilde{\\theta}(u) G(u,T) \\, du$ in terms of day-0 market quantities:\n",
"\\begin{align}\n",
"\\implies\n",
"\\underbrace{\\int_t^T \\tilde{\\theta}(u) G(u,T) \\, du}_{\\text{what we want}}\n",
"= -\\ln \\frac{B(0,T)}{B(0,t)}\n",
"-f(0,t) G(t,T) \n",
"+ r_0 \\big(G(0,T) - G(0,t)\\big)\n",
"+ \\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du\n",
"+ \\frac{1}{2} G^2(t,T) \\int_0^t \\sigma^2(u) \\, \\partial_t G^2(u,t) \\, du \n",
"\\end{align}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d8de3273-03ba-4c73-bf5d-9b265c389a52",
"cell_type": "markdown",
"id": "3aac081d-5c31-456b-8749-b5a03f22efa7",
"metadata": {},
"outputs": [],
"source": []
"source": [
"Putting everything back into our HW ZCB equation:\n",
"\\begin{align}\n",
"B(t,T) = \\exp \\bigg( -r_t \\, G(t,T) - \\int_t^T \\tilde{\\theta}(u) \\, G(u,T) \\, du + \\frac{1}{2} \\int_t^T \\sigma^2(u) \\, G^2(u,T) \\, du \\bigg)\n",
"\\end{align}\n",
"We now have\n",
"\\begin{align}\n",
"B(t,T) = \n",
"\\frac{B(0,T)}{B(0,t)} \\, \n",
"\\exp \\bigg( -r_t \\, G(t,T) + f(0,t) \\, G(t,T) - \\underbrace{r_0 \\big(G(0,T) - G(0,t)\\big)}_{\\text{where?!}} - \\frac{1}{2} G^2(t,T) \\int_0^t \\sigma^2(u) \\, \\partial_t G^2(u,t) \\, du \\bigg)\n",
"\\end{align}\n",
"Tidying up, we have\n",
"\\begin{align}\n",
"\\boxed{B(t,T) = \n",
"\\frac{B(0,T)}{B(0,t)} \\, \n",
"\\exp \\bigg( -\\underbrace{\\big(r_t - f(0,t) \\big)}_{x_t} \\, G(t,T) - \\frac{1}{2} G^2(t,T) \\underbrace{\\int_0^t \\sigma^2(u) \\, \\partial_t G^2(u,t) \\, du}_{y_t} \\,\\bigg)}\n",
"\\end{align}\n",
"where $\\partial_t G^2(u,t) = \\exp \\big( -2k (t-u) \\big)$."
]
},
{
"cell_type": "code",
Expand Down
10 changes: 5 additions & 5 deletions src/python/Lecture6/short_rate_model_dynamics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@
"\n",
"The Merton short rate model is defined by the SDE:\n",
"\\begin{align}\n",
"dr_t = \\theta dt + \\sigma dW_t\n",
"dr_t = \\mu dt + \\sigma dW_t\n",
"\\end{align}\n",
"Solving the SDE (simply integrating both sides), we get\n",
"\\begin{align}\n",
"\\boxed{r_s = r_t + \\theta (s-t) + \\sigma (W_s - W_t)}\n",
"\\boxed{r_s = r_t + \\mu (s-t) + \\sigma (W_s - W_t)}\n",
"\\end{align}"
]
},
Expand Down Expand Up @@ -203,10 +203,10 @@
"\n",
"### Merton:\n",
"\\begin{align}\n",
"\\mathbb{E} [r_t] &= r_0 + \\theta t \\\\\n",
"\\mathbb{E} [r_t] &= r_0 + \\mu t \\\\\n",
"\\mathbb{V}ar [r_t] &= \\sigma^2 t\n",
"\\end{align}\n",
"We can see that both the mean and variance grows linearly in time for the Merton model.\n",
"We can see that both the mean and variance grow linearly in time for the Merton model.\n",
"\n",
"### Vasicek:\n",
"\\begin{align}\n",
Expand Down Expand Up @@ -333,7 +333,7 @@
"source": [
"### Merton:\n",
"\\begin{align}\n",
"\\mathbb{E} [X_T] &= -r_0 T - \\frac{1}{2} \\theta T^2 \\\\\n",
"\\mathbb{E} [X_T] &= -r_0 T - \\frac{1}{2} \\mu T^2 \\\\\n",
"\\mathbb{V}ar [X_T] &= \\frac{1}{3} \\sigma^2 T^3 \\\\\n",
"\\end{align}\n",
"\\begin{align}\n",
Expand Down

0 comments on commit 430bd1a

Please sign in to comment.