<a id="sphx-glr-auto-examples-risk-budgeting-plot-2-risk-budgeting-cvar-py"></a>

<a id="risk-budgeting-cvar"></a>

# Risk Budgeting - CVaR

This tutorial uses the [`RiskBudgeting`](https://skfolio.org/generated/skfolio.optimization.RiskBudgeting.html.md#skfolio.optimization.RiskBudgeting) optimization to
build a risk budgeting portfolio by specifying a risk budget on each asset with CVaR as
the risk measure.

<a id="data"></a>

## Data

We load the S&P 500 [dataset](https://skfolio.org/user_guide/datasets.html.md#datasets) composed of the daily prices of 20
assets from the S&P 500 Index composition starting from 1990-01-02 up to 2022-12-28:

```Python
from plotly.io import show
from sklearn.model_selection import train_test_split

from skfolio import Population, RiskMeasure
from skfolio.datasets import load_sp500_dataset
from skfolio.optimization import InverseVolatility, RiskBudgeting
from skfolio.preprocessing import prices_to_returns

prices = load_sp500_dataset()

X = prices_to_returns(prices)
X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)
```

<a id="risk-budget"></a>

## Risk Budget

We chose the following risk budget: 1.5 on Apple, 0.2 on General Electric and
JPMorgan and 1.0 on the remaining assets:

```Python
risk_budget = {asset_name: 1 for asset_name in X.columns}
risk_budget["AAPL"] = 1.5
risk_budget["GE"] = 0.2
risk_budget["JPM"] = 0.2
```

<a id="model"></a>

## Model

We create the risk budgeting model and then fit it on the training set:

```Python
model = RiskBudgeting(
    risk_measure=RiskMeasure.CVAR,
    risk_budget=risk_budget,
    portfolio_params=dict(name="Risk Budgeting - CVaR"),
)
model.fit(X_train)
model.weights_
```

```none
array([0.06173048, 0.03257426, 0.03336027, 0.03994757, 0.06349066,
       0.00930166, 0.04579232, 0.06880897, 0.00765321, 0.06700255,
       0.05537176, 0.05430752, 0.0482822 , 0.07033578, 0.05371225,
       0.0689283 , 0.04230919, 0.04897363, 0.06251636, 0.06560108])
```

To compare this model, we use an inverse volatility benchmark using
the [`InverseVolatility`](https://skfolio.org/generated/skfolio.optimization.InverseVolatility.html.md#skfolio.optimization.InverseVolatility) estimator:

```Python
bench = InverseVolatility(portfolio_params=dict(name="Inverse Vol"))
bench.fit(X_train)
bench.weights_
```

```none
array([0.03306735, 0.02548697, 0.03551377, 0.0296872 , 0.06358463,
       0.05434705, 0.04742354, 0.07049715, 0.03882539, 0.06697905,
       0.05570808, 0.05576851, 0.04723274, 0.06351213, 0.05581397,
       0.0676481 , 0.02564642, 0.03970752, 0.05744543, 0.06610498])
```

<a id="risk-contribution-analysis"></a>

## Risk Contribution Analysis

Let’s analyze the risk contribution of both models on the training set.
As expected, the risk budgeting model has 50% more CVaR contribution to Apple and 80%
less to General Electric and JPMorgan compared to the other assets:

```Python
ptf_model_train = model.predict(X_train)
fig = ptf_model_train.plot_contribution(measure=RiskMeasure.CVAR)
show(fig)
```

[plotly figure stripped from llms output]<style>html[data-theme="dark"] div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}@media (prefers-color-scheme: dark){html:not([data-theme="light"]) div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}}</style><script>if (!window.plotlySphinxGalleryResize) {window.plotlySphinxGalleryResize = true;window.addEventListener("load", function () {document.querySelectorAll(".plotly-graph-div").forEach(function (gd) { Plotly.Plots.resize(gd); });});}</script>

<br/>

And the inverse volatility model has different CVaR contribution for each asset:

```Python
ptf_bench_train = bench.predict(X_train)
ptf_bench_train.plot_contribution(measure=RiskMeasure.CVAR)
```

<style>html[data-theme="dark"] div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}@media (prefers-color-scheme: dark){html:not([data-theme="light"]) div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}}</style><script>if (!window.plotlySphinxGalleryResize) {window.plotlySphinxGalleryResize = true;window.addEventListener("load", function () {document.querySelectorAll(".plotly-graph-div").forEach(function (gd) { Plotly.Plots.resize(gd); });});}</script>[plotly figure stripped from llms output]
<br />
<br />

<a id="prediction"></a>

## Prediction

We predict the model and the benchmark on the test set:

```Python
ptf_model_test = model.predict(X_test)
ptf_bench_test = bench.predict(X_test)
```

<a id="analysis"></a>

## Analysis

For improved analysis, it’s possible to load both predicted portfolios into a
[`Population`](https://skfolio.org/generated/skfolio.population.Population.html.md#skfolio.population.Population):

```Python
population = Population([ptf_model_test, ptf_bench_test])
```

Let’s plot each portfolio composition:

```Python
population.plot_composition()
```

<style>html[data-theme="dark"] div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}@media (prefers-color-scheme: dark){html:not([data-theme="light"]) div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}}</style><script>if (!window.plotlySphinxGalleryResize) {window.plotlySphinxGalleryResize = true;window.addEventListener("load", function () {document.querySelectorAll(".plotly-graph-div").forEach(function (gd) { Plotly.Plots.resize(gd); });});}</script>[plotly figure stripped from llms output]
<br />
<br />

Let’s plot each portfolio cumulative returns:

```Python
fig = population.plot_cumulative_returns()
show(fig)
```

[plotly figure stripped from llms output]<style>html[data-theme="dark"] div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}@media (prefers-color-scheme: dark){html:not([data-theme="light"]) div.output_subarea:has(.plotly-graph-div){background:#fff;border-radius:0.25rem;padding:0.5rem}}</style><script>if (!window.plotlySphinxGalleryResize) {window.plotlySphinxGalleryResize = true;window.addEventListener("load", function () {document.querySelectorAll(".plotly-graph-div").forEach(function (gd) { Plotly.Plots.resize(gd); });});}</script>

<br/>

Finally, we print a full summary of both strategies evaluated on the test set:

```Python
population.summary()
```

<div class="output_subarea output_html rendered_html output_result">
<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>Risk Budgeting - CVaR</th>
      <th>Inverse Vol</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>Mean</th>
      <td>0.067%</td>
      <td>0.064%</td>
    </tr>
    <tr>
      <th>Annualized Mean</th>
      <td>17.00%</td>
      <td>16.06%</td>
    </tr>
    <tr>
      <th>Variance</th>
      <td>0.00010</td>
      <td>0.00010</td>
    </tr>
    <tr>
      <th>Annualized Variance</th>
      <td>2.57%</td>
      <td>2.56%</td>
    </tr>
    <tr>
      <th>Semi-Variance</th>
      <td>0.000052</td>
      <td>0.000053</td>
    </tr>
    <tr>
      <th>Annualized Semi-Variance</th>
      <td>1.32%</td>
      <td>1.33%</td>
    </tr>
    <tr>
      <th>Standard Deviation</th>
      <td>1.01%</td>
      <td>1.01%</td>
    </tr>
    <tr>
      <th>Annualized Standard Deviation</th>
      <td>16.02%</td>
      <td>16.00%</td>
    </tr>
    <tr>
      <th>Semi-Deviation</th>
      <td>0.72%</td>
      <td>0.73%</td>
    </tr>
    <tr>
      <th>Annualized Semi-Deviation</th>
      <td>11.50%</td>
      <td>11.54%</td>
    </tr>
    <tr>
      <th>Mean Absolute Deviation</th>
      <td>0.65%</td>
      <td>0.65%</td>
    </tr>
    <tr>
      <th>CVaR at 95%</th>
      <td>2.33%</td>
      <td>2.35%</td>
    </tr>
    <tr>
      <th>EVaR at 95%</th>
      <td>5.12%</td>
      <td>5.29%</td>
    </tr>
    <tr>
      <th>Worst Realization</th>
      <td>10.08%</td>
      <td>10.49%</td>
    </tr>
    <tr>
      <th>CDaR at 95%</th>
      <td>12.03%</td>
      <td>12.22%</td>
    </tr>
    <tr>
      <th>MAX Drawdown</th>
      <td>32.78%</td>
      <td>34.83%</td>
    </tr>
    <tr>
      <th>Average Drawdown</th>
      <td>2.34%</td>
      <td>2.34%</td>
    </tr>
    <tr>
      <th>EDaR at 95%</th>
      <td>18.98%</td>
      <td>20.05%</td>
    </tr>
    <tr>
      <th>First Lower Partial Moment</th>
      <td>0.33%</td>
      <td>0.32%</td>
    </tr>
    <tr>
      <th>Ulcer Index</th>
      <td>0.040</td>
      <td>0.040</td>
    </tr>
    <tr>
      <th>Gini Mean Difference</th>
      <td>0.99%</td>
      <td>0.98%</td>
    </tr>
    <tr>
      <th>Value at Risk at 95%</th>
      <td>1.43%</td>
      <td>1.45%</td>
    </tr>
    <tr>
      <th>Drawdown at Risk at 95%</th>
      <td>8.81%</td>
      <td>8.79%</td>
    </tr>
    <tr>
      <th>Entropic Risk Measure at 95%</th>
      <td>3.00</td>
      <td>3.00</td>
    </tr>
    <tr>
      <th>Fourth Central Moment</th>
      <td>0.000021%</td>
      <td>0.000022%</td>
    </tr>
    <tr>
      <th>Fourth Lower Partial Moment</th>
      <td>0.000010%</td>
      <td>0.000011%</td>
    </tr>
    <tr>
      <th>Skew</th>
      <td>-2.47%</td>
      <td>-14.95%</td>
    </tr>
    <tr>
      <th>Kurtosis</th>
      <td>2033.11%</td>
      <td>2118.56%</td>
    </tr>
    <tr>
      <th>Sharpe Ratio</th>
      <td>0.067</td>
      <td>0.063</td>
    </tr>
    <tr>
      <th>Annualized Sharpe Ratio</th>
      <td>1.06</td>
      <td>1.00</td>
    </tr>
    <tr>
      <th>Sortino Ratio</th>
      <td>0.093</td>
      <td>0.088</td>
    </tr>
    <tr>
      <th>Annualized Sortino Ratio</th>
      <td>1.48</td>
      <td>1.39</td>
    </tr>
    <tr>
      <th>Mean Absolute Deviation Ratio</th>
      <td>0.10</td>
      <td>0.098</td>
    </tr>
    <tr>
      <th>First Lower Partial Moment Ratio</th>
      <td>0.21</td>
      <td>0.20</td>
    </tr>
    <tr>
      <th>Value at Risk Ratio at 95%</th>
      <td>0.047</td>
      <td>0.044</td>
    </tr>
    <tr>
      <th>CVaR Ratio at 95%</th>
      <td>0.029</td>
      <td>0.027</td>
    </tr>
    <tr>
      <th>Entropic Risk Measure Ratio at 95%</th>
      <td>0.00023</td>
      <td>0.00021</td>
    </tr>
    <tr>
      <th>EVaR Ratio at 95%</th>
      <td>0.013</td>
      <td>0.012</td>
    </tr>
    <tr>
      <th>Worst Realization Ratio</th>
      <td>0.0067</td>
      <td>0.0061</td>
    </tr>
    <tr>
      <th>Drawdown at Risk Ratio at 95%</th>
      <td>0.0077</td>
      <td>0.0073</td>
    </tr>
    <tr>
      <th>CDaR Ratio at 95%</th>
      <td>0.0056</td>
      <td>0.0052</td>
    </tr>
    <tr>
      <th>Calmar Ratio</th>
      <td>0.0021</td>
      <td>0.0018</td>
    </tr>
    <tr>
      <th>Average Drawdown Ratio</th>
      <td>0.029</td>
      <td>0.027</td>
    </tr>
    <tr>
      <th>EDaR Ratio at 95%</th>
      <td>0.0036</td>
      <td>0.0032</td>
    </tr>
    <tr>
      <th>Ulcer Index Ratio</th>
      <td>0.017</td>
      <td>0.016</td>
    </tr>
    <tr>
      <th>Gini Mean Difference Ratio</th>
      <td>0.068</td>
      <td>0.065</td>
    </tr>
    <tr>
      <th>Effective Number of Assets</th>
      <td>17.7281118539998</td>
      <td>18.460872007821077</td>
    </tr>
    <tr>
      <th>Assets Number</th>
      <td>20</td>
      <td>20</td>
    </tr>
  </tbody>
</table>
</div>
</div>
<br />
<br />

**Total running time of the script:** (0 minutes 1.901 seconds)

<a id="sphx-glr-download-auto-examples-risk-budgeting-plot-2-risk-budgeting-cvar-py"></a>
