Minimum CVaR
Calculate the weights of the minimum Conditional Value at Risk (CVaR) portfolio: the fully invested portfolio whose average loss in the worst periods is the smallest. Unlike variance, CVaR only looks at the losses in the tail, so it accounts for skewed and fat-tailed returns.
The problem is solved as a linear programme over the historical returns: minimize VaR + 1/((1 - α)T) Σ max(0, -r_t’w - VaR), with α the confidence level and T the number of periods.
For more information, see the following paper:
- Rockafellar, R.T. and Uryasev, S. (2000). “Optimization of Conditional Value-at-Risk.” Journal of Risk, 2(3), 21-41.
Also known as: minimum expected shortfall portfolio, mean-CVaR, tail risk optimization.
Minimum CVaR in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_minimum_cvar_weights as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["AAPL", "MSFT", "JNJ", "XOM"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
toolkit.portfolio.get_minimum_cvar_weights()
Or, after setting up the Finance Toolkit MCP, ask:
Which weights in Apple, Microsoft, Johnson & Johnson and ExxonMobil minimized the 95% conditional value at risk, based on 2021 to 2025?
Which returns:
| Weight | Expected Return | Volatility | Sharpe Ratio | Risk Contribution | CVaR | |
|---|---|---|---|---|---|---|
| AAPL | 0 | 0.1933 | 0.2786 | 0.5727 | 0 | 0.0389 |
| MSFT | 0.1823 | 0.2017 | 0.2572 | 0.6532 | 0.1507 | 0.0355 |
| JNJ | 0.5966 | 0.0984 | 0.1673 | 0.3867 | 0.6006 | 0.0227 |
| XOM | 0.2211 | 0.291 | 0.2702 | 0.9522 | 0.2488 | 0.0369 |
| Portfolio | 1 | 0.1598 | 0.136 | 0.9273 | 1 | 0.0189 |
Parameters
get_minimum_cvar_weights accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
confidence_level | float | The confidence level of the CVaR, e.g. 0.95 for the average of the worst 5% of periods. Defaults to 0.95. | 0.95 |
period | str | The frequency of the returns (daily, weekly, monthly, quarterly or yearly). Defaults to “daily”. | "weekly" |
minimum_weight | float | The lowest weight an asset may have. Defaults to 0. | 0 |
maximum_weight | float | The highest weight an asset may have. Defaults to 1. | 1 |
include_benchmark | bool | Whether to include the benchmark as an asset. Defaults to False. | True |
rounding | int | None | The number of decimals to round the results to. Defaults to None, which uses the Toolkit’s rounding. | 2 |