.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/interest_rate_models/options/plot_01_jamshidian_bond_option.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_interest_rate_models_options_plot_01_jamshidian_bond_option.py: Jamshidian: an exact bond option formula ======================================== Farshid Jamshidian (1989) priced a European option on a zero-coupon bond in Vasicek's model in closed form. Under the measure that uses the option-expiry bond as numeraire, the forward bond price :math:`P(0, S)/P(0, T)` is a lognormal martingale, so .. math:: c = P(0, S) N(h) - K P(0, T) N(h - \sigma_P), \quad h = \frac{1}{\sigma_P}\ln\frac{P(0, S)}{K P(0, T)} + \frac{\sigma_P}{2}, which is Black-76 on the forward bond. Only the total volatility :math:`\sigma_P` depends on the model, and the same formula holds in Ho-Lee, Hull-White and G2++. .. GENERATED FROM PYTHON SOURCE LINES 19-27 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from financialkit.interest_rate_models import G2PlusPlusModel, HoLeeModel, HullWhiteModel, VasicekModel, path_discount_factors, zero_coupon_bond_option vasicek = VasicekModel(0.03, 0.3, 0.05, 0.015) T, S = 2.0, 7.0 .. GENERATED FROM PYTHON SOURCE LINES 28-30 Closed form against Monte Carlo ------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 30-47 .. code-block:: Python K = np.linspace(0.70, 0.90, 9) closed = zero_coupon_bond_option(vasicek, T, S, K, "call") times, r = vasicek.simulate(T, 100, 20_000, rng=0) D = path_discount_factors(times, r)[:, -1] bond_at_T = vasicek.zero_coupon_bond(S, t=T, state=r[:, -1]) payoffs = D[:, None] * np.maximum(bond_at_T[:, None] - K[None, :], 0.0) mc, se = payoffs.mean(axis=0), payoffs.std(axis=0) / np.sqrt(D.size) fig, axes = plt.subplots(1, 2, figsize=(11, 4)) axes[0].plot(K, closed, "k-", label="Jamshidian closed form") axes[0].errorbar(K, mc, yerr=1.96 * se, fmt="o", ms=3, capsize=2, label="Monte Carlo") axes[0].set_xlabel("strike") axes[0].set_ylabel(f"call on a {S:g}y bond, expiring in {T:g}y") axes[0].legend() print(f"largest |MC - closed form| / SE: {np.max(np.abs(mc - closed) / se):.2f}") .. image-sg:: /api/gallery/interest_rate_models/options/images/sphx_glr_plot_01_jamshidian_bond_option_001.png :alt: plot 01 jamshidian bond option :srcset: /api/gallery/interest_rate_models/options/images/sphx_glr_plot_01_jamshidian_bond_option_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none largest |MC - closed form| / SE: 1.14 .. GENERATED FROM PYTHON SOURCE LINES 48-53 One formula, four Gaussian models --------------------------------- At the forward strike, the option value is driven by the total bond volatility each model implies. .. GENERATED FROM PYTHON SOURCE LINES 53-71 .. code-block:: Python curve = vasicek.curve() models = { "Vasicek": vasicek, "Hull-White": HullWhiteModel(curve, 0.3, 0.015), "Ho-Lee": HoLeeModel(curve, 0.015), "G2++": G2PlusPlusModel(curve, 0.8, 0.012, 0.05, 0.008, -0.7), } expiry = np.linspace(0.25, 6.0, 40) for name, m in models.items(): Kf = m.zero_coupon_bond(S) / m.zero_coupon_bond(expiry) axes[1].plot(expiry, zero_coupon_bond_option(m, expiry, S, Kf), label=name) axes[1].set_xlabel("option expiry T (years)") axes[1].set_ylabel(f"at-the-money call on the {S:g}y bond") axes[1].legend() fig.tight_layout() plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.109 seconds) .. _sphx_glr_download_api_gallery_interest_rate_models_options_plot_01_jamshidian_bond_option.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/interest_rate_models/options/plot_01_jamshidian_bond_option.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_jamshidian_bond_option.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_jamshidian_bond_option.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_jamshidian_bond_option.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_