.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/portfolio/bayesian/plot_02_michaud_resampling.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_portfolio_bayesian_plot_02_michaud_resampling.py: Michaud's resampled efficiency ============================== Richard Michaud (1998) called mean-variance optimizers "estimation-error maximizers": they put the most weight on the assets whose expected returns were most overestimated. His remedy treats the estimates as one draw among many. Resample histories from them, compute each history's frontier, and average the weights rank by rank along the frontier. The resampled portfolios are more diversified and change more gradually with risk than the classical corner solutions. .. GENERATED FROM PYTHON SOURCE LINES 15-35 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from financialkit.portfolio import resampled_frontier from financialkit.portfolio.visualizers import plot_weights names = ["bonds", "credit", "US equity", "intl equity", "emerging"] mu = np.array([0.03, 0.045, 0.07, 0.075, 0.09]) vol = np.array([0.05, 0.08, 0.16, 0.18, 0.25]) corr = np.array( [ [1.0, 0.6, -0.1, -0.1, 0.0], [0.6, 1.0, 0.3, 0.3, 0.4], [-0.1, 0.3, 1.0, 0.8, 0.7], [-0.1, 0.3, 0.8, 1.0, 0.75], [0.0, 0.4, 0.7, 0.75, 1.0], ] ) cov = corr * np.outer(vol, vol) .. GENERATED FROM PYTHON SOURCE LINES 36-40 Classical and resampled compositions ------------------------------------ 40 resamples of ten years of annual-scale data, 12 ranks each. .. GENERATED FROM PYTHON SOURCE LINES 40-52 .. code-block:: Python res = resampled_frontier(mu, cov, n_obs=10, n_resamples=40, n_points=12, rng=0) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 3.8), sharey=True) plot_weights(res.frontier.weights, x=np.arange(12), ax=ax1) ax1.get_legend().remove() ax1.set_title("classical long-only frontier") plot_weights(res.weights, labels=names, x=np.arange(12), ax=ax2) ax2.set_title("Michaud resampled frontier") for ax in (ax1, ax2): ax.set_xlabel("frontier rank (low to high risk)") fig.tight_layout() .. image-sg:: /api/gallery/portfolio/bayesian/images/sphx_glr_plot_02_michaud_resampling_001.png :alt: classical long-only frontier, Michaud resampled frontier :srcset: /api/gallery/portfolio/bayesian/images/sphx_glr_plot_02_michaud_resampling_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 53-59 The resampled frontier lies inside the true one ----------------------------------------------- Under the true inputs the averaged portfolios are slightly inefficient, the price of robustness; each resample's own frontier, evaluated at the truth, is far worse. .. GENERATED FROM PYTHON SOURCE LINES 59-71 .. code-block:: Python fig, ax = plt.subplots(figsize=(7, 4)) for s in range(res.sample_weights.shape[0]): W = res.sample_weights[s] ax.plot(np.sqrt(np.einsum("ij,jk,ik->i", W, cov, W)), W @ mu, color="0.8", lw=0.7) ax.plot(res.frontier.volatilities, res.frontier.returns, lw=2, label="true frontier") ax.plot(res.volatilities, res.returns, "o-", color="C3", label="resampled frontier") ax.set_xlabel("volatility") ax.set_ylabel("expected return") ax.legend() fig.tight_layout() plt.show() .. image-sg:: /api/gallery/portfolio/bayesian/images/sphx_glr_plot_02_michaud_resampling_002.png :alt: plot 02 michaud resampling :srcset: /api/gallery/portfolio/bayesian/images/sphx_glr_plot_02_michaud_resampling_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.201 seconds) .. _sphx_glr_download_api_gallery_portfolio_bayesian_plot_02_michaud_resampling.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/portfolio/bayesian/plot_02_michaud_resampling.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_michaud_resampling.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_michaud_resampling.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_michaud_resampling.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_