.. 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_03_fisher_weil_duration.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_03_fisher_weil_duration.py: Fisher-Weil duration ==================== Fisher and Weil (1971) computed Macaulay's weights with each cash flow discounted on its own zero rate instead of the bond's single yield, .. math:: D_{FW} = \frac{1}{P}\sum_i t_i\, c_i\, e^{-r(t_i) t_i}. It is the exact sensitivity of the price to a parallel shift of the zero curve, which the script verifies by repricing on shifted curves. .. GENERATED FROM PYTHON SOURCE LINES 15-29 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from financialkit.fixed_income import NelsonSiegelCurve, bond_cash_flows, fisher_weil_duration, macaulay_duration, yield_to_maturity curve = NelsonSiegelCurve(0.05, -0.035, 0.0, 3.0) # steeply upward sloping cf = bond_cash_flows(100.0, 0.06, 20.0) P = cf.present_value(curve) ytm = yield_to_maturity(P, cf) d_fw = fisher_weil_duration(cf, curve) print(f"price {P:.3f}, yield {100 * ytm:.3f}%") print(f"Macaulay at the yield: {macaulay_duration(cf, ytm):.4f}") print(f"Fisher-Weil on the curve: {d_fw:.4f}") .. rst-class:: sphx-glr-script-out .. code-block:: none price 122.445, yield 4.268% Macaulay at the yield: 12.7253 Fisher-Weil on the curve: 12.4868 .. GENERATED FROM PYTHON SOURCE LINES 30-32 Parallel shifts of the zero curve --------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 32-44 .. code-block:: Python shifts = np.linspace(-0.02, 0.02, 41) actual = np.array([cf.present_value(curve.shifted(s)) for s in shifts]) fig, ax = plt.subplots() ax.plot(1e4 * shifts, actual, label="repriced") ax.plot(1e4 * shifts, P * np.exp(-d_fw * shifts), ls="--", label=r"$P e^{-D_{FW} s}$") ax.set_xlabel("parallel shift of zero curve (bp)") ax.set_ylabel("price") ax.legend() slope = (actual[21] - actual[19]) / (shifts[21] - shifts[19]) / P print(f"-dP/ds / P by finite difference: {-slope:.4f}") plt.show() .. image-sg:: /api/gallery/fixed_income/duration/images/sphx_glr_plot_03_fisher_weil_duration_001.png :alt: plot 03 fisher weil duration :srcset: /api/gallery/fixed_income/duration/images/sphx_glr_plot_03_fisher_weil_duration_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none -dP/ds / P by finite difference: 12.4875 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.027 seconds) .. _sphx_glr_download_api_gallery_fixed_income_duration_plot_03_fisher_weil_duration.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_03_fisher_weil_duration.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_03_fisher_weil_duration.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_03_fisher_weil_duration.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_03_fisher_weil_duration.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_