.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/portfolio/risk_based/plot_01_cvar_optimization.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_risk_based_plot_01_cvar_optimization.py: Rockafellar-Uryasev CVaR optimization ===================================== Value at risk is not convex in the portfolio weights, so minimizing it is hard. R. Tyrrell Rockafellar and Stanislav Uryasev (2000) showed that conditional value at risk (expected shortfall) is, and better: over a set of scenarios, minimizing it is a linear program, .. math:: \min_{w,\zeta,u}\; \zeta + \frac{1}{(1-\alpha)n}\sum_k u_k \quad\text{s.t.}\quad u_k \ge -r_k'w - \zeta,\; u_k \ge 0, and the optimal :math:`\zeta` is the VaR as a by-product. With fat-tailed, skewed scenarios, the CVaR-optimal portfolio avoids the asset whose variance looks modest but whose crashes are large. .. GENERATED FROM PYTHON SOURCE LINES 21-37 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from financialkit.portfolio import cvar_optimization, efficient_portfolio from financialkit.portfolio.visualizers import plot_weights from financialkit.risk import expected_shortfall rng = np.random.default_rng(9) names = ["bonds", "equity", "credit carry", "commodities"] n = 2000 R = rng.multivariate_normal([0.003, 0.006, 0.0, 0.005], np.diag([0.01, 0.045, 0.008, 0.05]) ** 2, size=n) # The carry trade earns a steady premium but loses heavily in crash months, alongside equities. crash = rng.random(n) < 0.04 R[:, 2] += np.where(crash, -0.10, 0.009) R[:, 1] += np.where(crash, -0.05, 0.0) .. GENERATED FROM PYTHON SOURCE LINES 38-40 Minimum-CVaR versus minimum-variance at the same mean ----------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 40-53 .. code-block:: Python target = 0.004 cv = cvar_optimization(R, 0.95, target_return=target) mv = efficient_portfolio(R.mean(axis=0), np.cov(R, rowvar=False), target, long_only=True) fig, axes = plt.subplots(1, 2, figsize=(10, 3.5), sharey=True) plot_weights(mv.weights, names, ax=axes[0]).set_title("minimum variance") plot_weights(cv.weights, names, ax=axes[1]).set_title("minimum 95% CVaR") fig.tight_layout() for label, w in [("min variance", mv.weights), ("min CVaR", cv.weights)]: pnl = R @ w print(f"{label:>12}: vol {pnl.std():.4f}, 95% ES {expected_shortfall(pnl, 0.95):.4f}") print(f"LP: CVaR {cv.cvar:.4f}, VaR (zeta) {cv.var:.4f}") .. image-sg:: /api/gallery/portfolio/risk_based/images/sphx_glr_plot_01_cvar_optimization_001.png :alt: minimum variance, minimum 95% CVaR :srcset: /api/gallery/portfolio/risk_based/images/sphx_glr_plot_01_cvar_optimization_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none min variance: vol 0.0111, 95% ES 0.0291 min CVaR: vol 0.0124, 95% ES 0.0226 LP: CVaR 0.0226, VaR (zeta) 0.0170 .. GENERATED FROM PYTHON SOURCE LINES 54-56 The mean-CVaR frontier ---------------------- .. GENERATED FROM PYTHON SOURCE LINES 56-66 .. code-block:: Python targets = np.linspace(R.mean(axis=0).min() + 1e-4, R.mean(axis=0).max() - 1e-4, 15) fig, ax = plt.subplots(figsize=(7, 3.5)) for a in [0.9, 0.95, 0.99]: ax.plot([cvar_optimization(R, a, t).cvar for t in targets], targets, "o-", ms=3, label=f"alpha = {a}") ax.set_xlabel("CVaR (monthly loss)") ax.set_ylabel("expected return") ax.legend() fig.tight_layout() plt.show() .. image-sg:: /api/gallery/portfolio/risk_based/images/sphx_glr_plot_01_cvar_optimization_002.png :alt: plot 01 cvar optimization :srcset: /api/gallery/portfolio/risk_based/images/sphx_glr_plot_01_cvar_optimization_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.732 seconds) .. _sphx_glr_download_api_gallery_portfolio_risk_based_plot_01_cvar_optimization.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/risk_based/plot_01_cvar_optimization.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_01_cvar_optimization.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_01_cvar_optimization.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_01_cvar_optimization.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_