.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/stochastic_volatility/simulation/plot_02_full_truncation.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_stochastic_volatility_simulation_plot_02_full_truncation.py: Lord, Koekkoek and van Dijk's full truncation ============================================= An Euler step for the square-root variance can go negative, and the repairs proposed in the literature differ in where they take the positive part: in the diffusion only (partial truncation, Deelstra and Delbaen 1998), as an absolute value in the diffusion (Higham and Mao 2005), or in both the drift and the diffusion while letting the variance itself go negative (full truncation). Lord, Koekkoek and van Dijk (2010) put them in one framework and found full truncation the least biased. All three schemes here run through :func:`financialkit.integrators.euler_maruyama` with correlated increments. .. GENERATED FROM PYTHON SOURCE LINES 17-45 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from financialkit.stochastic_volatility import HestonModel, heston_mc_price, heston_paths from financialkit.stochastic_volatility.visualizers import plot_heston_paths m = HestonModel(v0=0.04, kappa=0.5, theta=0.04, xi=1.0, rho=-0.9) S, K, T, r = 100.0, 100.0, 10.0, 0.0 exact = m.price(S, K, T, r) # Higham-Mao's absolute value keeps feeding large variances back in, so # its estimates are both biased and very noisy. steps = np.array([10, 20, 40, 80]) fig, ax = plt.subplots(figsize=(7, 4)) for scheme in ("full_truncation", "partial_truncation", "higham_mao"): res = [heston_mc_price(m, S, K, T, r, n_steps=n, n_paths=20_000, scheme=scheme, rng=3) for n in steps] bias = np.array([x.estimate - exact for x in res]) se = np.array([x.std_error for x in res]) print(f"{scheme:>18}: bias {np.round(bias, 2)}, standard error {np.round(se, 2)}") ax.errorbar(T / steps, bias, yerr=2 * se, marker="o", ms=3, capsize=2, label=scheme) ax.axhline(0.0, color="k", lw=0.8) ax.set_xscale("log") ax.set_ylim(-15, 15) ax.set_xlabel("time step") ax.set_ylabel("price bias (exact 13.0847)") ax.legend() .. image-sg:: /api/gallery/stochastic_volatility/simulation/images/sphx_glr_plot_02_full_truncation_001.png :alt: plot 02 full truncation :srcset: /api/gallery/stochastic_volatility/simulation/images/sphx_glr_plot_02_full_truncation_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none full_truncation: bias [6.5 3.78 1.94 0.95], standard error [0.21 0.15 0.12 0.1 ] partial_truncation: bias [12.5 8.95 5.65 3.39], standard error [0.3 0.21 0.16 0.13] higham_mao: bias [-3.52 -7.14 -7.57 10.62], standard error [ 1.62 0.89 1.22 15.36] .. GENERATED FROM PYTHON SOURCE LINES 46-51 Full truncation lets the variance go negative --------------------------------------------- The state :math:`v` itself crosses zero, but only :math:`v^+` enters the coefficients, so it drifts back up at rate :math:`\kappa\theta`. .. GENERATED FROM PYTHON SOURCE LINES 51-57 .. code-block:: Python paths = heston_paths(m, S, 2.0, r, n_steps=200, n_paths=8, scheme="full_truncation", rng=4) print(f"lowest simulated variance: {paths.variance.min():.4f}") plot_heston_paths(paths) plt.show() .. image-sg:: /api/gallery/stochastic_volatility/simulation/images/sphx_glr_plot_02_full_truncation_002.png :alt: Heston paths (full_truncation) :srcset: /api/gallery/stochastic_volatility/simulation/images/sphx_glr_plot_02_full_truncation_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none lowest simulated variance: -0.0107 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.306 seconds) .. _sphx_glr_download_api_gallery_stochastic_volatility_simulation_plot_02_full_truncation.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/stochastic_volatility/simulation/plot_02_full_truncation.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_full_truncation.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_full_truncation.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_full_truncation.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_