.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/fixed_income/duration/plot_05_ho_key_rate_durations.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_fixed_income_duration_plot_05_ho_key_rate_durations.py: Ho's key rate durations ======================= A single duration assumes the whole curve moves in parallel. Thomas Ho (1992) shocked the curve one *key rate* at a time, with triangular shapes that sum to a parallel shift, so a bond's risk becomes a vector whose entries add up to its effective duration. Two portfolios with the same duration can have very different key rate profiles. .. GENERATED FROM PYTHON SOURCE LINES 13-22 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from financialkit.fixed_income import NelsonSiegelCurve, bond_cash_flows, key_rate_durations, key_rate_weights, redington_immunize from financialkit.fixed_income.visualizers import plot_key_rate_durations keys = np.array([0.5, 1, 2, 5, 10, 20, 30]) curve = NelsonSiegelCurve(0.045, -0.02, 0.01, 2.0) .. GENERATED FROM PYTHON SOURCE LINES 23-25 The key-rate shock shapes ------------------------- .. GENERATED FROM PYTHON SOURCE LINES 25-34 .. code-block:: Python t = np.linspace(0, 35, 400) fig, ax = plt.subplots() for k, w in zip(keys, key_rate_weights(t, keys), strict=True): ax.plot(t, w, label=f"{k:g}y") ax.set_xlabel("maturity (years)") ax.set_ylabel("shock weight") ax.legend(ncol=4) .. image-sg:: /api/gallery/fixed_income/duration/images/sphx_glr_plot_05_ho_key_rate_durations_001.png :alt: plot 05 ho key rate durations :srcset: /api/gallery/fixed_income/duration/images/sphx_glr_plot_05_ho_key_rate_durations_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 35-37 Bullet and barbell with equal duration -------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 37-47 .. code-block:: Python bullet = bond_cash_flows(100.0, 0.045, 10.0) target = bullet.scaled(1.0) barbell = redington_immunize(target, [bond_cash_flows(1.0, 0.04, 2.0), bond_cash_flows(1.0, 0.05, 30.0)], curve).portfolio fig, axes = plt.subplots(1, 2, figsize=(10, 4), sharey=True) for ax, (name, cf) in zip(axes, (("bullet 10y", bullet), ("2y/30y barbell", barbell)), strict=True): res = key_rate_durations(cf, curve, keys) plot_key_rate_durations(res, ax=ax) ax.set_title(f"{name}: sum {res.durations.sum():.2f}") plt.show() .. image-sg:: /api/gallery/fixed_income/duration/images/sphx_glr_plot_05_ho_key_rate_durations_002.png :alt: bullet 10y: sum 8.16, 2y/30y barbell: sum 8.16 :srcset: /api/gallery/fixed_income/duration/images/sphx_glr_plot_05_ho_key_rate_durations_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.061 seconds) .. _sphx_glr_download_api_gallery_fixed_income_duration_plot_05_ho_key_rate_durations.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/fixed_income/duration/plot_05_ho_key_rate_durations.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_05_ho_key_rate_durations.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_05_ho_key_rate_durations.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_05_ho_key_rate_durations.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_