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.

ParameterTypeDescriptionExample
confidence_levelfloatThe confidence level of the CVaR, e.g. 0.95 for the average of the worst 5% of periods. Defaults to 0.95.0.95
periodstrThe frequency of the returns (daily, weekly, monthly, quarterly or yearly). Defaults to “daily”."weekly"
minimum_weightfloatThe lowest weight an asset may have. Defaults to 0.0
maximum_weightfloatThe highest weight an asset may have. Defaults to 1.1
include_benchmarkboolWhether to include the benchmark as an asset. Defaults to False.True
roundingint | NoneThe number of decimals to round the results to. Defaults to None, which uses the Toolkit’s rounding.2
Share