├── README.md ├── interest-rate-models ├── jupyter_import.py └── Hull-White-1f.ipynb └── yieldcurve └── nelson-siegel-svensson.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # Interesting Rates Code 2 | 3 | *Thomas Viehmann * 4 | 5 | In this repository I collect sample code around topics in financial 6 | and risk modelling and interest rates in particular. 7 | 8 | I mainly use [Jupyter](http://jupyter.org/) notebooks and [pytorch](http://pytorch.org/). 9 | 10 | Highlights: 11 | 12 | # Interest-Rate-Models 13 | - A [one-factor CIR++ model (Cox-Ingersoll-Ross plus shift extension)](interest-rate-models/CIR.ipynb) 14 | - A [one-factor Hull-White model](interest-rate-models/Hull-White-1f.ipynb) 15 | 16 | # Yield-Curve 17 | - A [small notebook on the Nelson-Siegel-Svensson method](yieldcurve/nelson-siegel-svensson.ipynb) 18 | 19 | #### The fine print 20 | 21 | Note that these models are provided for educational and informative 22 | purposes only. I shall not be liable for any (mis-) behaviour, 23 | mathematical mistakes, bugs or other. 24 | 25 | I have written them in my spare time / vacation and they do not 26 | reflect work or opinions of my employer. -------------------------------------------------------------------------------- /interest-rate-models/jupyter_import.py: -------------------------------------------------------------------------------- 1 | # The main idea is to define a %lib magic and then only import cells which contain %lib on import 2 | # this allows to mix the module code with illustrative examples of its use. 3 | # The above modification by Thomas Viehmann 4 | # mostly taken from https://github.com/jupyter/notebook/blob/master/docs/source/examples/Notebook/Importing%20Notebooks.ipynb 5 | # Copyright (c) 2001-2017, IPython Development Team 6 | # Copyright (c) 2015-, Jupyter Development Team 7 | # All rights reserved. 8 | # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | # Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer 11 | # in the documentation and/or other materials provided with the distribution. 12 | # Neither the name of the Jupyter Development Team nor the names of its contributors 13 | # may be used to endorse or promote products derived from this software without specific prior written permission. 14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 | # IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 | # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 | # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 22 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 23 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | 26 | import io, os, sys, types 27 | 28 | from IPython import get_ipython 29 | from nbformat import read 30 | from IPython.core.interactiveshell import InteractiveShell 31 | 32 | def find_notebook(fullname, path=None): 33 | """find a notebook, given its fully qualified name and an optional path 34 | 35 | This turns "foo.bar" into "foo/bar.ipynb" 36 | and tries turning "Foo_Bar" into "Foo Bar" if Foo_Bar 37 | does not exist. 38 | """ 39 | name = fullname.rsplit('.', 1)[-1] 40 | if not path: 41 | path = [''] 42 | for d in path: 43 | nb_path = os.path.join(d, name + ".ipynb") 44 | if os.path.isfile(nb_path): 45 | return nb_path 46 | # let import Notebook_Name find "Notebook Name.ipynb" 47 | nb_path = nb_path.replace("_", " ") 48 | if os.path.isfile(nb_path): 49 | return nb_path 50 | 51 | class NotebookLoader(object): 52 | """Module Loader for Jupyter Notebooks""" 53 | def __init__(self, path=None): 54 | self.shell = InteractiveShell.instance() 55 | self.path = path 56 | 57 | def load_module(self, fullname): 58 | """import a notebook as a module""" 59 | path = find_notebook(fullname, self.path) 60 | 61 | #print ("importing Jupyter notebook from %s" % path) 62 | 63 | # load the notebook object 64 | with io.open(path, 'r', encoding='utf-8') as f: 65 | nb = read(f, 4) 66 | 67 | 68 | # create the module and add it to sys.modules 69 | # if name in sys.modules: 70 | # return sys.modules[name] 71 | mod = types.ModuleType(fullname) 72 | mod.__file__ = path 73 | mod.__loader__ = self 74 | mod.__dict__['get_ipython'] = get_ipython 75 | sys.modules[fullname] = mod 76 | 77 | # extra work to ensure that magics that would affect the user_ns 78 | # actually affect the notebook module's ns 79 | save_user_ns = self.shell.user_ns 80 | self.shell.user_ns = mod.__dict__ 81 | 82 | try: 83 | for cell in nb.cells: 84 | if cell.cell_type == 'code': 85 | # transform the input to executable Python 86 | code = self.shell.input_transformer_manager.transform_cell(cell.source) 87 | if "get_ipython().magic('lib')" in code: 88 | # run the code in themodule 89 | exec(code, mod.__dict__) 90 | finally: 91 | self.shell.user_ns = save_user_ns 92 | return mod 93 | 94 | class NotebookFinder(object): 95 | """Module finder that locates Jupyter Notebooks""" 96 | def __init__(self): 97 | self.loaders = {} 98 | 99 | def find_module(self, fullname, path=None): 100 | nb_path = find_notebook(fullname, path) 101 | if not nb_path: 102 | return 103 | 104 | key = path 105 | if path: 106 | # lists aren't hashable 107 | key = os.path.sep.join(path) 108 | 109 | if key not in self.loaders: 110 | self.loaders[key] = NotebookLoader(path) 111 | return self.loaders[key] 112 | 113 | 114 | sys.meta_path.append(NotebookFinder()) 115 | 116 | from IPython.core.magic import (register_line_magic, register_cell_magic, 117 | register_line_cell_magic) 118 | 119 | @register_line_magic 120 | def lib(line): 121 | "lib highlighter" 122 | return line 123 | 124 | -------------------------------------------------------------------------------- /interest-rate-models/Hull-White-1f.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "cell_id": "42B4C8D85B1B4E74932E71A47B6AAAA8" 7 | }, 8 | "source": [ 9 | "# One Factor Hull-White model in PyTorch\n", 10 | "Thomas Viehmann, \n", 11 | "\n", 12 | "In this notebook, we are implementing the [Hull-White model](https://en.wikipedia.org/wiki/Hull-White_model) in the formulation given by Brigo and Mercurio [On Deterministic Shift Extensions of Short Rate Models](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=292060) in PyTorch.\n", 13 | "\n", 14 | "Thus we implement three things:\n", 15 | "- A special case of the one-factor Vasicek model including pricing of zero-coupon bond options.\n", 16 | "- The shift extension from this Vasicek model to the Hull-White-Model.\n", 17 | "- Swaption pricing using [Jamshidian's decomposition](https://en.wikipedia.org/wiki/Jamshidian's_trick) in the one-factor model\n", 18 | "\n", 19 | "The last two parts can be shared between the Hull-White model and the CIR++ proposed by Brigo and Mercurio (though there are minute differences to the [CIR notebook's version](CIR.ipynb)).\n", 20 | "\n", 21 | "And we would like many things, in particular swaption prices, to be differentiable by the model parameters in order to do calibration.\n", 22 | "The Hull-White model is given by the stochastic differential equation\n", 23 | "$$\n", 24 | "dr_t = \\alpha (\\mu(t)-r_t) dt + \\sigma dW_t.\n", 25 | "$$\n", 26 | "It has a closed-form solution for $r_t$: The short rate $r_t$ is normally distributed with\n", 27 | "$$\n", 28 | "r_t \\sim \\mathcal{N}\\left(\\exp(-\\alpha t) r_0 + \\int_0^t \\exp(-\\alpha (t-s)) \\mu(t) ds, \\frac{\\sigma^2}{2\\alpha} (1-\\exp(-2\\alpha t))\\right).\n", 29 | "$$\n", 30 | "\n", 31 | "Brio and Mercurio point out that $\\mu(t)$ and the initial value $r_0$ only affect the mean value of $r_t$, but not the stochasticity around it.\n", 32 | "Thus, one can write the model as a mean-zero Vasicek model\n", 33 | "$$\n", 34 | "dr^{\\text{V0}}_t = - \\alpha r^{\\text{V0}}_t dt + \\sigma dW_t,\n", 35 | "$$\n", 36 | "shifted by\n", 37 | "$$\n", 38 | "r^{\\text{shifted}}(t) = r^{\\text{V0}}(t) + \\varphi(t)\n", 39 | "$$\n", 40 | "for the deterministic shift function $\\varphi = E(r_t)$.\n", 41 | "\n", 42 | "As we are interested in observations of fixed time intervals and a corresponding set of discrete maturities, where only integrals of $\\varphi$ between time steps play a rôle, or more precisely, factors $F(t,T)=\\exp(-\\int_t^T \\varphi d\\tau)$. But these can be expressed as quotients\n", 43 | "$$\n", 44 | "\\exp\\left(-\\int_t^T \\varphi d\\tau\\right)=\\frac{ZCB(t,T)}{ZCB^{\\text{V0}}(t,T)}.\n", 45 | "$$\n", 46 | "Indeed, we will not compute or work with $\\varphi$ and substitute the above when applying Brigo or Mercurio's formulas (the same formulas as in the article mentioned above also appear in their book).\n", 47 | "\n", 48 | "First we import a few python modules." 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 1, 54 | "metadata": { 55 | "cell_id": "B04F7255BE2043AA805FD4492CF499CF" 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "import torch\n", 60 | "import numpy\n", 61 | "from matplotlib import pyplot\n", 62 | "import jupyter_import\n", 63 | "%matplotlib inline" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": { 69 | "cell_id": "0A48716E2BE04B16A07DCADEAD0F6746" 70 | }, 71 | "source": [ 72 | "We introduce a convenience function to wrap scalars and tensors in autograd `Variables`." 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 2, 78 | "metadata": { 79 | "cell_id": "553D0F8F318C494A9E4CA610E425A8C7" 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "%lib\n", 84 | "def wrap(x, **argv):\n", 85 | " if numpy.isscalar(x):\n", 86 | " x = torch.autograd.Variable(torch.DoubleTensor([x]), **argv)\n", 87 | " elif isinstance(x, torch.DoubleTensor):\n", 88 | " x = torch.autograd.Variable(x)\n", 89 | " elif isinstance(x, torch.FloatTensor):\n", 90 | " x = torch.autograd.Variable(x.double())\n", 91 | " elif isinstance(x, (torch.autograd.Variable, torch.nn.Parameter)):\n", 92 | " pass\n", 93 | " else:\n", 94 | " raise Exception(\"Nothing to help you with \"+str(x))\n", 95 | " return x\n" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": { 101 | "cell_id": "D4557F97658D4CF980BA49E0709C7FD6" 102 | }, 103 | "source": [ 104 | "We use an [approximation from Wikipedia](https://en.wikipedia.org/wiki/Normal_distribution#Numerical_approximations_for_the_normal_CDF) for the Normal CDF." 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 3, 110 | "metadata": { 111 | "cell_id": "C3F57F1A0F4340028A2A51095C704DB9" 112 | }, 113 | "outputs": [], 114 | "source": [ 115 | "a_for_erf = 8.0/(3.0*numpy.pi)*(numpy.pi-3.0)/(4.0-numpy.pi)\n", 116 | "def erf_approx(x):\n", 117 | " return torch.sign(x)*torch.sqrt(1-torch.exp(-x*x*(4/numpy.pi+a_for_erf*x*x)/(1+a_for_erf*x*x)))\n", 118 | "def erfinv_approx(x):\n", 119 | " b = -2/(numpy.pi*a_for_erf)-torch.log(1-x*x)/2\n", 120 | " return torch.sign(x)*torch.sqrt(b+torch.sqrt(b*b-torch.log(1-x*x)/a_for_erf))\n", 121 | "\n", 122 | "def normal_cdf(x):\n", 123 | " return 0.5*(1.0+erf_approx(x/(2**0.5)))\n" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": { 129 | "cell_id": "91C49610780B4B82816BC53BDC1CB652" 130 | }, 131 | "source": [ 132 | "For the Jamshidian decomposition we need an implicitly defined critical rate $r^*$. This will be obtained by\n", 133 | "gradient descent to minimize the square norm of the defining function to find the zero level set, i.e.\n", 134 | "$f(x) = y$ where $y$ is given by $F(x,y)=0$.\n", 135 | "\n", 136 | "The implicit function theorem readily provides a formula for the derivative, in order to backpropagate through\n", 137 | "the implicit function, we define an autograd function. Details of the implementation and a brief mention of\n", 138 | "mathematics is at my [Implicit functions in Pytorch Notebook](https://github.com/t-vi/pytorch-tvmisc/blob/master/misc/Implicit_Functions_Pytorch.ipynb). Note that the input may $x$ may be a vector, but the sought value $y$ needs to be a scalar as we do not compute the Jacobian and its inverse. But that is all we need." 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 4, 144 | "metadata": { 145 | "cell_id": "B16CF8A782F744F081BE3560CD8680D4" 146 | }, 147 | "outputs": [], 148 | "source": [ 149 | "%lib\n", 150 | "class Implicit(torch.autograd.Function):\n", 151 | " @staticmethod\n", 152 | " def forward(ctx, x, y0, F, max_iter=200, reg=1e-6):\n", 153 | " y = torch.autograd.Variable(y0.clone(), requires_grad=True)\n", 154 | " xv = torch.autograd.Variable(x)\n", 155 | " opt = torch.optim.LBFGS([y], max_iter=max_iter)\n", 156 | " def reevaluate():\n", 157 | " opt.zero_grad()\n", 158 | " z = F(xv,y)**2\n", 159 | " z.backward()\n", 160 | " return z\n", 161 | " opt.step(reevaluate)\n", 162 | " xv = torch.autograd.Variable(x, requires_grad=True)\n", 163 | " y.grad = None\n", 164 | " z = F(xv,y)\n", 165 | " z.backward()\n", 166 | " ctx._dx_by_dy = xv.grad.data/(y.grad.data+y.grad.data.sign()*reg)\n", 167 | " return y.data\n", 168 | " @staticmethod\n", 169 | " def backward(ctx, output_grad):\n", 170 | " return -torch.autograd.Variable(ctx._dx_by_dy)*output_grad, None, None, None, None" 171 | ] 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "metadata": { 176 | "cell_id": "B6583E7FBCFD46C5A8D032B4A730B318" 177 | }, 178 | "source": [ 179 | "We are now ready to define a Vasicek0 class.\n", 180 | "While the bond price and zero-coupon bond option formulas seem to be well-covered in the literature (e.g. Brigo and Mercurio), the simulation implemented in the `step` method below seems to be less so. For your convenience, I have written some [notes on the derivation](http://www.interestingrates.de/artikel/hull-white-implementation/)." 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 5, 186 | "metadata": { 187 | "cell_id": "8FA08DECFAA049208B84BBAB1C1AFFD9" 188 | }, 189 | "outputs": [], 190 | "source": [ 191 | "%lib\n", 192 | "eps = 1e-8\n", 193 | "\n", 194 | "class Vasicek0:\n", 195 | " def __init__(self, alpha, sigma):\n", 196 | " self.alpha = alpha\n", 197 | " self.sigma = sigma\n", 198 | " self.initr = wrap(0.0)\n", 199 | " def get_params(self):\n", 200 | " return torch.cat([self.alpha, self.sigma])\n", 201 | " def step(self, dt, r0, defl0):\n", 202 | " numSim = r0.size(0)\n", 203 | " \n", 204 | " mu = torch.exp(-self.alpha*dt)\n", 205 | " VR = ((self.sigma**2/(2*self.alpha))*(1-mu**2))\n", 206 | " VIntR = (self.sigma**2/(self.alpha**3) * ( dt*self.alpha - 2*(1-mu) + (1-mu**2)/2))\n", 207 | " CovRIntR = (self.sigma**2/(2*self.alpha**2)) * ((1-mu)**2)# ((1-mu)**2)\n", 208 | " rnd2factor = (VIntR - CovRIntR**2/VR)**0.5\n", 209 | " rnd = r0.data.new(*r0.size()).normal_()\n", 210 | " numRnd = r0.size(0)//2\n", 211 | " rnd1 = wrap(torch.cat((rnd[:numRnd],-rnd[:numRnd]),dim=0))\n", 212 | " rnd2 = wrap(torch.cat((rnd[numRnd:],-rnd[numRnd:]),dim=0))\n", 213 | " r = r0*mu + VR**0.5 * rnd1\n", 214 | " defl = defl0 * torch.exp(-(r0/self.alpha*(1-mu)+ (CovRIntR/(VR**0.5))*rnd1+ rnd2factor*rnd2))\n", 215 | " \n", 216 | " return r, defl\n", 217 | "\n", 218 | " def simulate(self, num_sims, num_years, initr=None, steps_per_year=1):\n", 219 | " \"\"\"Simulate the process for a given number of years and simulations and keep the annual values\"\"\"\n", 220 | " initr = initr if initr is not None else wrap(0.0)\n", 221 | " r0 = initr.expand(num_sims)\n", 222 | " d0 = wrap(torch.ones(num_sims))\n", 223 | " r = [r0]\n", 224 | " d = [d0]\n", 225 | " for i in range(num_years):\n", 226 | " for j in range(steps_per_year):\n", 227 | " r0,d0 = model.step(1.0/steps_per_year,r0,d0)\n", 228 | " r.append(r0)\n", 229 | " d.append(d0)\n", 230 | " r = torch.stack(r)\n", 231 | " d = torch.stack(d)\n", 232 | " return r,d\n", 233 | "\n", 234 | " def zcb_price(self, r, term, params=None):\n", 235 | " \"\"\"Returns ZCB prices (= expected exponential integrated short rates) in the Vasicek 0 model\"\"\"\n", 236 | " if params is None:\n", 237 | " alpha, sigma = self.alpha, self.sigma\n", 238 | " else:\n", 239 | " alpha, sigma = torch.split(params, 1, dim=0)\n", 240 | " B = (1-torch.exp(-alpha*term))/alpha\n", 241 | " A = torch.exp(-sigma**2/(2*alpha**2)*(B-term)-sigma**2/(4*alpha)*B**2)\n", 242 | " return A*torch.exp(-B*r)\n", 243 | "\n", 244 | " def init_zcb_price(self, term):\n", 245 | " \"\"\"Return initial ZCB prices, a convenience function for the shift extension\"\"\"\n", 246 | " return self.zcb_price(0.0, term)\n", 247 | " \n", 248 | " def call_zcb(self, term, tenor, X, r0):\n", 249 | " \"\"\"Returns the price of a call option on a zero coupon bond.\n", 250 | " The option matures at term, the zero coupon bond at term+tenor.\n", 251 | " The strike ZCB price is X.\n", 252 | " The current (time 0) short rate is r0.\"\"\"\n", 253 | "\n", 254 | " sigma_zcb = 1/self.alpha*(1-torch.exp(-self.alpha*(tenor)))*torch.sqrt(self.sigma**2/(2*self.alpha)*(1-torch.exp(-2*self.alpha*term)))\n", 255 | " Pbondmat = self.zcb_price(r0, term+tenor)\n", 256 | " Poptionexp = self.zcb_price(r0, term)\n", 257 | " d1 = (Pbondmat.log()-Poptionexp.log()-X.log()+0.5*sigma_zcb**2)/(sigma_zcb)\n", 258 | " d2 = d1-sigma_zcb\n", 259 | " return Pbondmat*normal_cdf(d1)-Poptionexp*X*normal_cdf(d2)\n" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": { 265 | "cell_id": "429D7472EC924206B8210D16192C20F8" 266 | }, 267 | "source": [ 268 | "We are now ready to implement the shifted model of Brigo and Mercurio that will give a Hull-White-Model when combined with the above.\n", 269 | "\n", 270 | "We take a fully initialized `Vasicek0` model (that can give zero bond prices) and a desired Zero Coupon Bond curve.\n", 271 | "The formulas follow Brigo and Mercurio with the substitution mentioned above and get formulas for the deflators (in the method `simulate`), zero coupon bonds (but this time, it is dependend on the time step, so we expect $r$ to be of shape $timesteps \\times simulation$).\n", 272 | "\n", 273 | "The function `call_atm_swap` implements pricing of at the money european receiver swaptions using Jamshidians decomposition. The critical rate $r^*$ is defined as the one where the resulting swap rate is exactly the strike swap rate. Using that the forward swap rate $s$ is defined as \n", 274 | "$$f = \\frac{ZCB(0,oterm)-ZCB(0,oterm+tenor)}{\\sum_{i=oterm+1}^{oterm+tenor}ZCB(0,i)},$$\n", 275 | "we can define the critical rate $r^*$ as the rate given by the equation\n", 276 | "$$\n", 277 | "F(\\alpha,\\mu,\\sigma,r^*):=s_{\\text{strike}} \\sum_{i=oterm+1}^{oterm+tenor}ZCB(0,i) - (ZCB(0,oterm)-ZCB(0,oterm+tenor)) =0.\n", 278 | "$$\n", 279 | "The ZCB prices and thus the critical rate also depend on the model parameters $\\alpha$, $\\mu$, and $\\sigma$." 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": 6, 285 | "metadata": { 286 | "cell_id": "BF85D84185C4437CB2CD50DF082CC48C" 287 | }, 288 | "outputs": [], 289 | "source": [ 290 | "%lib\n", 291 | "class ShiftedModel:\n", 292 | " def __init__(self, basemodel, zcbs):\n", 293 | " self.zcbs = zcbs\n", 294 | " self.basemodel = basemodel\n", 295 | " self.xzcbsbase = self.basemodel.init_zcb_price(wrap(torch.arange(0,zcbs.size(0)+1)))\n", 296 | " self.zcbsbase = self.xzcbsbase[1:]\n", 297 | " self.xzcbs = torch.cat((wrap(self.zcbs.data.new(1).fill_(1.0)),self.zcbs),dim=0)\n", 298 | "\n", 299 | " def simulate(self, num_sims, num_years, steps_per_year=12):\n", 300 | " r, d_base = self.basemodel.simulate(num_sims, num_years, steps_per_year=steps_per_year)\n", 301 | " numYears_plus_one = r.size(0)\n", 302 | " d = d_base*(self.xzcbs[:numYears_plus_one].unsqueeze(1)/self.xzcbsbase[:numYears_plus_one].unsqueeze(1))\n", 303 | " return r,d\n", 304 | "\n", 305 | " def zcb_price(self, r, term):\n", 306 | " numYears = r.size(0)-1\n", 307 | " assert len(self.zcbs)>=term+numYears\n", 308 | " forwardzcbs = self.xzcbs[term:]/self.xzcbs[:-term]\n", 309 | " forwardzcbsbase = self.xzcbsbase[term:]/self.xzcbsbase[:-term]\n", 310 | " forwardzcbfactors = forwardzcbs[:numYears+1]/forwardzcbsbase[:numYears+1]\n", 311 | " zcbPrice = self.basemodel.zcb_price(r, term)*forwardzcbfactors.unsqueeze(1)\n", 312 | " return zcbPrice\n", 313 | "\n", 314 | " def forward_zcb_prices_terms(self, r, t, maxterm, params=None):\n", 315 | " assert len(self.xzcbs) >= t+maxterm+1\n", 316 | " terms = wrap(torch.arange(0, maxterm+1))\n", 317 | " zcb_prices_base = self.basemodel.zcb_price(r, terms, params=params)\n", 318 | " forwardzcbsbase = zcb_prices_base/zcb_prices_base[0] #self.xzcbsbase[t:t+maxterm+1]/self.xzcbsbase[t]\n", 319 | " forwardzcbs = self.xzcbs[t:t+maxterm+1]/self.xzcbs[t]\n", 320 | " forwardzcbfactors = forwardzcbs/forwardzcbsbase\n", 321 | " zcbPrices = zcb_prices_base*forwardzcbfactors\n", 322 | " return zcbPrices\n", 323 | " \n", 324 | " def call_zcb(self, term, tenor, X, r0): # Brigo Mercurio ZCB in CIR\n", 325 | " zcb_factor_term_plus_tenor = self.xzcbs[term+tenor]/self.xzcbsbase[term+tenor]\n", 326 | " zcb_factor_term = self.xzcbs[term]/self.xzcbsbase[term]\n", 327 | " X_adj = X/(zcb_factor_term_plus_tenor/zcb_factor_term)\n", 328 | " return self.basemodel.call_zcb(term, tenor, X_adj, r0)*zcb_factor_term_plus_tenor\n", 329 | "\n", 330 | " def call_atm_swap(self, oterm, tenor, r0=None):\n", 331 | " if r0 is None:\n", 332 | " r0 = self.basemodel.initr\n", 333 | " s = (self.xzcbs[oterm]-self.xzcbs[oterm+tenor])/self.xzcbs[oterm+1:oterm+tenor+1].sum()\n", 334 | " def F_jamshidian(params, r):\n", 335 | " zcbs = self.forward_zcb_prices_terms(r, oterm, tenor, params=params)\n", 336 | " return s*zcbs[1:].sum()+zcbs[tenor]-zcbs[0]\n", 337 | "\n", 338 | " params = self.basemodel.get_params()\n", 339 | " rstar = Implicit.apply(params, wrap(0.01), F_jamshidian) # where is sigma from?!\n", 340 | " zcbs = self.forward_zcb_prices_terms(rstar, oterm, tenor)\n", 341 | " price = (1+s)*self.call_zcb(oterm, tenor, zcbs[tenor], r0)\n", 342 | " for i in range(tenor-1):\n", 343 | " price += s*self.call_zcb(oterm, i+1, zcbs[i+1], r0)\n", 344 | " normvol = price*(((2*numpy.pi)/oterm)**0.5)/(self.xzcbs[oterm+1:oterm+tenor+1].sum())\n", 345 | " return price, normvol" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": { 351 | "cell_id": "D0D363732A5D4FF48E8917B7EEF59BC0" 352 | }, 353 | "source": [ 354 | "We can test the our new class.\n", 355 | "We use the spot (zero coupon swap rate) rates of 31 December 2016. \n", 356 | "These can be obtained from the usual providers, or freely from the Deutsche Bundesbank [published as part of the HGB §253 (2) discount rate information](http://www.bundesbank.de/Navigation/DE/Statistiken/Zeitreihen_Datenbanken/Geld_und_Kapitalmaerkte/geld_und_kapitalmaerkte_list_node.html?listId=www_skms_it05b).\n", 357 | "The other parameters are made up, though." 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": 7, 363 | "metadata": { 364 | "cell_id": "B91FC04FC0C4432687A5D46AA4725C2A" 365 | }, 366 | "outputs": [], 367 | "source": [ 368 | "num_sims = 100000\n", 369 | "num_years = 10\n", 370 | "spots = torch.FloatTensor([-0.00217, -0.00163, -0.00119, -0.00025, 0.0006, 0.00177, 0.00302, 0.00437, 0.00558, 0.00676, 0.0077, 0.00849, 0.00925, 0.00991, 0.01048, 0.01087, 0.01121, 0.01152, 0.01179, 0.01204])\n", 371 | "zcbs = wrap((1+spots)**(-torch.arange(1,spots.size(0)+1)))\n", 372 | "alpha = wrap(0.1)\n", 373 | "sigma = wrap(0.016)\n", 374 | "model = Vasicek0(alpha, sigma)\n", 375 | "model2 = ShiftedModel(model, zcbs)" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": { 381 | "cell_id": "AE6821C40AFF4EA884914D4A1E702673" 382 | }, 383 | "source": [ 384 | "We can produce simulations for the short rate $r$ and the discount factor $defl$." 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": 8, 390 | "metadata": { 391 | "cell_id": "F71A4FCF16924CB1B2A82CDEBC763307" 392 | }, 393 | "outputs": [], 394 | "source": [ 395 | "r,d = model2.simulate(num_sims, num_years, steps_per_year=1)" 396 | ] 397 | }, 398 | { 399 | "cell_type": "markdown", 400 | "metadata": { 401 | "cell_id": "0A1458C317634F83954C70E96D3896A0" 402 | }, 403 | "source": [ 404 | "The first check is whether the mean deflator matches the zero cupon bonds, i.e. whether the simulation discount factors reflect the initial discount curve for fixed payments.\n", 405 | "\n", 406 | "(Ideally we would produce confidence intervals to match standard practice, but that is for another day.)" 407 | ] 408 | }, 409 | { 410 | "cell_type": "code", 411 | "execution_count": 9, 412 | "metadata": { 413 | "cell_id": "7C48D2EA0CE34B758BA6C2D3D75E8783" 414 | }, 415 | "outputs": [ 416 | { 417 | "data": { 418 | "text/plain": [ 419 | "[]" 420 | ] 421 | }, 422 | "execution_count": 9, 423 | "metadata": {}, 424 | "output_type": "execute_result" 425 | }, 426 | { 427 | "data": { 428 | "image/png": "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\n", 429 | "text/plain": [ 430 | "" 431 | ] 432 | }, 433 | "metadata": {}, 434 | "output_type": "display_data" 435 | } 436 | ], 437 | "source": [ 438 | "pyplot.plot((d[1:].mean(1)/zcbs[:d.size(0)-1]-1).data.numpy())" 439 | ] 440 | }, 441 | { 442 | "cell_type": "markdown", 443 | "metadata": { 444 | "cell_id": "6C9FF9356034480FAF4BBFF0707B349D" 445 | }, 446 | "source": [ 447 | "We can also do this for forward prices, e.g. for the 10-year ZCB in the future." 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 10, 453 | "metadata": { 454 | "cell_id": "B0523EE7127E4AF6BC66A065CC0F65B1" 455 | }, 456 | "outputs": [ 457 | { 458 | "data": { 459 | "text/plain": [ 460 | "[]" 461 | ] 462 | }, 463 | "execution_count": 10, 464 | "metadata": {}, 465 | "output_type": "execute_result" 466 | }, 467 | { 468 | "data": { 469 | "image/png": "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\nlFId+v9oYAf9axgRfwAAAABJRU5ErkJggg==\n", 470 | "text/plain": [ 471 | "" 472 | ] 473 | }, 474 | "metadata": {}, 475 | "output_type": "display_data" 476 | } 477 | ], 478 | "source": [ 479 | "pyplot.plot((((model2.zcb_price(r,10)*d).mean(1)/zcbs[9:])-1).data.numpy())" 480 | ] 481 | }, 482 | { 483 | "cell_type": "markdown", 484 | "metadata": { 485 | "cell_id": "FFDAB7FEF582496C8F51C632509BB1CC" 486 | }, 487 | "source": [ 488 | "We can also compare the Monte Carlo price, i.e. the discounted payoff, of a call option on a ZCB with the analytical price function." 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": 11, 494 | "metadata": { 495 | "cell_id": "7DFFEF7A73D04F708DEE1BAD8784F137" 496 | }, 497 | "outputs": [ 498 | { 499 | "data": { 500 | "text/plain": [ 501 | "(0.09214147244611484, 0.092169449862495617)" 502 | ] 503 | }, 504 | "execution_count": 11, 505 | "metadata": {}, 506 | "output_type": "execute_result" 507 | } 508 | ], 509 | "source": [ 510 | "def compare_zcb_call(term, tenor, strike):\n", 511 | " formula_price = model2.call_zcb(term, tenor, wrap(strike), wrap(0.0))\n", 512 | " zcb_forward = model2.zcb_price(r[:term+1], tenor).data.numpy()[term]\n", 513 | " d_term = d[term,:].data.numpy()\n", 514 | " mc_price = (numpy.fmax(zcb_forward-strike,0)*d_term).mean()\n", 515 | " return formula_price.data[0], mc_price\n", 516 | "\n", 517 | "compare_zcb_call(5,1,0.9)" 518 | ] 519 | }, 520 | { 521 | "cell_type": "markdown", 522 | "metadata": { 523 | "cell_id": "10A49411D9354556864AA8707795F30C" 524 | }, 525 | "source": [ 526 | "And we can also compare Monte Carlo price of a receiver swaption to the Jamshidian-calculated price." 527 | ] 528 | }, 529 | { 530 | "cell_type": "code", 531 | "execution_count": 12, 532 | "metadata": { 533 | "cell_id": "DA62CE56C0234A0DA910C1EEBCF8617D" 534 | }, 535 | "outputs": [ 536 | { 537 | "data": { 538 | "text/plain": [ 539 | "(0.073441667132462349, 0.0735625476327573)" 540 | ] 541 | }, 542 | "execution_count": 12, 543 | "metadata": {}, 544 | "output_type": "execute_result" 545 | } 546 | ], 547 | "source": [ 548 | "def compare_swaption(term, tenor):\n", 549 | " atm_swap_rate = (model2.xzcbs[term]-model2.xzcbs[term+tenor])/model2.xzcbs[term+1:term+tenor+1].sum()\n", 550 | " zcb_forwards = torch.stack([model2.zcb_price(r[:term+1], t)[term] for t in range(1,tenor+1)])\n", 551 | " payoffs = (atm_swap_rate*zcb_forwards.sum(0)-(1-zcb_forwards[-1])).data.numpy()\n", 552 | " d_term = d[term,:].data.numpy()\n", 553 | " mc_price = (numpy.fmax(payoffs,0)*d_term).mean()\n", 554 | " formula_price,_ = model2.call_atm_swap(term, tenor)\n", 555 | " return mc_price, formula_price.data[0]\n", 556 | "compare_swaption(10,10)" 557 | ] 558 | }, 559 | { 560 | "cell_type": "markdown", 561 | "metadata": { 562 | "cell_id": "BB38CBE8CC754FA08FA46AC2356109FD" 563 | }, 564 | "source": [ 565 | "# Calibration" 566 | ] 567 | }, 568 | { 569 | "cell_type": "markdown", 570 | "metadata": { 571 | "cell_id": "A9BF479F44B0424988733267E59A9DEE" 572 | }, 573 | "source": [ 574 | "For illustration, we calibrate the model three times.\n", 575 | "\n", 576 | "The first method is gradient descent (which is not stochastic in our case) using the `torch.SGD` class." 577 | ] 578 | }, 579 | { 580 | "cell_type": "code", 581 | "execution_count": 13, 582 | "metadata": { 583 | "cell_id": "E3C32CCF2A9A44AEA4CB41C0FF1D5F15" 584 | }, 585 | "outputs": [ 586 | { 587 | "name": "stdout", 588 | "output_type": "stream", 589 | "text": [ 590 | "err 4.073408922898773e-11 sigma 0.017275957440965186\n" 591 | ] 592 | } 593 | ], 594 | "source": [ 595 | "vol_market = 0.0074 # 10-10 swaption 2016-12-31, normal volatility (=74bps)\n", 596 | "\n", 597 | "sigma = wrap(0.016, requires_grad=True)\n", 598 | "opt = torch.optim.SGD([sigma],lr=1e-4)\n", 599 | "for i in range(20):\n", 600 | " opt.zero_grad()\n", 601 | " hw = ShiftedModel(Vasicek0(alpha, sigma), zcbs)\n", 602 | " _,vol_model = hw.call_atm_swap(10, 10)\n", 603 | " error = ((vol_model-vol_market)*100)**2\n", 604 | " error.backward()\n", 605 | " opt.step()\n", 606 | "hw = ShiftedModel(Vasicek0(alpha, sigma), zcbs)\n", 607 | "_,vol_model = hw.call_atm_swap(10, 10)\n", 608 | "error = ((vol_model-vol_market)*100)**2\n", 609 | "print (\"err\", error.data[0], \"sigma\", sigma.data[0])\n" 610 | ] 611 | }, 612 | { 613 | "cell_type": "markdown", 614 | "metadata": { 615 | "cell_id": "0E279DA183E245F7B9B2827C153318E9" 616 | }, 617 | "source": [ 618 | "The second method is the [LBFGS](https://en.wikipedia.org/wiki/Limited-memory_BFGS) quasi-newton method. It is a bit more elaborate to use in pytorch because it needs a closure to reevaluate the model." 619 | ] 620 | }, 621 | { 622 | "cell_type": "code", 623 | "execution_count": 14, 624 | "metadata": { 625 | "cell_id": "A893BB97A8AB4C1DBF1F773CD5C90758" 626 | }, 627 | "outputs": [ 628 | { 629 | "name": "stdout", 630 | "output_type": "stream", 631 | "text": [ 632 | "err 6.1346504079490504e-09 sigma 0.017277943162396\n" 633 | ] 634 | } 635 | ], 636 | "source": [ 637 | "vol_market = 0.0074 # 10-10 swaption 2016-12-31\n", 638 | "\n", 639 | "sigma = wrap(0.016, requires_grad=True)\n", 640 | "opt = torch.optim.LBFGS([sigma], lr=1e-1, max_iter=100)\n", 641 | "def calc_error():\n", 642 | " opt.zero_grad()\n", 643 | " hw = ShiftedModel(Vasicek0(alpha, sigma), zcbs)\n", 644 | " _,vol_model = hw.call_atm_swap(10, 10)\n", 645 | " error = ((vol_model-vol_market)*100)**2\n", 646 | " error.backward()\n", 647 | " return error\n", 648 | " \n", 649 | "opt.step(calc_error)\n", 650 | "opt.zero_grad()\n", 651 | "hw = ShiftedModel(Vasicek0(alpha, sigma), zcbs)\n", 652 | "_,vol_model = hw.call_atm_swap(10, 10)\n", 653 | "error = ((vol_model-vol_market)*100)**2\n", 654 | "print (\"err\", error.data[0], \"sigma\", sigma.data[0])\n" 655 | ] 656 | }, 657 | { 658 | "cell_type": "markdown", 659 | "metadata": { 660 | "cell_id": "661146B8B1DE45748DB91E4E35762323" 661 | }, 662 | "source": [ 663 | "Finally, given that there is only one parameter, we implement a bisection method. The search range of $\\sigma$ does seem to come out of thin air. In my experience and for $\\alpha=0.1$ most historic values of $\\sigma$ fall into the interval $[0.1,0.2]$, so we double each of the bounds to be safe." 664 | ] 665 | }, 666 | { 667 | "cell_type": "code", 668 | "execution_count": 15, 669 | "metadata": { 670 | "cell_id": "ED1EF9A0C91F402F84FEA0FB98821C31" 671 | }, 672 | "outputs": [ 673 | { 674 | "name": "stdout", 675 | "output_type": "stream", 676 | "text": [ 677 | "resulting sigma: 0.01727638244628906 model vol: 0.007400117474390436 market vol: 0.0074\n" 678 | ] 679 | } 680 | ], 681 | "source": [ 682 | "sigma_min = 0.005\n", 683 | "sigma_max = 0.04\n", 684 | "\n", 685 | "vol_market = 0.0074 # 10-10 swaption 2016-12-31\n", 686 | "\n", 687 | "_, vol_min = ShiftedModel(Vasicek0(alpha, wrap(sigma_min)), zcbs).call_atm_swap(10, 10)\n", 688 | "_, vol_max = ShiftedModel(Vasicek0(alpha, wrap(sigma_max)), zcbs).call_atm_swap(10, 10)\n", 689 | "\n", 690 | "\n", 691 | "while sigma_max-sigma_min>1e-6:\n", 692 | " sigma_mid = 0.5*(sigma_min+sigma_max)\n", 693 | " _, vol_mid = ShiftedModel(Vasicek0(alpha, wrap(sigma_mid)), zcbs).call_atm_swap(10, 10)\n", 694 | " if vol_mid.data[0] > vol_market:\n", 695 | " sigma_max, vol_max = sigma_mid, vol_mid\n", 696 | " else:\n", 697 | " sigma_min, vol_min = sigma_mid, vol_mid\n", 698 | "\n", 699 | "print (\"resulting sigma:\",sigma_mid, \"model vol:\", vol_mid.data[0], \"market vol:\",vol_market)" 700 | ] 701 | }, 702 | { 703 | "cell_type": "markdown", 704 | "metadata": { 705 | "cell_id": "949D43D6772C4A82A54BB27FCECDEFFF" 706 | }, 707 | "source": [ 708 | "I hope this notebook is informative for you. I read and appreciate every mail with feedback you send to .\n", 709 | "\n", 710 | "Thomas Viehmann" 711 | ] 712 | }, 713 | { 714 | "cell_type": "code", 715 | "execution_count": null, 716 | "metadata": { 717 | "cell_id": "C34ECDCEA0F54C8B8EDA067AE56C4390" 718 | }, 719 | "outputs": [], 720 | "source": [] 721 | } 722 | ], 723 | "metadata": { 724 | "kernelspec": { 725 | "display_name": "Python 3", 726 | "language": "python", 727 | "name": "python3" 728 | }, 729 | "language_info": { 730 | "codemirror_mode": { 731 | "name": "ipython", 732 | "version": 3 733 | }, 734 | "file_extension": ".py", 735 | "mimetype": "text/x-python", 736 | "name": "python", 737 | "nbconvert_exporter": "python", 738 | "pygments_lexer": "ipython3", 739 | "version": "3.5.3" 740 | } 741 | }, 742 | "nbformat": 4, 743 | "nbformat_minor": 2 744 | } 745 | -------------------------------------------------------------------------------- /yieldcurve/nelson-siegel-svensson.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "cell_id": "4753EEF952C84B03933ACBBC2915BBC5" 7 | }, 8 | "source": [ 9 | "# Nelson-Siegel-Svensson from the German Bundesbank\n", 10 | "Thomas Viehmann \n", 11 | "\n", 12 | "We quickly implement the Nelson-Siegel-Svensson method and calculate the German Bundesbank's Bund yield curves from the parameters.\n" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": 78, 18 | "metadata": { 19 | "cell_id": "8CCBAC2B868F43148C1F67370254CC8F" 20 | }, 21 | "outputs": [], 22 | "source": [ 23 | "import pandas\n", 24 | "import numpy\n", 25 | "import urllib.request\n", 26 | "from matplotlib import pyplot\n", 27 | "%matplotlib inline" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "cell_id": "9410D3813B124952853E046579DB94DD" 34 | }, 35 | "source": [ 36 | "We download the parameters from the Bundesbank in CSV format." 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 105, 42 | "metadata": { 43 | "cell_id": "3415D556CE794967819D18636F1726B4" 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "df = pandas.read_csv(urllib.request.urlopen(\"http://www.bundesbank.de/cae/servlet/StatisticDownload?tsId=BBK01.WZ9801&tsId=BBK01.WZ9802&tsId=BBK01.WZ9803&tsId=BBK01.WZ9804&tsId=BBK01.WZ9805&tsId=BBK01.WZ9806&its_csvFormat=en&its_fileFormat=csv&mode=its&its_dateFormat=dateOfDay\"), index_col=0)\n", 48 | "df.drop([x for x in df.columns if x.endswith(\"_FLAGS\")],axis=1, inplace=True)\n", 49 | "mapping = dict((df.iloc[0].dropna().apply(lambda x: x.split(\" / \")[1].split()[1])).items())\n", 50 | "df.columns = [mapping.get(x,x).lower() for x in df.columns]\n", 51 | "df = df.iloc[4:]\n", 52 | "df = df.apply(lambda x: x.astype(float))\n", 53 | "df.index = pandas.to_datetime(df.index)\n" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": { 59 | "cell_id": "BE4E627FE5C44C8188CEC55FA9F1A6BD" 60 | }, 61 | "source": [ 62 | "Let us see what we got:" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 106, 68 | "metadata": { 69 | "cell_id": "42A3A48687464F118F3B204910085C07" 70 | }, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/html": [ 75 | "
\n", 76 | "\n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | " \n", 554 | " \n", 555 | " \n", 556 | " \n", 557 | " \n", 558 | " \n", 559 | " \n", 560 | " \n", 561 | " \n", 562 | " \n", 563 | " \n", 564 | " \n", 565 | " \n", 566 | " \n", 567 | " \n", 568 | " \n", 569 | " \n", 570 | " \n", 571 | " \n", 572 | " \n", 573 | " \n", 574 | " \n", 575 | " \n", 576 | " \n", 577 | " \n", 578 | " \n", 579 | " \n", 580 | " \n", 581 | " \n", 582 | " \n", 583 | " \n", 584 | " \n", 585 | " \n", 586 | " \n", 587 | " \n", 588 | " \n", 589 | " \n", 590 | " \n", 591 | " \n", 592 | " \n", 593 | " \n", 594 | " \n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 619 | " \n", 620 | " \n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | " \n", 629 | " \n", 630 | " \n", 631 | " \n", 632 | " \n", 633 | " \n", 634 | " \n", 635 | " \n", 636 | " \n", 637 | " \n", 638 | " \n", 639 | "
beta0beta1beta2tau1beta3tau2
1972-09-308.5838730.00000-29.884500.36495-13.912000.36543
1972-10-318.5288929.5895328.984290.00481-7.486760.26523
1972-11-308.8041829.92019-20.511460.51241-30.000000.24715
1972-12-319.43739-7.46531-20.486381.2951028.550311.01820
1973-01-3111.61329-4.48145-8.472010.52885-7.082964.69237
1973-02-2811.4554013.02996-30.000000.39174-7.292065.24815
1973-03-3111.44706-6.1588428.955512.46182-30.000003.09107
1973-04-308.90814-12.64824-10.759080.5848530.000000.42540
1973-05-3110.3605621.01261-30.000000.12923-2.287583.54882
1973-06-3010.3013819.20941-24.005490.44307-1.485251.65952
1973-07-3110.28803-0.75852-29.296361.6972530.000001.54753
1973-08-319.45106-1.76690-30.000000.00685-8.085380.01089
1973-09-309.5989630.0000030.000000.02152-15.456490.09899
1973-10-319.44673-29.0859630.000000.19653-30.000000.01996
1973-11-3010.435460.99556-2.496491.83575-2.806981.83550
1973-12-3110.610792.12365-1.817611.39298-5.900791.40155
1974-01-316.484183.1544230.000005.40143-24.815424.35549
1974-02-2812.02109-1.05923-3.286532.80130-1.698052.81055
1974-03-3111.06112-1.21315-30.000001.1600828.333331.08420
1974-04-3010.99285-1.2277428.595091.18632-30.000001.26113
1974-05-3111.0115911.30677-30.000000.1639930.000000.02584
1974-06-3012.8785619.85707-30.000000.31596-6.776462.07747
1974-07-3112.88140-3.34980-1.478832.18805-2.673532.18630
1974-08-3112.89372-3.17628-1.237122.66876-2.542532.69818
1974-09-3012.30008-2.44785-2.612711.85613-1.147381.86477
1974-10-3113.67133-4.67172-2.694822.27010-8.1222530.00000
1974-11-3011.30768-1.91948-3.047201.17281-2.151141.16793
1974-12-3110.73064-1.82234-3.111411.30525-0.366431.31588
1975-01-3110.35981-1.54463-3.054940.98556-4.160071.00195
1975-02-2810.61680-3.79682-2.869491.14062-3.484961.13985
.....................
2015-05-310.46930-0.6741530.000006.48595-28.309525.78670
2015-06-300.61250-0.84021-26.788585.6499529.293656.65600
2015-07-310.74211-0.95124-7.581984.787978.966157.70390
2015-08-310.00010-0.2149012.859838.49736-9.232065.46717
2015-09-300.00021-0.2209030.000007.61921-26.703436.45672
2015-10-310.00039-0.274549.845379.05896-6.798395.10291
2015-11-300.00044-0.3113130.000007.42196-26.989746.17789
2015-12-310.00698-0.3868529.989937.76139-25.972346.47600
2016-01-310.00010-0.37225-27.654786.0777930.000007.11502
2016-02-290.00010-0.4194921.019287.29171-19.374075.97233
2016-03-310.00022-0.43630-28.106686.6413730.000007.56583
2016-04-301.60800-2.2103126.384371.77300-29.983601.91008
2016-05-311.48722-2.1039124.200781.80138-27.653781.94603
2016-06-300.83366-1.5199127.200251.80380-29.813521.89838
2016-07-310.79072-1.49237-0.004450.70120-3.806962.38485
2016-08-310.86296-1.53240-21.100211.9599118.521081.80823
2016-09-300.85359-1.61903-29.351701.9167126.670201.80187
2016-10-311.33061-2.18835-0.140680.70931-4.817002.31295
2016-11-300.55600-1.3752526.251975.62709-25.385405.03144
2016-12-311.46745-2.60460-21.051461.5395017.741901.33560
2017-01-311.78318-2.4489025.600041.51221-30.000001.61925
2017-02-281.63301-2.5741316.243211.56949-20.738421.75779
2017-03-311.71984-2.4826518.127411.70136-22.272061.84439
2017-04-301.74353-2.37674-1.331170.63335-5.611032.22454
2017-05-311.80291-2.42013-1.651320.45237-6.398282.11766
2017-06-301.78529-2.59107-27.249481.7133623.686341.58797
2017-07-311.76955-2.408124.413934.68211-5.792223.23586
2017-08-311.73866-2.528890.030240.91346-5.704452.14135
2017-09-301.88347-2.34000-4.064362.33709-1.383620.05894
2017-10-311.60514-2.3438711.268044.53295-12.621203.83460
\n", 640 | "

542 rows × 6 columns

\n", 641 | "
" 642 | ], 643 | "text/plain": [ 644 | " beta0 beta1 beta2 tau1 beta3 tau2\n", 645 | "1972-09-30 8.58387 30.00000 -29.88450 0.36495 -13.91200 0.36543\n", 646 | "1972-10-31 8.52889 29.58953 28.98429 0.00481 -7.48676 0.26523\n", 647 | "1972-11-30 8.80418 29.92019 -20.51146 0.51241 -30.00000 0.24715\n", 648 | "1972-12-31 9.43739 -7.46531 -20.48638 1.29510 28.55031 1.01820\n", 649 | "1973-01-31 11.61329 -4.48145 -8.47201 0.52885 -7.08296 4.69237\n", 650 | "1973-02-28 11.45540 13.02996 -30.00000 0.39174 -7.29206 5.24815\n", 651 | "1973-03-31 11.44706 -6.15884 28.95551 2.46182 -30.00000 3.09107\n", 652 | "1973-04-30 8.90814 -12.64824 -10.75908 0.58485 30.00000 0.42540\n", 653 | "1973-05-31 10.36056 21.01261 -30.00000 0.12923 -2.28758 3.54882\n", 654 | "1973-06-30 10.30138 19.20941 -24.00549 0.44307 -1.48525 1.65952\n", 655 | "1973-07-31 10.28803 -0.75852 -29.29636 1.69725 30.00000 1.54753\n", 656 | "1973-08-31 9.45106 -1.76690 -30.00000 0.00685 -8.08538 0.01089\n", 657 | "1973-09-30 9.59896 30.00000 30.00000 0.02152 -15.45649 0.09899\n", 658 | "1973-10-31 9.44673 -29.08596 30.00000 0.19653 -30.00000 0.01996\n", 659 | "1973-11-30 10.43546 0.99556 -2.49649 1.83575 -2.80698 1.83550\n", 660 | "1973-12-31 10.61079 2.12365 -1.81761 1.39298 -5.90079 1.40155\n", 661 | "1974-01-31 6.48418 3.15442 30.00000 5.40143 -24.81542 4.35549\n", 662 | "1974-02-28 12.02109 -1.05923 -3.28653 2.80130 -1.69805 2.81055\n", 663 | "1974-03-31 11.06112 -1.21315 -30.00000 1.16008 28.33333 1.08420\n", 664 | "1974-04-30 10.99285 -1.22774 28.59509 1.18632 -30.00000 1.26113\n", 665 | "1974-05-31 11.01159 11.30677 -30.00000 0.16399 30.00000 0.02584\n", 666 | "1974-06-30 12.87856 19.85707 -30.00000 0.31596 -6.77646 2.07747\n", 667 | "1974-07-31 12.88140 -3.34980 -1.47883 2.18805 -2.67353 2.18630\n", 668 | "1974-08-31 12.89372 -3.17628 -1.23712 2.66876 -2.54253 2.69818\n", 669 | "1974-09-30 12.30008 -2.44785 -2.61271 1.85613 -1.14738 1.86477\n", 670 | "1974-10-31 13.67133 -4.67172 -2.69482 2.27010 -8.12225 30.00000\n", 671 | "1974-11-30 11.30768 -1.91948 -3.04720 1.17281 -2.15114 1.16793\n", 672 | "1974-12-31 10.73064 -1.82234 -3.11141 1.30525 -0.36643 1.31588\n", 673 | "1975-01-31 10.35981 -1.54463 -3.05494 0.98556 -4.16007 1.00195\n", 674 | "1975-02-28 10.61680 -3.79682 -2.86949 1.14062 -3.48496 1.13985\n", 675 | "... ... ... ... ... ... ...\n", 676 | "2015-05-31 0.46930 -0.67415 30.00000 6.48595 -28.30952 5.78670\n", 677 | "2015-06-30 0.61250 -0.84021 -26.78858 5.64995 29.29365 6.65600\n", 678 | "2015-07-31 0.74211 -0.95124 -7.58198 4.78797 8.96615 7.70390\n", 679 | "2015-08-31 0.00010 -0.21490 12.85983 8.49736 -9.23206 5.46717\n", 680 | "2015-09-30 0.00021 -0.22090 30.00000 7.61921 -26.70343 6.45672\n", 681 | "2015-10-31 0.00039 -0.27454 9.84537 9.05896 -6.79839 5.10291\n", 682 | "2015-11-30 0.00044 -0.31131 30.00000 7.42196 -26.98974 6.17789\n", 683 | "2015-12-31 0.00698 -0.38685 29.98993 7.76139 -25.97234 6.47600\n", 684 | "2016-01-31 0.00010 -0.37225 -27.65478 6.07779 30.00000 7.11502\n", 685 | "2016-02-29 0.00010 -0.41949 21.01928 7.29171 -19.37407 5.97233\n", 686 | "2016-03-31 0.00022 -0.43630 -28.10668 6.64137 30.00000 7.56583\n", 687 | "2016-04-30 1.60800 -2.21031 26.38437 1.77300 -29.98360 1.91008\n", 688 | "2016-05-31 1.48722 -2.10391 24.20078 1.80138 -27.65378 1.94603\n", 689 | "2016-06-30 0.83366 -1.51991 27.20025 1.80380 -29.81352 1.89838\n", 690 | "2016-07-31 0.79072 -1.49237 -0.00445 0.70120 -3.80696 2.38485\n", 691 | "2016-08-31 0.86296 -1.53240 -21.10021 1.95991 18.52108 1.80823\n", 692 | "2016-09-30 0.85359 -1.61903 -29.35170 1.91671 26.67020 1.80187\n", 693 | "2016-10-31 1.33061 -2.18835 -0.14068 0.70931 -4.81700 2.31295\n", 694 | "2016-11-30 0.55600 -1.37525 26.25197 5.62709 -25.38540 5.03144\n", 695 | "2016-12-31 1.46745 -2.60460 -21.05146 1.53950 17.74190 1.33560\n", 696 | "2017-01-31 1.78318 -2.44890 25.60004 1.51221 -30.00000 1.61925\n", 697 | "2017-02-28 1.63301 -2.57413 16.24321 1.56949 -20.73842 1.75779\n", 698 | "2017-03-31 1.71984 -2.48265 18.12741 1.70136 -22.27206 1.84439\n", 699 | "2017-04-30 1.74353 -2.37674 -1.33117 0.63335 -5.61103 2.22454\n", 700 | "2017-05-31 1.80291 -2.42013 -1.65132 0.45237 -6.39828 2.11766\n", 701 | "2017-06-30 1.78529 -2.59107 -27.24948 1.71336 23.68634 1.58797\n", 702 | "2017-07-31 1.76955 -2.40812 4.41393 4.68211 -5.79222 3.23586\n", 703 | "2017-08-31 1.73866 -2.52889 0.03024 0.91346 -5.70445 2.14135\n", 704 | "2017-09-30 1.88347 -2.34000 -4.06436 2.33709 -1.38362 0.05894\n", 705 | "2017-10-31 1.60514 -2.34387 11.26804 4.53295 -12.62120 3.83460\n", 706 | "\n", 707 | "[542 rows x 6 columns]" 708 | ] 709 | }, 710 | "execution_count": 106, 711 | "metadata": {}, 712 | "output_type": "execute_result" 713 | } 714 | ], 715 | "source": [ 716 | "df" 717 | ] 718 | }, 719 | { 720 | "cell_type": "markdown", 721 | "metadata": { 722 | "cell_id": "EC0B802777F541DA889759024F962F0D" 723 | }, 724 | "source": [ 725 | "We define the [Nelson-Siegel-Svensson](https://en.wikipedia.org/wiki/Fixed-income_attribution#Modeling_the_yield_curve) function:\n", 726 | "$$\n", 727 | "y(t) = \\beta_0 + \\beta_1 \\frac{1-\\exp(-t/\\tau_1)}{t/\\tau_1}\n", 728 | " + \\beta_2 (\\frac{1-\\exp(-t/\\tau_1)}{t/\\tau_1} - \\exp(-t/\\tau_1))\n", 729 | " + \\beta_3 (\\frac{1-\\exp(-t/\\tau_2)}{t/\\tau_2} - \\exp(-t/\\tau_2))\n", 730 | "$$" 731 | ] 732 | }, 733 | { 734 | "cell_type": "code", 735 | "execution_count": 41, 736 | "metadata": { 737 | "cell_id": "87E83A984CE442F1A68D1F1AC7D4D664" 738 | }, 739 | "outputs": [], 740 | "source": [ 741 | "def nelson_siegel_svensson(term, beta0, beta1, beta2, beta3, tau1, tau2):\n", 742 | " return ( beta0\n", 743 | " +beta1*(1-numpy.exp(-term/tau1))/(term/tau1)\n", 744 | " +beta2*((1-numpy.exp(-term/tau1))/(term/tau1)-numpy.exp(-term/tau1))\n", 745 | " +beta3*((1-numpy.exp(-term/tau2))/(term/tau2)-numpy.exp(-term/tau2)))" 746 | ] 747 | }, 748 | { 749 | "cell_type": "markdown", 750 | "metadata": { 751 | "cell_id": "9E0EA35E49554D708AE4A6E23D2D28CF" 752 | }, 753 | "source": [ 754 | "Let us apply it with the Bundesbank parameters:" 755 | ] 756 | }, 757 | { 758 | "cell_type": "code", 759 | "execution_count": 62, 760 | "metadata": { 761 | "cell_id": "3737D09AFB6D4136870AEFA3E6B839A2" 762 | }, 763 | "outputs": [ 764 | { 765 | "data": { 766 | "text/plain": [ 767 | "1972-09 6.699762\n", 768 | "1972-10 7.043209\n", 769 | "1972-11 9.094030\n", 770 | "1972-12 6.917985\n", 771 | "1973-01 6.419964\n", 772 | "1973-02 7.048853\n", 773 | "1973-03 6.969552\n", 774 | "1973-04 8.327831\n", 775 | "1973-05 8.945003\n", 776 | "1973-06 10.608796\n", 777 | "dtype: float64" 778 | ] 779 | }, 780 | "execution_count": 62, 781 | "metadata": {}, 782 | "output_type": "execute_result" 783 | } 784 | ], 785 | "source": [ 786 | "nelson_siegel_svensson(1.0, *[df[i] for i in [\"beta0\",\"beta1\",\"beta2\",\"beta3\",\"tau1\",\"tau2\"]]).iloc[:10]" 787 | ] 788 | }, 789 | { 790 | "cell_type": "markdown", 791 | "metadata": { 792 | "cell_id": "E39273F29C4646EF8194D615A1593921" 793 | }, 794 | "source": [ 795 | "And check against the Bundesbank's own calculations:" 796 | ] 797 | }, 798 | { 799 | "cell_type": "code", 800 | "execution_count": 121, 801 | "metadata": { 802 | "cell_id": "13E08117A566436FB730D72B87D64BEC" 803 | }, 804 | "outputs": [ 805 | { 806 | "data": { 807 | "text/html": [ 808 | "
\n", 809 | "\n", 810 | " \n", 811 | " \n", 812 | " \n", 813 | " \n", 814 | " \n", 815 | " \n", 816 | " \n", 817 | " \n", 818 | " \n", 819 | " \n", 820 | " \n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | " \n", 830 | " \n", 831 | " \n", 832 | " \n", 833 | " \n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | " \n", 858 | " \n", 859 | " \n", 860 | " \n", 861 | " \n", 862 | " \n", 863 | " \n", 864 | " \n", 865 | " \n", 866 | " \n", 867 | " \n", 868 | " \n", 869 | " \n", 870 | " \n", 871 | " \n", 872 | " \n", 873 | " \n", 874 | " \n", 875 | " \n", 876 | " \n", 877 | " \n", 878 | " \n", 879 | " \n", 880 | "
12030
1972-09-016.70NaNNaN
1972-10-017.04NaNNaN
1972-11-019.09NaNNaN
1972-12-016.92NaNNaN
1973-01-016.42NaNNaN
1973-02-017.05NaNNaN
1973-03-016.97NaNNaN
1973-04-018.33NaNNaN
1973-05-018.95NaNNaN
1973-06-0110.61NaNNaN
\n", 881 | "
" 882 | ], 883 | "text/plain": [ 884 | " 1 20 30\n", 885 | "1972-09-01 6.70 NaN NaN\n", 886 | "1972-10-01 7.04 NaN NaN\n", 887 | "1972-11-01 9.09 NaN NaN\n", 888 | "1972-12-01 6.92 NaN NaN\n", 889 | "1973-01-01 6.42 NaN NaN\n", 890 | "1973-02-01 7.05 NaN NaN\n", 891 | "1973-03-01 6.97 NaN NaN\n", 892 | "1973-04-01 8.33 NaN NaN\n", 893 | "1973-05-01 8.95 NaN NaN\n", 894 | "1973-06-01 10.61 NaN NaN" 895 | ] 896 | }, 897 | "execution_count": 121, 898 | "metadata": {}, 899 | "output_type": "execute_result" 900 | } 901 | ], 902 | "source": [ 903 | "check_df = pandas.read_csv(urllib.request.urlopen(\"http://www.bundesbank.de/cae/servlet/StatisticDownload?tsId=BBK01.WZ9808&tsId=BBK01.WZ3449&tsId=BBK01.WZ3500&its_csvFormat=en&its_fileFormat=csv&mode=its\"), index_col=0)\n", 904 | "check_df.drop([x for x in check_df.columns if x.endswith(\"_FLAGS\")],axis=1, inplace=True)\n", 905 | "mapping = dict((check_df.iloc[0].dropna().apply(lambda x: int(float(x.split(\" / \")[1].split()[3])))).items())\n", 906 | "check_df.columns = [mapping.get(x,x) for x in check_df.columns]\n", 907 | "check_df = check_df.iloc[4:]\n", 908 | "check_df = check_df.apply(lambda x: x.astype(float))\n", 909 | "check_df.index = pandas.to_datetime(check_df.index)\n", 910 | "check_df.iloc[:10]" 911 | ] 912 | }, 913 | { 914 | "cell_type": "markdown", 915 | "metadata": { 916 | "cell_id": "14E8A39C932A4E21BE9320F55CC98C38" 917 | }, 918 | "source": [ 919 | "In the 70's and 80's there were no long-running Bunds.\n", 920 | "We can get a taste of how it is not a good idea to use Nelson-Siegel-Svensson for extrapolation when we compare\n", 921 | "the movements of (existing) 10-year rates with the (extrapolated) 30-year rates for that period." 922 | ] 923 | }, 924 | { 925 | "cell_type": "code", 926 | "execution_count": 126, 927 | "metadata": { 928 | "cell_id": "8991BC6673454423B3521DFD4CC5EF87" 929 | }, 930 | "outputs": [ 931 | { 932 | "data": { 933 | "text/plain": [ 934 | "" 935 | ] 936 | }, 937 | "execution_count": 126, 938 | "metadata": {}, 939 | "output_type": "execute_result" 940 | }, 941 | { 942 | "data": { 943 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD8CAYAAABn919SAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXmcXFWd9r+n9uqq3rd0p5N0NkhCQgiETRFBRFFBHAcd\ncUZx5NVxBt9x1JnXbUbHeX3V2ZxNR8ddUXHBBUEF2REhQICQQEL2rZNO71vtVbfO+8e5t+pWdVV1\ndXVXuiuc7+eTT3Xf2k66q5/73Of8zu8IKSUajUajqX0cCz0AjUaj0cwPWtA1Go3mDEELukaj0Zwh\naEHXaDSaMwQt6BqNRnOGoAVdo9FozhC0oGs0Gs0ZghZ0jUajOUPQgq7RaDRnCK7T+WZtbW2yt7f3\ndL6lRqPR1DxPP/30sJSyfabHnVZB7+3tZfv27afzLTUajabmEUIcLedxOnLRaDSaMwQt6BqNRnOG\noAVdo9FozhBOa4au0Wg01SSZTNLX10csFlvooVSEz+ejp6cHt9td0fO1oGs0mjOGvr4+6uvr6e3t\nRQix0MOZFVJKRkZG6OvrY+XKlRW9ho5cNBrNGUMsFqO1tbXmxBxACEFra+ucri60oGs0mjOKWhRz\ni7mOXQt6OUwNwJNfg0RkoUei0Wg0RdGCPhN774YvXQi//mu44xbQe7BqNJoSvPvd76ajo4ONGzdm\njo2OjnL11Vezdu1arr76asbGxqry3lrQZ+LRL4CvCS59P7zwM3j8Sws9Io1Gs4h517vexd13351z\n7POf/zxXXXUV+/fv56qrruLzn/98Vd5bC/pMJCLQeQ685jPQcxE8f/tCj0ij0SxiLr/8clpaWnKO\n3XHHHdx0000A3HTTTfziF7+oynvrssWZSEXB5QMhYMkmeP6nCz0ijUZTBp++8wV2n5yc19fc0N3A\np647Z9bPGxgYoKurC4Curi4GBwfndVwW2qHPRDIGbr/6umUlxMYhWp38S6PRaOaCdugzkYxkBb3Z\nLPYfPQxLmxduTBqNZkYqcdLVorOzk/7+frq6uujv76ejo6Mq76Md+kykYipyAeXQAcYOL9x4NBpN\nzfHGN76R73znOwB85zvf4frrr6/K+8wo6EKIbwohBoUQz9uO/bMQ4kUhxE4hxM+FEE1VGd1CIyUk\nozaH3qtuR7WgazSawtx4441ceuml7N27l56eHr7xjW/w0Y9+lHvvvZe1a9dy77338tGPfrQq711O\n5PJt4IvAd23H7gU+JqVMCSH+EfgY8JH5H94CYyQAmXXongAEO7VD12g0RbntttsKHr///vur/t4z\nOnQp5SPAaN6x30opU+a324CeKoxt4UlG1a3l0EHl6KNHFmQ4Go1GU4r5yNDfDfym2J1CiPcKIbYL\nIbYPDQ3Nw9udRlJmkxzLoYPK0bVD12g0i5A5CboQ4hNACvh+scdIKb8qpdwqpdza3j7jHqeLi2IO\nffKkKmfUaDSaRUTFgi6EuAm4FvhjKc/QBieWQ7cLestKQML4sQUZkkaj0RSjojp0IcQ1qEnQV0op\nz9wWhEnzv+ayCbrfXNIbGz/949FoNJoSlFO2eBvwOHC2EKJPCHEzquqlHrhXCLFDCPGVKo9zYbBi\nFbctQ/fWq9v41Okfj0aj0ZRgRocupbyxwOFvVGEsi4+UmaHbHbo3qG61oGs0mgLEYjEuv/xy4vE4\nqVSKG264gU9/+tMcPnyYt73tbYyOjnL++edz66234vF45vW99UrRUpRy6InQ6R+PRqNZ9Hi9Xh54\n4AGee+45duzYwd133822bdv4yEc+wgc/+EH2799Pc3Mz3/jG/PtiLeilyJQt2h26jlw0Gk1xhBAE\ng+pKPplMkkwmEULwwAMPcMMNNwDVa6Grm3OVIlO2aHPoHi3oGk1N8JuPwqld8/uaSzbB62benMIw\nDC644AIOHDjALbfcwurVq2lqasLlUpLb09PDiRMn5ndsaIdemkzZYl32mNOlHLsWdI1GUwSn08mO\nHTvo6+vjySefZM+ePdMeU43NrLVDL4Xl0O0rRUFNjGpB12gWN2U46WrT1NTEFVdcwbZt2xgfHyeV\nSuFyuejr66O7u3ve30879FIUWikKKkfXgq7RaAowNDTE+LhapxKNRrnvvvtYv349V155Jbffrraw\nrFYLXe3QS5GKgsMNDmfucW+9rnLRaDQF6e/v56abbsIwDNLpNG9961u59tpr2bBhA29729v427/9\nW7Zs2cLNN9887++tBb0U9u3n7Hi0Q9doNIU599xzefbZZ6cdX7VqFU8++WRV31tHLqWwNojOR0cu\nGo1mEaIF3WKiDwbzZqKTsdySRQs9KarRaBYhWtAtHvgM/Pim3GOpaG7JooV26BrNoqWWm7/Odexa\n0C3iU6rPuZ1krHjkoidFNZpFh8/nY2RkpCZFXUrJyMgIPl8BzSkTPSlqkTYgMZW7KXQyUnxSNBUD\nIwlO9+kdp0ajKUpPTw99fX3U3O5oJj6fj56eynf01IJukTa3SA0PQ9My9XUqBp7g9Mfa+7nUtZye\n8Wk0mhlxu92sXLlyoYexYOjIxSKdVLfhwewxs2yxbyzC+3/wDMOhuDquG3RpNJpFiBZ0i7ShbsPD\n2WNm2eKn7niBu3b286Onjqvjuie6RqNZhGhBt8hELrbsLRnjRBjuf3EQn9vBT5/uU5Mtuie6RqNZ\nhGhBt7AEPWSLXFJRnh9MsLItwN9du4FDw2GeOTamW+hqNJpFiRZ0C8PK0G2RSzLGSNzBluVNXH/e\nUvxuJ+/73jPc8tP96n4t6BqNZhGhBd0ik6GbkYuUyFSU0YST7kY/Qa+Lj1xzNms7gjx9ynTzWtA1\nGs0iYkZBF0J8UwgxKIR43nbsLUKIF4QQaSHE1uoO8TSRydDNyMVIIGSaSNpNV5Mq9H/Xy1dy680X\nI3w6ctFoNIuPchz6t4Fr8o49D7wZeGS+B7RgpPMiF7MXehwP3Y3ZxUVOh2DDii71jZ4U1Wg0i4gZ\nBV1K+Qgwmndsj5Ryb9VGtRDkV7mY28/F8LCkMXcp7kWr2glLL/HD2+DOv8rm7xqNRrOA6Azdwl6H\nnk5nHHpM5jp0gEtWtRLCj/fog/D0t2B43+kerUaj0Uyj6oIuhHivEGK7EGL7ou6vYLlsaUB0LOPQ\n0y4fDf7cDgnndDcQxtaFMTRwukap0Wg0Ram6oEspvyql3Cql3Nre3l7tt6ucdAp8Terr8FBmwrMu\nEJy2O7fL6eCXjW/n+43vUQfstesajUazQOjIxSKdggZzF+7wEOy+gxROJprOKfjwF9tfzw/TV6lv\npk6dpkFqNBpNccopW7wNeBw4WwjRJ4S4WQjxB0KIPuBS4FdCiHuqPdCqkzag0eyyuPc38Oz3eEhc\nhL9lacGHdzZ4OTrlAHdAO3SNRrMomLF9rpTyxiJ3/Xyex7KwpJPQfhb4m2HblwD4euLVXNRUoB86\n0NHgYzKWIt3cgUNn6BqNZhGgIxeLdAocbrj2C9CxgUT7Rral19HdWHj3kI56LwAJX5ueFNVoNIsC\nLegAUipBd7rBE4D3PsSOV/8AEHSVcOgAEY8WdI1GszjQgg7ZGnSHmUC5vBwYV5Utq9sDBZ/S2aAc\n+qSzRQu6RqNZFGhBh+wqUYczc+jgUAif2zFtUZFFR71y6COiCWITancjjUajWUC0oINN0LMbPh8c\nCrGqLYjDIQo+pbnOjdspGEibtevapWs0mgVGCzpkG3M5skU/B4dCrO4osEG0iRCCjnofJ1IN6oAu\nXdRoNAuMFnSYlqHHkgZ9Y1HWtBcXdID2ei9HE+ZjtEPXaDQLjBZ0mJahHx4OIyWs7ig8IWrR2eDl\nQMR8TEivFtVoNAvLjAuLXhKYgv74kQlOOMyNoIHVMzj0jnof2w/5AKEjF41Gs+BoQYdMp8Xbnx3g\np08/h8/tQAhY2TazQx+JppGtbQjdz0Wj0SwwOnKBTIbe1RLgs3+wiVgyTU+zH5/bWfJp1uKiZN0S\nmDxZ9WFqNBpNKbRDh0zk4vV4efvFy3E61OLRmbBq1EO+LlomjldzhBqNRjMjWtAhU7bodnsA+KML\nl5f1NGvz6DF3By0Dj6mzgChct67RaDTV5qUduUwNwL57Mg7d4/HM6umWQz9Fm9owOjah7njh5/Dj\nd87rUDUajWYmXtqC/uD/gx++HQxT0N3uGZ6Qi9/jpCXg4ZjRog5M9CmX/tA/wu479ObRGo3mtFLb\ngr73bnjsi5U9V0o4cB+kU8hEGACP1zvrl+lq9HEgbi7/n+iDk8/A0B71veXYNRqN5jRQ24L+3A/g\n4X8qbwYzn8E9MHkCgGRU7R8628gFoLvJz55Io/pmsg+e/X72zuj47MelOS0Y6Qo+MxrNIqe2BT0R\nhviE2gP0vr+Hx/6r/OceuDfzZSwyCYC/Aofe3ejj+Umvauw1ehh23Q7BTvOFtaAvRkbDCTZ+6h4e\nPziSOfbIviHu2qlLTzW1TY0LekTdDu+Dp74J++8t/Xg7B+6zvYxy6N4KHfpkLE26YSk8/zN1gjnv\n7erO6NisX09TfQYmY0STBi+emswc+++HDvBPd+9dwFFpNHOnxgU9pG73/1YJacrWkzw8Ao//Nxzb\nlm2+ZZE24OjjUN8FQDKq/rB9lTh0c0ejWF0XTJ1UTn39G9WdOnJZlEST6vMwGk5kjg1Oxukbi5BI\npRdqWMWREr57PTz9nYUeiWaRU+OCriYz2XW7uk1Gs/fd90m452PwzdfCA5/JfV5sQtWet64BwDAz\n9MoEXdWiT3rMmGXFpdC4zHwfLeiLkVhCCfqITdAHJmOkJfSNRRZqWMWJjMChh+BXH4aTzy70aDSL\nmBkFXQjxTSHEoBDieduxFiHEvUKI/eZtc3WHWQRL0M3JzYygjx6CHbfB+TdB0woYPZj7PCsKMbNu\nI66cfkUZuunQh53t6sCaV4PfrHrRDn1REkuZDj2kBD0UTxE2Rf7oyCIUdGsVsjTgp++ZfsWp0ZiU\n49C/DVyTd+yjwP1SyrXA/eb3px9L0C2syOWRf1UbPl/5cRWr5GfZlnOuXwKAjCuH7vfPXtA76n04\nHYLjqPiGta9R7+0OaIe+SIkmVKxiRS6Dk9mo7vCw+kydHI/ygR8+y/HRRSDw46agv/wDMLJ/dnNF\nmpcUMwq6lPIRYDTv8PWAFeh9B3jTPI9rZqSEZJ6gWw796KNw1jVKsP3NEMkXdLM+PNihXiquXqfO\n55v1MJwOwZIGHw+4L4f3PAgd69Ud/iY9KbpIsTL0kXAcgIHJeOa+oyPqs/Cvv93HHTtO8n9u35lp\np7xgWA79kr+A4BLY/g31fSoBv/prGDlY/LmalxSVZuidUsp+APO2Y/6GVCapGMh0JgcnuCTr0BOR\nbOxR1zJdWK0oJKgcukhagj57hw7QVu/lVDgNS8/PHvQ16chlkRLLmxQdnFKfm6DXxZGRCIeGQvz8\n2T7O6gzy+KERbntygRuvTfSpK75AO1xwk3LoY0fg8CPw1Nfg4AMLOz7NoqHqk6JCiPcKIbYLIbYP\nDQ3N3wtbccu6a5UbX/d65dClhGRE/QGAcujRvAuMTOSiMnSHKeh+7+zLFgHagx6GQ4ncg/4mHbks\nUixBH4skSRlpBszI5YIVzRwZCfOFe/fhdTn5/v+6hAtWNPOVhw8urEsfPwaNParx2/k3gXDA9m/B\n3l+r++3FAJqXNJUK+oAQogvAvC26XY+U8qtSyq1Syq3t7e0Vvl0BrJLFtrPg7T+C+m41aWQkldh7\n6tT9/mYl8ElbSWOeQ3eagi6cFQp6vZehqXjuQX+zduiLlGgiO6k4FkkyMBmnzuNk49IGjo5EuGtn\nP++5fBXt9V7eftFyjo1G2H50AeOziePQZFZONS6Fs18Hz94Ke3+jjtnLdTUvaSoV9F8CN5lf3wTc\nMT/DmQWWQ/eYTtytqk2UK5bgVoI+IRrUcXvsEhsHpycTy7gMc+LLUXpDi2K0Bb2MhuO5y8l9OkNf\nrFhVLqBil4HJGJ0NPnpb1WdpZVuAv7hiNQDXbFxCncfJT5/uW5CxAipysUphAba+W5UyTpkrW7VD\n15iUU7Z4G/A4cLYQok8IcTPweeBqIcR+4Grz+9OLtUrUY+776TYnNCNqOXcEL++79Wk+freZf9pj\nl+g4+JpIO1Vm7jbMPwhHZe3h24Je0jJ3oYqOXBYvVpULqInRwck47fVetixvot7n4rN/sCmzW1XA\n6+J1G7v41c7+HGd/2kiE1We6sSd7bNWV0LIKEOozqx26xqScKpcbpZRdUkq3lLJHSvkNKeWIlPIq\nKeVa8za/Cqb6WJGL5dBdpkM3BX3b8Rh3v3CKhMeqCc9z6P4mvrmtX72E5dCds2ufa9Fer04MwyFb\n7OJrUlFPKlHkWZqFwqpyAdOhTymHvqajnp2feg2Xrm7Nefy1m7uYiqd4eiFilwlzjUWTbdMVhwNe\n+zm44mPm50w7dI2idleKZiIXMyu3HHp4GID942lWtQVY1r1UHY/YzjmxCfA1cvtzapLWl7Yil8od\nOuQJulVlo136oiOeNPCbDjwTuZgnZVFgx6kty9TvcteJBWiHPHFM3dojF4Czr4ErPqKiRe3QNSZn\ngKBbkYsp7KZDf3HEYPOyJoLNZkWl3aFHx4k663lxIERcunEJ8xJcVJahWw49Z2LU35x5L838Eksa\nfPmhgySNyvquRJNGZvvAI8MRYsk0nQ3F1yA01XlY3lLHrhML8Lu0FhU1LSt8v9unHbomQw0Len7k\nYmXoyomfijo4b1kTDS1K0ONTw9nnxsY5EVcinBAqZknjUJeyFdAWVNUx0yIX0BOjVeDR/cP8490v\n8kyFEUg0aRD0umiqc2dEuqOh9BqETT2NC+PQQwPq1qzImobLpx26JkMNC3qRKhdrUlR62bysifbm\nJuLSTXjcVgMfHefgpIuzO+txmM8zROX7ZQe9LrwuR55D15FLtTCGD/CQ54PERyurPIkmDHxutX3g\nU0fGcDsFF/a2lHzOuUsbOT4aZcyc+B4LJ4gkUhW9/6xIRlVFlrPI59Pt1w5dk6F2BT1p5t5W1OLK\nrXJJOvys76qnu7mOcQJZh55OI2MT7J9ycdX6Dlxe9TxZYdwCKndtr/fmLi7KOHQt6PONd3g3vY4B\nnCMvVvT8WCqN3+2kNaCurG64YFmmyVoxNvWoXal2nZjg+GiEq77wMFf880Pct3ugojGUTSqenfAv\nhHboGhu1K+iJkBJzq3Y8k6Er4V7a2YbX5WRJg48xWY8RMidF45MIJGPpOs7tacLjVc9zFHNAZdIW\nzFtc5GvMvF9RIqNw65vVSkBN2aTNk6QRrqy4KpYw8LkdtAa8uByCW65cPeNzNi5Vv8+fPtPHe767\nnZSRpqnOzS0/eIZUhVl+WaRi4CoRB2mHrrFRw4Iezoo4TKtDX9KmLqGXNPqYIADRUcb+51qmHvoP\nACYJsKGrAWE6e5e7slWiFsqhK0FPpNL0h8zSOKNE2eLe38DB+6H/uTm990sNaTZXS1d49RM1q1ze\nd8Vq/vPGLfQ01834nAafm3O6G7hjx0kODoX4r7efz00v6yWeSjMUis/4/IpJxbJXn4XQDl1jY262\ndCFJhLP5Odjq0JVr8wXqAXA7HUScjXROPYN7MklsYLt6uquBnmZ/1v1UWLJo0Rb08uwxNUn393e+\nwAM7D7MNSgv6oYfUrZGc03u/1BBxJeiiwgnnWNLA73Fy3rImzjNLEsvh9ve9jKGpOEGfi5aAh/v3\nqLjl1ESMrsbSkU3FpGJZs1IItz+3rYXmJU1tO3SrZBEyH3oZGSEtBXX+7H1JTxNuqUTTl1aXp00t\n7TgcIut+5ijo7fVeRsIJToxH+cn244xEzTYARpGJMynh8MPq63I2LLjrQ7DjB3Ma45mC04yxHPHK\nqk6iSQOva/ZzJn6Pk+WtdbSY2fuSRvXZOTVRRUFNxUtHLi4fpHTkolHUuKBPd+giGSGKh4a6bIQi\nzZrwfemlmWMdHeaWcRmHXvmkKChBlxI+/OMdJA1JEvP10kXc99DebElascdYpA145rtw/z8oN3/i\nmdyFUi8xXEm1IYkrUWJ+ogSWQ58rS8za9VOT1RT0GSIX7dA1Ns4cQXe61AbNqD4uDb6s43YEVJ6+\no/tGXkyrBRrdXeYOQxmHXtmyf4vXb1zCuT2NbDs0yrIWPyBIC1fxOMWKWwDSM5S/TZ5Uoj/VD3d/\nDL5+FTzyz3Maby3jTSkh9yRm79BTRpqkITMrRedCS8CDx+morqAny8nQtUPXKM4cQYdMLXpUemnw\nZwU60XYO/bKFFZf9ETsbX0Vculm5zFx5N08ZemvQy8/+/GX8141b+Le3ngdA2uEq7r6Pb8v2bJ9J\n0MeOqFvhVBsayDT075zTeGsZn6EWlVnCPhtiKVWR4nPP/aMvhKCjwctAVSOXMhx6OqXnYTRATQt6\naLqgmx/8CD4afFlB33LlH/LDy+7hgvVrkC//AG9x/AtnLevMec5cBR3A5XRw3eZuzl6iJmQNXMUz\n9HgIAmYTqGKPsRg/qm4v+yu1a83Ky2HgeZXDvwTxp5Wg1xmzF3SrY+J8OHSArkZflSOXMjJ00KWL\nGqCmBb2QQ1cf7iheGvxZge5u8vPBq8/C5XTw1otXcfsn3kmdx7zf+mOZYx26naDXhd/txBDO4g7d\nSMzOoQuH6q734b2w/o1qBerkyXkbcy0RSIfN29Csn2vtVuSbJ0HvbPBVeVK0DIduPU7zkqd2BT0Z\nKSDoqp44Ir05Dt2OEAKPy/bfnkeHbn+P9novSeksfilsJLOdImeaFB07qvphO91q8rZzozo+8MK8\njblWSBlp6lGCXi8rF/T5mBQFNTF6ajJWvS3qyhV07dA11Kqgpw1T0IO5xzORS26GXpJ5ytDz6aj3\nqkqXYu7biGcXRpXj0JtW2F58vbodeH7O46w1QpEoAREnjps6EcdIzm5Rj9UL3VdB2WIhljT6iCXT\nTEar1Ndlpjp0S+y1Q9dQq4Ju9XEpNimKl3pvmQJdBYcOqntfIl3KoSeygj5Thj52BJp7s9/7m1R/\n7JegQw9PqJXAg44O8/vhUg+fRiZDnyeH3lmgdHEkFOfg0OyvHgqSimuHrimb2hR0q9OiO2/JtvnB\nTzr9atFQOVTJobcHvcSlo0SGnsy+dymHnohAeBCaV+Qe7zznJSnokSlVfz/mVWsKopMjs3p+tspl\n/iZFAfonsoL6L7/dy41f3TY/McxMvVy0Q9fYqE1Bj6uFJXjrc4+bAm84Z7EMu2oO3Uc87cRIlXDo\nLq+qfy8l6FaFS/PK3OOd58DwvpfcFnfRSSXokTq1x2ZssjKHPh9li5B16AM2h35iPMbgVJy+sTm6\nZiOlPhului1qh66xUZuCPqX2AiXYmXvcWv6f79xLUS2HXu8lhZNEvIhzMpKqz3WpWnVQE6KQm6Fb\n30sDQqfmZ8A1QiKs+rcYjWqPzfjU7FbMZiZF57HKBeDURDbLHzGbde3sm+OGGJbr1g5dUya1KeiT\npqA3dOceN53M7ATd/IOocIPoYmQEPVFk0s5IqPd0ukv3crFOXo1Lc4/Xmytdp15agp4Kqw6L7rZV\n6vvQLCOXea5y8bgcNPrdjITtgq6umnb2zbEXfsp8TZ2ha8pkToIuhPiAEOJ5IcQLQoi/mq9BzciU\nWX9tiZqF6dBF/mRpKeapl0s+VpVLKlkkEjESRAwHkwnJeChS/IWsbo35f9T15pZkluBbREZhYHdl\ng64BjIhy6HWdq3O+L5d5rXKREtJp2oKeTOtkKWVG3Hccn6ugmyKtHbqmTCoWdCHERuA9wEXAZuBa\nIcTa+RpYSSb7wdsA3ryyRdOtOGYl6NXJ0DsbfKSki2RRQU9yYsognnYwMhku/kKWoDvz+rUXc+i/\n/w+49Q8qG3QNYPVCb16qBH22PdGjc3Xop56Hb75OzeM89XX4j3NpC3gYnlK/p8lYiqQh8TgdPH9i\nAiM9h4lRy6G7dYauKY+5OPT1wDYpZURKmQIeBk6Pkkz1Zx2qHTNycfoWXtBbAx6k010ycjkVSpPC\nSSxRYmKzmKDXtaoJ1XxBj01kJ43PQERsgpR00NLczqT0z7on+rPHxmnwqT1gK+L4Njj2mKowOvE0\nTBxnSdCRcehWfn7xqhbCCWNu5Ys6Q9fMkrkI+vPA5UKIViFEHfB6YFn+g4QQ7xVCbBdCbB8aGpr2\nIhUx1T89bgEMp/rgu3zBafcVJRO5zG+GLoTA6/WSLCTWUoKR4MSUgYGDRLzE4hirjj0/43c41Ekt\nX9CN5MwLlWoYR2KSkAjg8ziZJDCrnui7+ia4d/cAN1+2CiHKLGvNxzqBjB6C8eMALPWnMrsWjZib\nSL9qnaqTf/LwHNocZwRdZ+ia8qhY0KWUe4B/BO4F7gaeA6YpiZTyq1LKrVLKre3t7RUPNIfJ/ukT\nokBCKBfrmZWgWw59fjN0AL/Ph5FMTK9HNkX65JRBUjpJJEtUuRgJdfVQSIDql0zP0I3E4hf0I7+H\nX324ouZirsQkYRFACEFIBHHNooXuv9+3j0a/m3df1jvr981gRTyjhzJ7wS7xJZmKpYgljYxDv7C3\nhZVtAX69q7/YK81MsgyH7vQAQjt0DTDHSVEp5TeklOdLKS8HRoH98zOsEqTTqlSvgEOPSPXB99TV\nT7uvKFUqWwSo8/twyBT9+c2bzBglmlYNvFKllq8biZy4JZowuP5Lv+dHTx0r4tATqpxxMXdi3PNL\nlT9XsIWcOzlF1KlO2FFHAFeyvEhjKpYkvO8h3nNBPfVF+vyUhTXm4f0weQKAdq86gY6EEwybFS7t\n9V6u29zN44dGGKy0G2PGoZfI0IXQG0VrMsy1yqXDvF0OvBm4bT4GVZLIsHKgBRx6VKo/VF9dBQ59\nnssWAYJ+Py4M9p7Ky7RNQU/iwuP2kizp0JPgdPN/79rNdx47wpcfPshzx8e554UBdVKb5tDN11rM\nLt0as9XnfRZ4U1PEnOqEHXPW402VN19w8MQA33N/ltdFfz3r98zBcuhHH1MnTqDVo37mw1PxTMli\nc52HN27u4jrxGCd/9onK3itTtljCoYPeKFqTYa629KdCiFYgCdwipaxs197ZYLWMrV/Ck4dHGZiM\ncd1mJe6jlsMTAAAgAElEQVQDTReww7iE9vZZFNtU0aE3BPzEhMHegSmuNDNVICO6Xq8Pj8dDOpQk\nnZaF2xUYCaTTw3ceO0IqLXEIZcp2nZhArlqCiI0rd2ZlqdYkqnkiWJRMmVvvjR9VLnffPXD9F8t6\nqi8dZtzbBkDSXY8vdrCs5w0d3IFLpGl3z66Z1zQshx4ezBxqccUBVbo4Eo7T6HfjcTlY0x7kY77b\nqT8aAv519u9VToYOaoW03oZOw9wjl1dIKTdIKTdLKe+fr0GVxHR3qcASPvTjHXz8Z7tIm6Vhx2Ub\n70/+JfXB2UQu1cvQPR4PXmGwL8+hJxLqj6+3swmXy4VDGoxGiterG8JFKi05qzNIW9DLn12+mqGp\nOBMuJWw5sYsl6IvZoVurW8eOwM4fwbO3lu3W/ekIhltdgRmeevzpEiWfNmInVGfKelcZG3KXokBM\n1OQ0HXpIOfTWoBmRnXiarvQpgjKETJRYa1CMcqpcQK2/0NvQaajFlaKmQ7+3z0HfWJSpeIojI2ES\nqTRffPAAS5v8rO6oZGHR/Dt0HG68jjS7TkyQNNKZw88cVu5u0/J2nG4PToycXiA5GCmS5oXUZ960\niW0fu4qrN6iWBwdiZrSUI+iLPHKRMjvesSMwuEd9faA8P1AnI6Q96oQtvY0EiZReaWviHnkRADHX\naCI6BnVtOYcaneo1h0MJhkNx2gLmZ2rnjzOPGR88Pvv3ssZaqg4dVMY+U4b+6L/BjuonopqFpfYE\nfeoUUjj4j20TNNepSGFn3wRf+90hDgyG+L9vOgfvbFYBztMm0QVxuvE5DPYPhrj2Px/l6aPK3f1u\njzopnb20BZfLjVsYDE4Vr1ePSyXovW11OByCDV0NOAQ8P2n+odtz9MXu0GMTWaEa2qeqRQAOPjDj\nU5MpgyBRpLcBAOFvBCAdm3krutbwAfXFXJyslErQl56vvjc/O+5UhKDXxdBUnJGw6dCNFLzwM+Je\ntc3gSP+x2b9fuRm621dY0I2Uat4WHYcHP6v2o9Wc0dSeoE+eJOVv48XBKB+5Zh0+t4MnDo/yPw8f\n5NXrO3jVus6ZX8OOywsb/xBWvGz+x+pw4cHga+/cymQsyQ1feYybv/0UTx5QAux2+3B7vDgxildC\nGAnihoOAx0l7UP1h+z1Ozuqs58lh8w+9lgQ9ZObnTg8cf0JteB3shEMPz7jRcWhqAoeQCJ9y6E5T\n0EMTpWu9JyJJVqbNJmdzyZqTUbUxSfcW9X3bWeo2EaIt6GEknGAkFFeCPnIAwkNMrXsrAJNDFTh0\nS6RnytDtk6JpQ/0fhw/AF7fC994Me3+tPhdDe1WVmOaMpfYEfeB5Bjyq8+DVGzo5p7uRn2w/zmQs\nxXsvXz371xMCbvgmrHrlPA8Us/FWkqs3dHLvh17J/7psJUdGwtS7zT8qpweP240bg4HJYg49SSTt\nYEVrIGcxzKaljTxx0kD6W7Kxhfl4YPEKunXy6TovUyXCRe+BxBQcf7LkUyOTqsLE4VMO3RVoBiA0\nwyYXh44eok2YLn4uDj1mVrjUd0HTcujYoKK6RIi2oJeBiRhjkSStAS9M9AFQt/Yy9dTRvtm/XznN\nuSC3bPEn74LPdsFXXq4mnI/8Du7/B3VfIgQTFZxYNDVDbQl6KgGDu3k2uYL1XQ20Br1sWtpIKi1Z\n39XAhb3NCz3CXKxe51IS9Lr4xBs2cP+Hr+Cb7zhP3e/y4HC68TpkiQw9QTjlYGVb7rzAhu4GRiJJ\nEp1b1BJ02+PV7Qz7lC4UVoXL8ovVrcMNF7xb3b54V8mnWptbuOqUM/cF1e87PFm6uGr00A4ApMOl\nRDKVgF/cklkYRLjMjo3WhKi/Gf74drj602obxLgS9CePqPGdvaQ+I5x1y84jjhtjsoIFRqkYOL1I\n4M9u3c59uwcKP85y6GNHYc+dsPJy2PQWeN+jaqerqX5YZv68h16c/Tg0NUNtCfrQHjASPDDRzWVr\nVDa5eZn6437Xy1ZUvpy7Wlhlg/lu2d6fxakmTjOCfu8n4bd/l3lo2kgQSjnobcttCby6XU2IDjac\noxy61b8l49DnWM1RLawKl2WXqNu2syDQCmdfA7t+UvJEFA0ph+wJKIfur1eCHpuhJ/rUsZ3qi44N\nysmOHoQd31Mxz+hh+Jc1cPh3M4/dLujtZ6uFXd56SITpbFDx14evPovXbVyiHLpwQn0XY44WnOEi\nYlwKc/u5gck497wwwLceO1z4cW6/2pbx6W+rK87rv6TKQNvPhlf9HQiHuoXcqznNGUdtCfpJ5bSe\nNVbwsjWq0uB1G7v4zJs28gdbehZyZIWxBD1fpDL9WTzgcBJwS363f5hDQyG1LP7Io5mHJuIxEtJF\nb2uuQ1/doQT9gOdsQGZ+NtkMfbE69FPgDqgdlyC74fXmGyE8VHJyNBFRy/x9gSYA/A3qpJ4MF++4\nKKVkdOgUaQSiablyslY8kQgp4ZVp1XRrJuyCbuEJQGKK912xmltvvoj/fdVaZSwm+qBhKTichDzt\n+GODhV+zFKkouLwcGFSrYZ84NMpEpMDvtblXXW08/kU46xpotP0tbLoB/uYgrHwF1HdrQT/DqS1B\n799BzBngpGMJF/W2AGpvyD+5ZAWeSrvnVROrciZfXDMO3Q0ON61+Jz63kw/++DmGx8YIh7IClYjH\nSeKaFrl0NfjwuR1sT5rzBie25772os3QTyln29gDwSXQ+3J1fM3VqoPkjh8UfWoybAq6GbU0NLaY\nx4tHLgeHQiQSMdIOj4omktGsoMenlKhDefuzFhR0Fbl0Nfp5xVpbr6KJ4xlhTfg7aEyNzH6P0VQc\n3D4ODKqrr1Ra8uDeQeIpg0/8fBd/9D+PMxZOwCv+Gi7/G3VFcMlfTH+dOvVzomOdusrVnLEsQhUs\nQf9z7BOrOG95KwFvFerG55uMQy8RuThcuEjxqes28NzxcSKhSSJT2YZTyYQS9FXtue0MHA7ByrYg\nL4w71X6jfZagV2lS9Kmvww/eNvfXCQ0oQXe64YMvwAV/qo67PLDuDXDowaJPTUXVz6XOjFoampRD\nL9UT/dH9w3hJ4nB5zAU4sVxBj1ci6E3ZY95gdtNyOzZBp34J7YxlOjGWTSoGLh8HhkI0+Fy013v5\n1mNHeOtXHuf7TxzjmWNjvOObTzCRFPCqv4WPn1ROvBgdG8xKl0Uax2nmTO0IeiKCPPU8T8aW8fLV\nbTM/fjFgLVaa5tBtkYvTBWmDN5/fw4N/fQVtXgNvOsLglMrUU8kYTreHlkBeP3RgdXuAQ0Nh6Nma\nnRjNTIrOs6Aff7K8WGIm7L3snXldJAPtSmCLOFlp1psHGpSguzxeIngzxwvx6IERWnzgcHnVApxU\nLFvpkgip6hpQZYYzlTRGx9Xv1GM7uXqCWZdvkTbUAjhT0N1NS6kXUU4Olrmhdf9O+OX/hkQkE7ms\n6Qjy2nM6ee74OENTcb749i189R1bebF/ik//0jwZOXL/nA8Phzk6YjvZtK9T///RIlm8puapDUE3\nUnD7u8FI8FvjAi5b27rQIyqPohm6PXJxZdz0yrYAXhkjQIztZh9tI5kk6C+8UnBVe5C+sQippl4l\nlOl09SKX6PjcTxLWKtFggc1JQPUkkUb2/5D/dFO43f6GzLGwCOCIFxZ0Iy154tAIS+udar2B26dE\nO8ehm4Iu0zNXgETHVNxiPwmZkUsOoQH18zcFPdiubgdPHin9+hYv/Aye+a66anD5ODAYZk1HkI++\nbj13vv8yHv3Iq7j23G6uXNfBn1+xmp89e4KH9uZm9PGUwR9/bRtv/9oTxFMGKSON7Nmq7jz6+/LG\noak5akPQ7/k47PsNdy79ILs9mzi3p2nm5ywGimXoVn2xGblkBF9KHKkoTiHZcegkkUQK0gnqA4U3\nvV7dHiAtYSxhroxNRgBZ+D3N12d4f2WtdWMTc59onTqlxtiysvD91taBhSIMQCRCRPEqZ28SdQRx\nJgt3XDwwGGIqnqKjTqiftcvseWK9fjyUK8aDM+zFagm6HW8Bh27WoNOo9ntpXaLWTYyeKnO16LDZ\nhXqyj5TDy3Aozur2IEGvi009jTlN3N7/qjWsbg/w6Tt352T0P9nex8mJGCfGo/zn/fu55j9+xyce\nTaqT6eGHyxuHpuaoDUHf9Ba46pN8YfxyLl7ZgttZG8MunqHbq1zc2UwzGUWYgrz76En29E/hJkVj\nfeHeNKva1KX/sLVWxr71XCGHfvhhtXrwvr+fvajHJubu+kfNzogtqwrf7zZPXMnCjawciSkiIvfk\nFnMG8RQR9GePqcy71Ydy6NYCHXNfUhW5hNT7unwz5+iFBN0TKCDo5uId06F7WpYDEB86VPr1LUay\nHSTDhjp5reko3BLa63Jy82WrODwcZt+AGsfAZIz/fvAAF6xo5qKVLXzpwYMcGAzxzLFxtYDu0MN6\nxegZSm0o47ILGdx8C0dGIly6ukbiFiiRodsjF2f2fpuQnRwY5JF9Q3hI0VxM0NvV8VOWobULS6GJ\nr76n1O3v/x22/fds/idqlaS5SKpiLKFqLbKiN+PQCwu6Kxki6sj9WSTd9fiMYoI+TlOdmzpnSp08\nrSZX1uRmfFKdBH2Nqnxy4PnS44+OgS/v6tBTr36fKVtMlHHo5qRocy8x4SM4VsainrSR7W8DTKXU\n1VcxQYfsdncPvDjIZ3+9h0s+dz+nJmN8+DVn8Xdv2MDmnkYuW9PG4eEw6d7L1Z4CM12NaGqS2hB0\n4IV+lZNuWtq4wCOZBRmHnpcJZwTda7YHMJ2vLWpoEAn+84H9eIRBoEiGHvC6WNsR5OC4eUKwZ8mF\nFuj071Q1y+3r4dBDs/u/WK52Li599KAS1sZpW88qMg69cOTiMsLEnbmCbrgbirbQffb4GFuWNSFS\niVyHnhH0kBJ0TxBaVquVlqUoFrlA7sl0og+8jWC2KMDhZDiwlu74fox03glxKm/B0cRx1S8GFauM\nJBzUeZz0NBeO3QCWNPo4p7uB7207ylcfOcR153Zz74deyctWt7Gpp5E73n8Zbzi3i3gqzalWc8Xo\nbH//mpqgZgT9xX7lwtZ1NczwyEWEY6bIxZ2bodsc+oeu6EJKcJNCuKZXuFhcuLKFfcOWoM8QuZza\nCV2bIdgOZXQozJBKZMc2F0EfOahOKMV6z8+w4bEvFSKZJ+hpbwMBGc70xLeYjCXZPxhiy/Lm7DZ+\nGYduriy1IhdvMLudX7ErECkhPAyBvAorTwFBj46p1a82Yi3rWc9RTozarj5O7YJ/PQv6bK0bhlVX\nyGOBjQD0h+CCFc04C21+YuNV6zo4MR6lvd7LZ9+8KbOS2GKVuY5hf7xJlbnOR8WSZtFRO4J+apKl\nTX4a/Yt0F55COEtELg63qpZwuACpMk1b1HD5ch//+bbNuDBy9hTN58LeZiaSpkCWEvTYhOo/vmQT\neBty3fxMzOT8y2X0kHLCxZghcvGlI6TcuUIl/I3UE2EymnsV9NzxcaSELcub1CS005NtQ2vVrVt1\n6N561XArFc1eieSTCKv7A3kbnVtjtk+uJqPZqw0T19LNNIgIfUf3ZQ8O7VW3g7bsfkQJ+q3jm9Rd\nUbh4ZUvhMdl47TlLEAI+/vp1BAus0bDWMRwaCpn16PumPUZT+9SOoPdPsW7JLHYiWgw4SpQtWiKd\nydlTuVFDPMQbN5riUWIruQt7W4hj3l9I0I0kPPFVOPq4+n7JZlPQy9uLE8gKoP11Z0s6rQS9WH4O\nM0YufpndrcjC6W/EIwzGJ3NPULtOKGE+t6dJ/bytOnSAiOnQkxF1svLUQ4O56Xj+Hq0WEbOGPF/Q\nveZn0u7Qk5Fpm1K0rLoAgNDRZ7IHzU2mGbd1QBzZT9QR5PH0BgDiuLlo5czzRhuXNvLUJ15dtAVG\nW9BDvc+l1i20n63ir1SB8tBkVF2JaGqSmhD0eMrg4FCIdV01JuiWaBdaWGSJtH3i1O5ME1PZrL3E\n5htLm/wEApZLLCDoJ3fAb/4GfvHn6vuuc1W2O5vIxe5aKxX0yRNqUUuxChcAjynoBRx60kgTJJLZ\n3MKivlGJ3bGTuUJ8cFA1zGr0u22RS16GDkrAvUHl0K3vC2GJXDmRi32PV5OGFZsxcCBO2SZerf1x\n7S1tRw7Q51zKAbmUlHQQFXWZBnQz0RYsvhGGEIJV7UEODYfUAqN0KmfyNcMj/wxfu7Ks99MsPmpC\n0A8MhkilJeuW1FB+DtnIZVqGHs+Kvb0jY55DzylvLIIQgtVdpsgUikasVZHRUQh0ZDsExifLL12L\n2Rx6pZGLVbLYuqb4Y9zmiamAQ5+KJgkSzTpik64lapHS4aO5E5qHhkOZsk7VtdDm0O2CHh1Tomyt\nXrVv52cnPKRupwl6ocglMi1ywVNHv3MpgbHd2by/kEMf3s8BYwl1gXr+JPlxdnXdMLsduEqwui2Q\ndehQeCHV8D7V6KuQe9cseuYk6EKIDwohXhBCPC+EuE0IMUMn/sqwJkTX19KEKJRozpWcHrkYqTyH\nHsotbyxBT7sqpUtGCjhp6zUC7dk+H94GQBaNNqaR49ArFPQCJYtSSr77+BE+9xuzYVQJhx4KTeIU\nMrO5hYVnxUUAuI49kvO6BwdDmbJO5dC9WYeev8nFrBx6fuRinjQOPQhPfUN9XcChA8SXnM/GxHN8\n7d5n1YGMQzcXHI0chMkTPBHv5S0X9LDPfx4XnHNW4fFUwKr2AP0TMSKNqwCRzfDtWCe0SJk94muR\nqQH48mXZDqVnEBULuhBiKfCXwFYp5UbACcxD96bp7OmfxOty0NtavHRrUVJq6f+0yCWVu6CmTIcO\n0FivXGs0ZHPoVh269Rpvuw3e/HX1tSWK5cYudodeaWOnyZOqL7clnMCnfvkCn7zjBf7n4UPEkkbx\nhUWRUSb2PQaAP5hXB968ggFvL6vHH88435FwgslYKlvpkYqr5l+uIpste+uVAPuaoNhGFJZDr8t3\n6OYVw/ZvZvvYF5gUBVh17V/TIKKEf/cldp+czAr65En1c93/WwDuT5/Hmo4gv/s/V/KeV5SIqGaJ\nVcu+cyCpdlwq5NAtQbf+v2ciB+6FgV1q4+wzjLlGLi7AL4RwAXXAybkPaTovW9PKX161FletrBC1\ncNjiFDvFJkWtOnRfU26GPoOgNzcqUUlE7MKbzL4XKMGymjdZsUW5E6N2h15p5BIeVGJolixORJN8\n9/GjLG9Rwnd8NKLuc/kgEaZ/cJjd+8xKjLv+ik0PvBOAnq6OaS89uvRKzpe7OdqvaroPmv3Dcx26\nrcoFchcIWaJc31XaobsD2asIC69tkjYZVjFWgUlRANF1LvFVr+FPnXezY99h5NQpxh1N6nc/dQr2\n3UOkYRXHZSfLWuoIeF0zlivOhlesbSfgcfLTp/tUjp7v0NPpl4agHzF72ey5EyZOLOxY5pmKFVJK\neQL4F+AY0A9MSCl/O18Ds/OqdZ3ccmWJ7HWxksnQy4hc0knTmQqV0+Y49NKRS0uDctypiN2h26pc\nIPek4DUn2cotXZyPyCU0BMGsGB8367HfcK5y7IeHzZOZuw6SEQ7+8G9o/MHrSRtpOPYE+93r+IX3\njfjPvnraSwfOeR0eYTC44x4ADpmvlXHo+XXokDOWjChbteiFCA9Nz89Bvebr/gnO+2P1fTJcNHIB\n8LzygzSLEI27v49A8kTS/FwP7YGjv+dYq9qDtKe5yNXEHAh4XVy3uZu7dvaTaFkLI/tz53eio9nf\n75lc6XLkUeg+XzVke/KrCz2aeWUukUszcD2wEugGAkKIPynwuPcKIbYLIbYPDZ3BZ/1ClNrgwpU/\nKWqo7NgTyLZkLdOhtzUpQc9pI5ufodtPCpZDLzdymY+yxfBQTv5sCforzJ2njo6YMYsnAIkIwUgf\nSxni2M4HIXSKH8cvYcc5H522YAege9MVhKUPcUQ1nTo4GMLrcrC0ya8WBGUmRW1TPAGboFuVKvVd\nxQU9Mjw9P7e4+M9gqSpLJB4qPClqIpZdTFgE2DCiTj7b02ZGvu0rYCR4zn8xTodgSUNVpqN464XL\niCYNnol2qs/GuG0y2X51UmsOPTpe3tXj2FE1Z7H5Rtj4h6oNxuO2NhiTVQkZThtzyTBeDRyWUg5J\nKZPAz4CX5T9ISvlVKeVWKeXW9vYifxBnKiUzdMuhO7OPSYaVEHjrZ5mhK0ESCVuEYuQJek7cYGbo\nlTj0SlvohgdzXPExU9A39jTSVOfmyIjdoYfxJc2TyLavAPB0spcLewsvsHF5vEy5molOqom8Q8Nh\nVrYFVFfCdAqQ5qSo3aHbPouWQ2/oUnueFqr+KebQM69hniStycQiDh2Hk5ON57PSOKL+X5agH7gX\nurewzTib7iZf1eLFLcuaWN5Sx4Mj5s/SnqPbT2a1JOjpNHzpItWfKG3Ad66DffcUfqzVOrj3MrX3\n6vrr4J6PwQu/gB23wRfW1/Q2fXP51BwDLhFC1Am1O/NVQO3+JKqBo1TkYk2K2nL2RERltJ5gXoZe\nencmYTpPl71qpWTkMgdBryRykVJFLnaHPhah0e+mweemtzWQFXRPHSQi1BtK0JcN3EcaB7vlCi7s\nbS706gA4PH7i0TCJVJp9A1O5E6KgroicHqweKTkO3fp51Hepn1ukQNxQaNm/Hat8MWz2JS/i0AHi\nPVnfc4huRmlQ2++99VaOjSfpaare5L8QgvVd9Tw2UUjQTYfucNWWoIcHVQ/64X3qhHr4EXjuh9Mf\nl0rAzh+Bv0XNIbh9cMO3oXMT3PMJ1YUUytu9apEylwz9CeB24Blgl/laZ1YgNVecJSKXYhm6O6Ac\nY7z8yAWHgyQu3Ia922LepGihyGU2k6JO0+FXErkkQqpUMCdDj7KsRbnY3tY6jgybkYs7gEyEaZBq\nbE7SHHEsp6uthY4SMYTHF8AtE9y7e4C+sWhW/O2N0ITIxi6+xuzP1WPL0CG7+5NFpo9LiSvMjKCb\nJ4NiDh1o3PAqAKLSw6bVK/hw4s+Y+qOfIht7ODoSqUp+bmd1e5A9oyAbunMnRs0Kn3738toS9HGz\n7DM0lB33scdz+/IYSfj+Daop2Ss/ki0QcLrg9f8Ek33q6gxqekenOV3XSSk/JaVcJ6XcKKV8h5Qy\nPl8DOyMotvQ/VUjQDVXlknHo5UcuACmHF3/aVu5nlRfaN9Ow8AQBMbuyRcudVlLlEjJdayB3UtSq\ncFnRGuDkRJR4ygBPHenIGPUiShQlvk8nV/Cp6zaUfAufvw4fSf7zfrU5xBVnm+9ld+iQrUV3+7NC\nbkUuyy5WG0DcdiP896XwX1tVsyxrc4/8kkU7VqVMaGaH3n3WViZkgFOyhRu2LuPB9Bb2yhU8f2KS\n4VCcrSWuROaDNR1BUmlJtHHtNIc+5Wxib7SedKiGBN3qkhkeyv78p/phzCbMe36p9gN4wxfgkvfl\nPn/Fy9Qm26/4sLpKK7SCtkaosTrAGsNZqmzRvM+ZV4furivg0GduSGY4PHiwiW2pyMXhyK4WLUUq\noT7csYnszvGVOHTLNZm5dTot6RuLssxsCbuyLYCUyrXjrssshT/RqqKJ7vWXZgW6CF5/gIAzxd6B\nKVa1Behts5UsQvb/b9WiW3MVkBX2YAe8/0l4+QegaYUax2P/UXxRkZ2MQzf/ryUcutPl4tHAq3ne\nfwHnL1fivW8gxF07T+J2Cl57TpEt+uYJqx590NurmnRZcwZTpxgWLYzIBoypQfUZrAVhH7cJur06\n5+hj2a+3f0vV3lubkufzqr+Fqz6pWlOM1a5DLx3OauaGwwmI8ppzGWYvl7pW5fZS0ewCmzIcetrp\nhVT2a4dhi1yEY3rL2nIadO34Ptz1QfX1kk3mi1cg6HkOfWAqRsJIsyzj0NXtkeEwazwBnEkVHRkb\n3kTc8TJefsl7ZnwL4fLR5DYgRq742yMXsDl0X1bQ7e0EfI1w9afV13f+Fez4AawxSyVLToqaJ4Uy\nBB1g481fxkhL1YvH4+S+PQPsPTXFK9a201Q38+97LljzC4dED72pqKr6aO6FqX76000MyUYc0WH4\nzf9RPfT//FH1xNgEfP8t8KYvl26ydrrJRC6DuXMYu34CO38MnefAkd8pwXbM4GFbVsL+e6s73iqi\nHXq1cXpmWPqf18vFcuiQ7TlShqALWxXLhOFB2ssWCz3f11C8VWzmhfpQe5TKbNxQSeRi/ZGZGfrx\nUbX03hL0laab3jswlRNV+Ju78V75N+AvYw9Zl4+gS43tynU2J50fudgduieoMvViV0CX/IXqu3O7\n6eqsHYgKMc2hl57YXNEaYFV7EIdD8BdXruGBFwc5MR7lus1dJZ83HwS8LrobfeyKm1cCQ3shFUeO\nH+N4soER2YDTiMPuX+Zm6aOH4PgT2Z2vFguWoBtxNUaHG1ZdqfLyvqdU9YvDBVveMfNrtaxSE6z5\nG3/XCNqhVxunu0BzriJL/60qF8sxZgR95shF2Gqso9KNLx7HD7knDzvlRC7RUSVM7jpYshF2/bhC\nhz4EiMxJwSpZtDL0pjoP65bU87v9Q9zSm3W2Da2ziB5cPhpcBjdftpJLVtlq1Q1rDsE84VknPrdf\n/QysuKUQ7WfBpe9XgnHRe7JNrQrhmZ1Dt3PLlWtY2uTnzudOcvWG6sYtFqs7gmybaucDoDba6H8O\nER3lV8bFtGHtuTqV+9mzTub25maLgfGjIJwgDVWhEmiHi9+rjNGrPw0nn1GLvYKlYztAbf4B5t4B\nG6s67GqgBb3aOFylq1ymZeiBrKBbeWAZDt3hUYKekE6S0kUoEjMFvYhD9zYULs+zExlRrvQvnlC5\n4r2frDBDH1QZvPl/PTYaQQjobsqehK44u4Ov/+4Q8VV+rGuN+pZZiJvbh8uI83fX5k2eWl0DM5Oi\nptC6/Go7ufwt5fJ57f8r7/2dbnXSCJXn0PN505alvGnL0lk9Zy6s6Qjyo6NjyCUbEA9+FoSDkd5r\neeTFzbzS8Vz2gfYrMutqx+onvxhIp1W3ys5z1I5cA7uheQWsukL9A2h4Q/mvZ7V3Hj1Uk4KuI5dq\n475Y3mUAACAASURBVHSXt/TfSGarXPzmBGTI3G+yRD90C7dXCVXa4SaFk3DM/OMrKuj1M1e5REZV\npu9wFF8kVQ6hwZwKl32npuhtDeS0hX3lWe2k0pIjk6rULI3AGZh5p54MLl9WcOxMc+i2KpcrPw5v\nnsdKW0+gIoe+EKzpCBJJGPS/6SdwwU3QuoYnzvprAOrsJ1L7frjW14vJoYdOKcPUs1V9H58oPXk9\nEy2mQ6/RShct6NXG4S6vDj0ZVZeM7rpsRYkl6GVELm6PEhCP10daOInGYuZ7JQs/31fGpGh0LHty\nKdbGoBzCQzkrM188NTlt96kLVjQT8Dh5cUSVW06JYPG9Rwvh8k1viwvTq3wsoXX71R/v0vPLf4+Z\n8AazJ5BZOvTTjfXz3z3uhmv/DW7ZxqGYio1W9ypRk8KpPqtWPfdijFyskkWr9QKUF60Uw9eoTMze\n36jFSZV0Fx09BCefrXwMc0ALerVxunIzdCmVKOZPiloTlJ5AVkStpdhlRC6W83Q4PTicbmJxy6HH\nK8/QI6NQZ0YS9nr52RKbyHQ3jCRSHB2NcHaeoHtcDl6+po3nBpQLDDvL26Ung9uv4qD8+Yppk6I2\nhz7f2PP4Re7QzzY3i9nTn/0MnBiP0Rrw0NWzkk8mbyJ87jtR+91aE+zmz3IxCfqAuQNU9/lkVwGX\nqEYqh+WXqk20f/5n8OTXZv/8Oz8A371+QSZWtaBXm3yHnl9bbrnQuCnoBR16OYLuzTzW5XYTi5vv\nU3RStFFtCVdqZ5roaPbkUqxzZDkkwhmx2z8QQkoK7g/7+k1dnIyon0fUPcvFNdb/PxXLPZ4fubhP\nk6C7qtNca74Iel2saK1jzym7oEfpbvKzojXId43XMuw0na5h+yzB4hH0Z74Ld38UOs6BtrXZv5u5\nRC4Ab70VPnZClave/w/ZzVnKIT6l9u+NTcBzt81tHBWgBb3aON2Fc8j8LejsDt3tV5N2VjvdcqIH\nS0CcblxuD6lkgpSRzq2osZNp0FUkdklElDjWzUPkYs0NAHtPqfcrtJ3gNRuXIMzHJb2zFXRToPMF\nPX9SNOPQqxCJWKWL7jrVZmCRs35JA3v6s7//k+NRupt8mXUB33vK7O2SEfRFlKGn0/Cbj6rVve/+\njfqMW/M0gTlELmAuvAvCtV9Q3//X+WrVsLWeohSHHlZ/I/5meOIr5W/zOE9oQa82jryyxfxM14oy\nrAlKS2gsIXV6yhMHm0P3eDw4pEHfWLT0pChkrwzysboGZjJ0WzXObLG1k91zahK/25kpWbTjczvZ\nulZVehj+mXe6z6Fch24JejUctLV+YJHHLRbruxo4MhImkkgxHklwdCTMyrYgPc1+PnLNOjqazI1T\nrPgutYgil4ljat3Gpreo3Buy8zRzdegWTcvh5t+qVaQj++HZ7838nP2/VQsDX/s5GDmgFjSdRrSg\nVxuna4bIxRJ0y6GbQue3CXo5ZBy6B5/Hg0sYaof3YpFLm9m2dedPCr9e1CxNy5xYrCqXWQp62lAi\na8YRe09NcVanWlBTiCs3qQk5d/0sc1BLRJPFHLop6BkXXcXIZZFPiFqs76pHSnjx1BR37uwnaUiu\nPbcLIQR/fsVqLlytql2OD5ufTcuMxCYq34pwvhgyd7NqX5c9Zgn5XDN0O0s2qj4vK14Oz96a2/Ar\nHynhwH2w6pWw+koAju1/jgdeHJi/8cyAFvRq48grW8yPXCxBt8rdLCG3JiPLqHABbA7djc/nw43B\nZ361h0g0Wvg1eraqBv+/+xfVgCofq9a4znTKVhuD2UYuiWxb3GMjEXadmJg2IWpnVbe6XF69ond2\n71PUoef9vM/7Y3jTV8r/uc6Gap4sqoC16fqe/kl++nQf65bUc053NgqzHPqRAdORZ6JDOfMq42oz\nbHaJtC/2sqKWuVS5FOP8d6rqlSOPFn/Mnl/C5Ak4+3Xq5CIcbHvuBd797e3890MHkKVOBvOEFvRq\n43TnxhSWcFsZtiXoVkWLJaD+PGc8EzaH7na5WdvuJxRLcXJkIndzCzuv/ZyKIh79wvT7LIfut9WC\nO1yzj1zMfjSDMSdv/vLvcToE77y0t/jjG7phySacyy+e3fsUy9CNvG6TzSvgvBtn99rl4qmtyKWn\n2U9b0MMXfruPHcfH+cPzexC2eK+9Wf1/jg+Zm40Ytjr/hY5dhvaqlcd1ts9nx3r191OqK2alrH+j\nEulffUj93/uezl3HER6Guz4EXZvh3D8ChxMZ6MARHqDe5+Kf7t7Lr3YV2a92HtErRauN060mGNNp\nNdly/El1fOnW7P2QnXCxPqB1s41csg4dh4t6t+RNW5ZiPJFAOtwUDDjqO1V1gFVNc8ctqvzrwptt\nDt32B1NokdRMmA798b4Yk9EUv/7AKzLd/griCcD7SrigYhRz6Kk8h15NaixyEULwrXddxKfvfIF4\nKs31W7pz7veYq4/78iMXyAr60cfVVdvKy0/HkLMM75veimHLO1Sm7qrC79pTB2/5tipH/MIGZVSa\nVsAN34KeC+CRf1ZXLTf9MvM3nfS30zIxxseuXY8QcE2Vu2iCdujVx+FWl2GfX64WKxx7HBqXQ6O5\nzNty6IkptezfcncVO3S3mdsbrOkI4pZJwkaJX7O5hycAe+9WO7pA9g/WvjTe4Z69QzcF/cBYmvXd\nDaXFfC4Uy9CNuBr3TF325oMamxQF2NTTyE/edynb//bVdNTnTRSbE8knRy1Bt1VrWZ+PX30YfvSO\n01tzLaVy6NY8kIXDkZ2DqgbWtnXdW+Caf1SbTH/vzepEd/BBlZt3npN5+ISrlU4xxrquem68aHnV\nthW0owW92jhNQU9MqR3Gj22D5Zdk7xe2X0GdrbKjYofuUScJI8lZnfV4RIqJRIkqGU9AbaYB6rZ/\np5r4jIyofi/2E4rDWXHksnc0zblLZ7lYaDaUcujFIqf5xl62WEMIIfC5C5TGmr/74YmQ2nwklRe5\nxCZgcLfaAOWZ75ym0aJiy9h46WZp1WLz2+BPf602ybjmc2oce3+tMv0VuVsqD8pmOsQ4Z3UWnzOa\nb7SgVxuHLdU6+ICKN3IEXWRrvOtsbnguDt100ms6grhJMV5qHylPQImukTIXGkVhaI+KXPIbV80h\nchlOuNnUU01BL5Ghn464BWouQ58R8+fmlCkOD4fN371pDqJj5lZ9Un1WH/ti6UVq84m1bV6+Qz/d\n9L5CdXl88HPq+xUvz7n7aKKeVjFJ8DQG21rQq40lyK1rsseWX5r7GEv05+TQs5OiavLSIOh14RUG\no7ESz3PXKdFN2C6ZTzyjJkXr8mrBy4lcEmF44DPZS3BT0KN4Obeagm6tAE3m9XNJxU+jQz8zBd1D\niq8+cohkwrbQLDpmzgcJuObzMHUSjlYw91EJI2qbwQUXdH+T6iEztEcZiq7zcu7eHwngQGb3AzgN\naEGvNpb73vRW6LlI9TSx185CVvTtAjrrOnR75OLMlBd6hcFwtES5lCeoMnSrvBBU/+jIaO6EKJQX\nuey7W00QPf9T9b0ZuRguP2vaq5SfQ/aEloqpHN1aoVesDr8a1GjkUhTzc3ntxlZ+9swJfrvrOGHp\nQfoaTUF/QmXGZ71GPf7kjtMzrqlTgFD7f5q8cHKCiWgFq5jnymq14TfLLsyZjI2nDHZPmZ8Dq4Lt\nNKAFvdpYPVCWXwLXfxH+6HvTJ+ispf0FHXolk6JZJ+0mxVA0jZEuIuqeOuXO7Q6972nVK92fJ+jl\nRC79Zi/tfXerW/NEsayjrbqTQnZB/8bV8MMb1eKX0xm51OCkaEnMn9tbNnfyo/deQtCVZjCcJuZq\nUGV6fduh50IVzTX3nr4Og6FB9bdi/m0ljTR/+OXH+MrDs+i5YpI00vxk+3FiyQoXSlmCvuKynMO7\n+iboT5s7bYVqYGGREOJsIcQO279JIcRfzefgzgicHpWz9WxVkzgrXzH9MY5CDr05976ZsNxBJnJJ\ngZQ4ZZJo2pXZJWganoBq22uVKXacAwO71C49DXnboRVqBTy0z8xSTfp3qttDD0EyirQEvasKiz3s\n2AV95IA6oTz0udM8KVpbZYszYp0IjQQXr2rl0hVBkrgIOerh8COqW+cyc71A9xboNx16tRfQhAZz\nFg8dH40QS6Y5PBQu8aTC3LXzJH9z+06+/NDsTwaAOqG95jNwwbtyDt/+dB9TbvPveaq/+j8Tk4oF\nXUq5V0p5npTyPOACIAL8fN5GdqZw/k1w3b9nL8cLkcnQbY7Y16QqYCrK0M3+MWkDgSQpXewfKNKE\ny22Oy3IRL3u/2vX+zV+HV35k+jjzl3zf9UH47puUY5NSOfSm5SpqOfIo0bBafLG8c5a9WWaL061+\nXtFx9d6eIDzyLyrb1ZOileHKCjqoq72UcDNJvcqFl5xLbPU1RBOGyo/Hj8HzP1MlutY+n9Ug/P/b\nO/P4uKorz39P7dr3xbKEFlvYeMM2slmMwcTN5rCFJWzTJCSZ7Et3MllnI03oZHrSSTdND4QESAjp\nZAi4CYGYHhIWh9Vggxe8YUuyJVu2NsvabK13/rj3VZXkKrkklVRKcb+fjz4qvXr16qjqvt8775xz\nzx0p6HWtWsgbjkVxWsbg91v1ZJ+fbNzP4Y4I/fTH4LkdTXxj/Xa44Et6Toeht3+Q3289zMpF8wHR\ndy4PXBiagzKFxOseeC2wXyl1IE7HSx5Kluppw2MRKSnqcmlRn8DU/2Cs28zsG8BDfVsU78W50DgT\nmwrPgkv/DpbcdOpFyO0Z1cZgQHvnfZ3w4j26PPNEO6z8tPZS9z7H8ePHOam8VBWe2l0xrojoi1qX\nmY03dy2g9BqT0+WhpxXAys/otqvJgHukoIvJRzyfug5W/xf45PN85an9fPyRTdpDB90LvK8z1Gtl\nKug+OqKjYlDQo92FjuJE/xD/67ndbGvs4M/vt/DhJbMYVvDj58e2+UfP72XtP77Eh374Ev2Dwzz0\nSh2Pv91Ic9fIqoM/bD9CT/8QN66s1H1ltjyq7xrj2WMmCvES9FuA6W/+myw4cfbRMevCs7S3Gwun\nVLkMBE9Ej89PXWu0kIsJDzge+liLJo8OuRzdocscc+fA5p/Dll/q7WXnQvESaNlDd9dxeggwZyoT\nog6eAHQe1o8rTGgrWrfJqcDlgnX/AIXzT7/vXwJBQTff+VA/Lq+PDYM1sPa/gzfAtsbjvFnXTr3P\nVHE5i6aMt7KjvTa2hl9K6XVbwzz0WiPonScHY0qMbtjRxP0v7efGB15nYEjxmYuquHxhMa/ui77G\n7tHOk9z7p/cZGlbUtvbw9NbDbD6gJ1dtOdAxYt/1WxqpzE+jpjwH0s3s0Iu+HlqvdAqZtKCLiA+4\nBojYtk9EPi0ib4vI2y0tLZN9u+QkkocO8NdPaW85FsKrXJykqKkLzkxLpa41ykw+R8BjEXS3d+RJ\n1/CW/n3Tz/XAffkHOuxRtFC3Mu1uprenk5P4mZ09DWEIT0DfJYCuJHIukNPloScbwQ6boX7obm+A\nw8e1R9rbP0iTebx+V4++sKeb0EMsvcMdOpvgvhU6XHM6+ru1ExEm6PWtobvPxhjCLv/x3hFyUr14\nXEJ5XiqLZ2exsCSTw8dP0tEbuZZ+a4MW7e9fv4TsVC/3PLsTp87gnYOhvjYtXX28UdvG1WeX6L44\nBfOgaBFc8OXT/29xIB4e+pXAFqVUxFSuUupBpVSNUqqmoCBOfYqTjUhJUdAxzFjX1RwxschcIMwk\nm+yMNOqjeehOAs85AceM9btHhlwaN+nSseLFcOPDOvmbV62PkVYIPS30n+hm0J0atV1uXPEGtDiA\nzkcULtCPp8tDTzZGhVwY6sfj9dPS1Uff4FBwTPk9Lp565xDquvvhtsf1mOoZh/N2ZLt2QNpHJSaH\nh0cm3CE0TkeFXKpNS4mG9rHj4Cf6h3h5bwtXLSnh6S+u4qGPrUBEWGA6T+4MW5IvnG2Nx3G7hKVl\n2Vy5qJhjvQPkp/s4uyybLWGC/tyOJoYVXLXEFBR85AH41B+npr9MBOIh6Ldiwy2TI1i2OI5V7kfj\nJOI8KaHjmRrw3Iw0jnSe1Mmr0fhGJUXHFPRRIZfGt3SWXwTKz9ei/ld36efSC+FEO3LyOGqsY8YT\nT0rIvtQ8HbICK+gTxXE0nBmgg/34fPpu58jxk8HY9e3nlnOwvZftrnk6Z5RWMD4PvXmn/u3kPxz2\nboCffkjnQRyc4xoP3blLuOhM7SyO9tBf3982Igyz8f0WTg4Mc/nCYuYWZgR7CzmthHcejizoWxs7\nmFeUQYrPzdVLdBOzS+YVsqI8h62Nx+kf1PMentnWRHVhemi6v9s7rUnySQm6iKQClwIx3CtZouLy\n6FVOJhMaSMnRgrr4ptCJ6Ah6lh60r+xr5RM/f4vX9ofFCsOTot7Use8IwlsBHzsAx+qhbGXo+YXX\nwfx1+rFJAOUPHcXtny5BD/v8UnKhaMGp2y2x43KZvkAhD90f0OJ0qONEMIx3x/nlAGyqM6Wv6YXj\ni6E379K/u0bd5DtzGtrrQtscx8MIunOXsOyMbNL9Hr1Kl+E/3jvCrT99g0dfqw9u++POo2QGPJxb\nNdJ5KsjwU5DhH7Ekn8PwsGJrQwdnl+m68nOr8vj4BRXcuaqS5eU59A8Os7Opk9buPjbVt/PhJbNO\nOcZ0MSlBV0r1KqXylFIJ7nb/F47bOznv3GHRDZCWF9bBUQ/2giztLfzP3+3ghd3N3P6zN/nNJlNW\n5gh6T/PY8XMwJ/egnvn22A16/3nrIu9rboln04o3ZRoSohDyhHzp+hbXhlwmj9s3QtADRtAPd5yk\ntrWH4swAFflpnJGbytv1JvSQVqgTl7HS4gj6KA+9OcJ2J5RjYvXOXUKVWTrP8dCPdp7kW0/qORHv\nN4fyR9saj1NTkYs3wiS3BbMyI4Zc6tt66Dw5yNIy3brC7RLuumYhC0oyOadczxd5q66dt+raUQou\nPjNxoWU7U3Qm4PLER9AdnGSW6WtSkKNvJw8fP8m1S0tYPDuLR16t1/s4gj48OHa4xbFzeBBe/Hs4\n3gC3PwF5cyLvazworwyRlj6FPVzCcTxx57N0Qi7WQ584bt+IKpdAQOdqDnecoK61h8p8PWZqynN4\n+8AxvSpPekHsHvrwUKjZ1ugZlc52J9Ht7COuYL7pnYPH8LldVOanUZqTGoyh3//Sfnr6dQtpR/T7\nBofY39LNWbMidz9cUJLJvuauYPjE4f++1QDAsjNOXbi8KDPAnII0Xt3fyqb6dgJeFwtLpmm8R8AK\n+kzg3M/ENwsejKHrgZwSCFCQoUXt82vmcvnCYvYc7aKtuy80sQhO76G7TQy9+6heGKP8/Ki7dntD\ngz8jY4pr0B2cjotOdUsgC2o+AXPWTs/7JyOjPHSPL0B+ui8k6AV6/JxTkUNrdx8H2nq1h97bFlsZ\n4rF6nbzPmKXDfs5rBvtDSdLOMA/dmfZvxvgLe5o5tyqXFJ+bstwUGo71opRi494WLpiTx6o5edS1\n9qCUYn9zD4PDivnFkcfjglmZDAwp9oV59L979xA/2VjLrSvPiNoG98K5+bxZ285r+9pYVpaDz5M4\nWbWCPhNYcC0suj5+xxsVcsHtY0VFDpcvLGJecQbnVWnvZlNdu6mkMR69P8aQS1+3jvmPwa+2hyWn\npi0pOspDB7jqxzDviul5/2RkhIeuJxaVZKfwzsEOOnoHqDIe+ooK/Znf+6f3eWzHCb34Q2/b6Y/v\nhFWqLtEtKHpMfqdtXyhfE+6h97QEwy0H2nqobenhQ/P13eDCkix6+4d4ZlsTta09rK4uoKogne6+\nQVq6+thlwinRPPSzRlW6/NubB/nq41tZWZnLd69ZGPE1AKvm5nNiYIg9R7tYURnHO+0JYAU9GRmV\nFMXt419vW879t58DwJLSLFK8bt6oNSecM7ko1pBLfxf4owv6if4h7n+9mX4xsevp6m0yerUny+Rx\ne0Me+qBudDa/OIM9ppXEHFMlMrcgncyAh/XvHOLVI0ZWYql0CQr6xeY1pjNhy279O2/uyBh691Fd\nRQO8sFsf3xH0KxYVk+J1c9fTuipmdXV+MCRU29rD7iOd+DwuKvIij/PK/DQCXhc7D3eycW8L3/n3\n7Vw4N5+HP75iTK/7vDl5uE1Z7oqKU8My04kV9GTE8dCd3uBuLyISrAX3ul3UVOTwRq2pSnBCLbGG\nXPq6xvTmn9jcQMeJQVSqSQ5Nu4c+xX1jPki4fbqFhFLBWbf3fGQxT31hFffdtoyLqvV37HIJX15b\nzS0rymhTJqQRSxy9bR9klobWC+gKE3RxQeXFevavUvrusL0OMvXyjS/sbqaqII1yI9Dpfg/rFs+i\nraefokw/1YXpVJmQUF1rD7uPdDGvKCNq10+3S5hfnMmupk5e2N1MwOviwTvOId0/9goVmQEvZ5dm\n4XZJxDj7dGIFPRlxWgmEeeijOa8qjz1Hu2g6fiLkQcdU5TKgQy5RPPShYcXPXqlj2RnZ+LLMrMHp\nrEOH+CaYP+g4IZfhIUCB24fX7WJpWTZXLSkJeqYAn1pdxV3XLKQVkxSMpdKl6zBkloRmmDqCXvdn\nPfM0t1KP45PH9QIaJ9rhzMvo6Rvkzdp2PjRvZBfPm2pKAVhdXYCIUJKVgs/joq61h11NXcwvHjtU\nuKBEV7psqmtn+Rk5+D2xTez77MVz+MIlc08r/lONFfRkxHV6QV+3eBYBr4uvPb41NPHntDF0M/W/\nryuq+L9R28aBtl4+eWEl4kzPnq6Qi+Oh25BL/HBCLqbR2+lmPAa8bgYCpglVLB56Z5Nu0xwu6HV/\nhoOvwYpParEH7aXvWK/HXfVlvLqvlf6h4WC4xeHcylw+t2YOd66qAPSdQ2VeGht2NNHa3cf8WWMn\n6M+alcnxEwPsbOoM5gVi4bKFxXz10gSvoIQV9OTklKToqR0bK/PT+LtrF/Ha/jYO9Rgv63SetNsT\nWnfUr0+MoWGlFxA2bKprxyWmFjdtmkMuXuuhxx2nysWJo8dQ05+akcuAeGNbqafrCENpxXz76d0M\nBXJ1DP2l7+veQOd8HDKMoHcchF1Pw7wrwZvCi3uaSfd7qBkluiLCN6+YP6J0cG5hOg3tJ6gpz+Ej\ny2aPac6CMME/N8EJzolgBT0ZcY2sQ492En60powblpey95jpMhRTUtRUPBhv/ptPbuPmn7yh64+B\nzQeOMa84k4yAN9RAadpCLqafjRX0+OExIRdn+n8M7ZyLslM45CqB1rB2tNseh/tW6sSqQ18X9Hdx\nROXw600NdLhz9dKFB16F1V/TF2jHQ9/yqF72buH1KKV4cXcLq6vzYyoR/Prl83joYzX89rPnk5s2\n9gVpfnGG7sQ8A+LhE8EKejIyqpcL7ugTa+6+bmFwav49zzdw19PvBcX51OOGncwm5PJuQwfvNnTw\nem0bg0PDvHPwmG4bCiEPfdpCLkbQbcglfpzioZ9+klZxpp9dqhyO7AhtbNgErXugPmwhaePB1/Vr\nr7hVcnWsfNENOtwCoXVD9zyrl7mbu5adTZ0c6TzJJaPCLdGoyE9j7VlFuvvhaUjze6jMT2NxaRYp\nvhgb480grKAnI+7RZYvRvapUn4dzqnUiqaQon5+/Vs/DzizSU44blvDxZzA0rDjYpt/j4Vfq2XO0\ni57+oeB06JCHPk1T/9MLdMdHx6uzTJ4JhFyKMgO801+qE549pjTWKT3csyG0o+ldv6tbOxQvuFfp\nxWA+8pOQU+LxhRyDy78PHj9vmZ4xq6unZsGIH390KT+4fsmUHHuqsYKejARj6KZP9GlOwvQMHW/8\n2JpFXLGwmHue3RmcLj3yuGEXBn8GhztO0D80TGlOCn/afZSHX6kHCAl69WWw5jsw6+zJ/DexM/9q\n+PwbI3plWyaJ26vDLUPjCLlkBtg5rBt2cXS7/u1M69+zIbS+phH5ze36zurnJy6Ea/7l1PcoXqx7\nBs27EoCmzpN43UJxZmDi/9cYnF2WzbzTVMPMVKygJyMR6tDHxMS4Xf507r5uEV63i/tf2hf9uAD+\njOCydt++8ixmZ6fw5JZGijL9lOakBPdhzTdHevZTidsDBYmvNEgqRnvoMfTFKc4MsGvYrLTlhF26\njujQW2cjPHoNPHZj0EN/s8WHz+PiaGcfvf2Dpx7w9ifgo7/UbZqB5s4+CjMCMYVQPmhYQU9GwssW\nxX36RTKcfi6+dAoy/Nyyooz1Ww5xaPSiue6RMXRnpZiaihw2fGU1n1hVyefXzLUnWjLh1KE70/9j\nDLm0kUVfoEAvU6iU9tAXXq/zHAdeh33PQ93LDHnTOTbkD3YoPBi2LqhSSvcnd7lHOAVHO09SlGkb\nrkXCCnoyEi7osbSO9YUEHeDTF89BBO55dufIBOkIDz2d2tYeUn1uCjP8ZAS8/I+rF/CxCyri8z9Y\nZgZOHbpTnRJLyCVLi21rWrX20E8c08coXgRf2gyff13vWPsyPX4dHnNW+AlfWevZ7U2su/fP7D4y\nsqVtc1cfRVMUbvlLxwp6MhJehx6LoKfoxv0EdCx9dnYKX7tsHn/YfoR/fTEs9DJC0DOpb+2hPC/N\neuTJzASqXPLT/LhdQqNvjp7C36F776v0Ysgq1Z06888EFK2SS4rXzZoztbAfaAvlbl7YpScm7Tky\nctEJ7aFbQY+EFfRkJLwfegweFQuug1t/A9llwU2fuaiKq88u4UfP76W9J0JCzJdOfVsvlfnTVJJo\nSQwTCLm4zOLL24fK9LyFuo0AfP7pQ/T0mRi5aWl8ZDibyvw0slK95KX5qG/robnzJMPDio3v686L\n4V57b/8gXScHKbQhl4hYQU9GwuvQY1ncwZcarCBwEBFuW3kGwwq2NXaY4xpBd/sZEA8N7b3BbnaW\nJMVpzjUUe8gF9BT6lzvNdP59fwTgva5Unt6qE6HM1YJ+cDArmEQvz0vlyc2HWPn3f+KLv95Ca7d+\nz/owr725U28ryrAeeiSsoCcjjvCqoZhPwEgsmq0nfGxvNCsMOhcKfzoH23sZHFZRW5FakgS3X3Qc\nNgAAC4RJREFUT7dMdmLoMa7+tGBWJq915KLcfjioY+bNKpvH3jig8zLlq1BFC3m5dw5lufou78Lq\nAoqzAlw4N58/bNeTjqoL00cKepe2w3rokbGCnoyEx7onsZ5mRsBLVX4a2w8ZQXcuDv4Mnt+p64rH\n08DI8heI850H5zTE6qFnMISb3uxqGOqnW9IYcAV473AnWw4eA18q7X/9IhsGlgY99K9eeiYbv3EJ\nj9y5gksXFLG6Op8VlbnBairQ8XPAxtCjYAU9GYmToAMsLs0KCbrx/JUvnSc3N3JOeQ4VNuSS3Djj\np7975N+nYcEsnWA/7NdrzjarHK5YVEx+uo///Ohm3m3ooOGYLostyxmZh/G6Xfz0jhp+cedKKvJS\nOdY7wPFeHcMPCroNuURkUoIuItki8oSI7BaRXSISfZFJy/SRmgvzr9KPJxFyAVg8O4um4ydp6eoL\nXih6SeH95m6uXz525zpLEhAUdMdDjy3UUZTpJyfVy26lZ4w2DWcxpyCd3372AtL9Hu58ZFOwoqU0\nNyXiMVwuCYb0nLBLc1cffo+LzJTE9h2fqUzWQ/9n4Dml1HzgbGDX5E2yTBoRuPkxuPb/wMXfnNSh\nFs/Wntb2Qx0MoGPo21qH8XlcXLXY9kxJeoIhl+6Rf58GEeGsWZm83qvHSLPKpjgzQGV+Gt+6cj7H\negd4Zpue+l+aE71Sykm6O4LulCzaUtnITFjQRSQTuAh4CEAp1a+U6oiXYZZJIgLLbj+lemW8LC7N\nIiPg4aFX6tiwU69Ao7zp/O8bl5CVOjnv3/IXgOOh9xlBjzEpCrrS5fk23UDrqMqh2Ew4Or8qDxG9\nhFxOqnfMVX7KclMRIdhbqLmzz84SHYPJeOhVQAvwiIi8IyI/ExEbUE0yUn0evnH5PF7d18YvN+mS\nswsWVHDtUhtu+UDgCPg4Y+igq6RaBlPZcObdPDb0VxSauHdOmo9FJVkMDatghUs0Al43JVkprN9y\niG+v38a7DR0U2oRoVCYj6B5gOXC/UmoZ0AN8a/ROIvJpEXlbRN5uaYlhjUHLjOO2c8tZUprFsBhP\nKsp6opYkxAmx9HXrRZtP1xcojCWlegbyfa3LaFSFFGeFhHjVXO25Bxu5jcGX184lze9h/ZZDrK7O\n53MXzxnHP/DBYjKZhUagUSn1pvn7CSIIulLqQeBBgJqamigrJ1hmMm6X8Is7V9K+3w3rmb7+5pbE\nE17lEmNC1KEyL40Mv4f3DnfidQu5qSHv/sK5+Tzw8v5TKlwicfOKM7h5xRnjeu8PKhP20JVSR4AG\nEZlnNq0FdsbFKsuMIyfNx5wis06j9dA/OIRXuYyzBNblEhaX6jFTmBHA5QolMmsqclhals0Fc6dm\nkYoPKpOt/fkS8CsR8QG1wJ2TN8kyYwlOLLIe+geG8CqXCZTALinN5rX9backMgNeN099YVU8LLSE\nMSlBV0q9C9TEyRbLTCdzNlStgbLzEm2JZboI99DHUeHisLRMe+jh8XPL1GGr8y2x40uFO36XaCss\n00l4DN20Vx4PTmLUTtWfHuzUf4vFEp3wOvQJtJGYlRXg06YVs2XqsR66xWKJjiPiwwOQXT7ul4sI\n31l3VpyNskTDeugWiyU6TiI0czZcc29ibbGcFuuhWyyW6ORUwPlfhOV3QKYNm8x0rKBbLJbouNxw\n+T2JtsISIzbkYrFYLEmCFXSLxWJJEqygWywWS5JgBd1isViSBCvoFovFkiRYQbdYLJYkwQq6xWKx\nJAlW0C0WiyVJEKWmbxEhEWkBDgD5QOu0vfHYzCRbYGbZY22JzEyyBWaWPdaW6EzGnnKlVMHpdppW\nQQ++qcjbSqkZ0Ud9JtkCM8sea0tkZpItMLPssbZEZzrssSEXi8ViSRKsoFssFkuSkChBfzBB7xuJ\nmWQLzCx7rC2RmUm2wMyyx9oSnSm3JyExdIvFYrHEHxtysVgsliQhLoIuIg+LSLOI7AjbdraIvC4i\n20Xk9yKSabbfLiLvhv0Mi8hSEUkVkWdFZLeIvCciP0ikPaOO93T4sRJhi4j4RORBEdlrPqMbEmjL\nrWb/bSLynIjkT8Nn4xWRX5jtu0Tk22GvuUJE9ojIPhH5VqJsEZEyEXnRbHtPRL6SyM/FPO8WkXdE\n5JlE2iIi2SLyhBm7u0Tk/ATb87fmO9ohIr8WkXGvYj1OW3wi8ojZvlVE1oS95hyzfZ+I3CsiMpHP\nBgCl1KR/gIuA5cCOsG1vARebx58A7o7wusVArXmcClxiHvuAPwNXJsqesG3XA/8WfqxE2AJ8F/ie\neewC8hP0PXmAZuf9gX8A7prqzwa4DfhN2FipByoAN7AfqDLjZiuwIEG2zAKWm+0ZwN5E2RL2uq+a\n8ftMor4j8/cvgE+Zxz4gO4FjZjZQB6SY5x4HPj7FtnwBeMQ8LgQ2Ay7z9ybgfECADUxQ95RS8fHQ\nlVIbgfZRm+cBG83j54FIHuWtwK/NMXqVUi+ax/3AFqA0UfYAiEg6+oT43kTsiKct6MHxfXPMYaXU\nuCcoxMkWMT9pxpPIBA6P15YJ2KPMe3qAFKAf6ARWAvuUUrVm3PwGuDYRtiilmpRSW8zxuoBdaPGY\ndlsARKQU+DDws/HaEE9bjJd6EfCQOWa/UqojUfaY5zxAinkulQmM4XHasgD4k3ldM9AB1IjILCBT\nKfW60ur+KHDdeG1xmMoY+g7gGvP4JqAswj43M1K0AH17BlyN+QASaM/dwD8CvXG0Y9y2mM8D4G4R\n2SIivxWRokTYopQaAD4HbEefBAswJ+oU2/ME0AM0AQeBHyql2tGC2RD2+kYmIKJxsiWIiFQAy4A3\nE2jLPwHfAIbjZMNEbakCWoBHTPjnZyKSlih7lFKHgB+abU3AcaXU/5tiW7YC14qIR0QqgXPMc7PR\nY9ZhUuN3KgX9E8AXRGQz+vazP/xJETkX6FVK7Ri13YMWj3uVUrWJskd0vHiuUurf42jDhGxBexOl\nwKtKqeXA6+gBOe22iIgXLejLgBJgGzAibjtF9qwEhsx7VgJfE5Eq9N3CaOJVujVeW4Dgnd2TwN8o\npTqJD+OyRUSuApqVUpvj9P4TtgU9fpcD9yullqFFdkK5jnjYIyI56Lu4SvNcmoj8pym25WG0WL+N\nvtC+BgwS5/E7ZYtEK6V2A5cBiMiZ6Fu/cG4hgneOrtV8Xyn1Twm253zgHBGpR39OhSLyklJqTQJs\naUPfJTgXl98Cn5ysHRO0Zal53X7zmseJ48k5hj23Ac+ZO4RmEXkVqEF75+F3FaVMMAQUB1tqzQXv\nSeBXSqn18bBjgrYsA64RkXVAAMgUkceUUpMWrgnYshFoVEo5dytPkNgxo4A6pVSLec164ALgsamy\nRSk1CPyts5+IvAa8DxxjZGh5UuN3yjx0ESk0v13AfwMeCHvOhb4d+c2o13wPyAL+JtH2KKXuV0qV\nKKUqgAuBvfEQ8wnaooDfA877rwV2JsIW4BCwQEScRkGXomPFcWEMew4CHxJNGnAesBudhKoWkUoR\n8aEvQE8nwhaTU3gI2KWU+lE8bJioLUqpbyulSs34vQV4IR5iPkFbjgANIjLP7Be38TsRe8z280RX\n1omxJy5jOJot5r3SzONLgUGl1E6lVBPQJSLnGVvuAH43YQMmmk0dle39NToWNYC+rfgk8BV0ln8v\n8APMJCaz/xrgjVHHKEVfOXcB75qfTyXKnlHHq2DiVS5xsQUoR3s629C5hTMSaMtnzfe0DX2hyZvq\nzwZIR9+ZvIcWg6+HHWed2X8/8F8TZQv6wq/M5+KM4XWJ+lxGfY8TrXKJ13e0FB1u2AY8BeQk2J7v\nosV9B/BLwD/FtlQAe9DnzR/R3ROd49QYO/YD9xF2Do73x84UtVgsliTBzhS1WCyWJMEKusVisSQJ\nVtAtFoslSbCCbrFYLEmCFXSLxWJJEqygWywWS5JgBd1isViSBCvoFovFkiT8f+bLQEDfIU31AAAA\nAElFTkSuQmCC\n", 944 | "text/plain": [ 945 | "" 946 | ] 947 | }, 948 | "metadata": {}, 949 | "output_type": "display_data" 950 | } 951 | ], 952 | "source": [ 953 | "pyplot.plot(nelson_siegel_svensson(10.0, *[df[i] for i in [\"beta0\",\"beta1\",\"beta2\",\"beta3\",\"tau1\",\"tau2\"]]).loc[:'1990-01-01'],label=\"10\")\n", 954 | "pyplot.plot(nelson_siegel_svensson(30.0, *[df[i] for i in [\"beta0\",\"beta1\",\"beta2\",\"beta3\",\"tau1\",\"tau2\"]]).loc[:'1990-01-01'],label=\"30\")\n", 955 | "pyplot.legend()" 956 | ] 957 | }, 958 | { 959 | "cell_type": "code", 960 | "execution_count": null, 961 | "metadata": { 962 | "cell_id": "5D4B2172AB7C4D9991A2BA715BC18B41" 963 | }, 964 | "outputs": [], 965 | "source": [] 966 | } 967 | ], 968 | "metadata": { 969 | "kernelspec": { 970 | "display_name": "Python 3", 971 | "language": "python", 972 | "name": "python3" 973 | }, 974 | "language_info": { 975 | "codemirror_mode": { 976 | "name": "ipython", 977 | "version": 3 978 | }, 979 | "file_extension": ".py", 980 | "mimetype": "text/x-python", 981 | "name": "python", 982 | "nbconvert_exporter": "python", 983 | "pygments_lexer": "ipython3", 984 | "version": "3.5.3" 985 | } 986 | }, 987 | "nbformat": 4, 988 | "nbformat_minor": 2 989 | } 990 | --------------------------------------------------------------------------------