Risk Parity or Budgeting with Constraints

This example shows how to solve risk parity or budgeting problems with constraints using `estimateCustomObjectivePortfolio`.

Risk parity is a portfolio allocation strategy that focuses on the allocation of risk to define the weights of a portfolio. You construct the risk parity portfolio, or equal risk contribution portfolio, by ensuring that all assets in a portfolio have the same risk contribution to the overall portfolio risk. The generalization of this problem is the risk budgeting portfolio in which you set the risk contribution of each asset to the overall portfolio risk. In other words, instead of all assets contributing equally to the risk of the portfolio, the assets' risk contribution must match a target risk budget.

In Risk Budgeting Portfolio, the example describes some advantages of risk parity or budgeting portfolios. It shows how to use `riskBudgetingPortfolio` to solve long-only, fully invested risk parity or budgeting problems. When the only constraints of the risk budgeting problem enforce nonnegative weights that sum to 1, the risk budgeting problem is a feasibility problem. In other words, the solution to the problem is the one that exactly matches the target risk budget and it is unique. Therefore, there is no need for an objective function. The `riskBudgetingPortfolio` function is optimized to solve this specific type of problems.

When you add more constraints to the risk parity problem, you must find the weight allocation that satisfies the extra constraints while trying to match the target risk budget as much as possible. The next section explains how.

Define Problem

Start by defining the problem data.

```% Assets variance vol = [0.1;0.15;0.2;0.3]; % Assets correlation rho = [1.00 0.50 0.50 0.50; 0.50 1.00 0.50 0.50; 0.50 0.50 1.00 0.75; 0.50 0.50 0.75 1.00]; % Assets covariance matrix Sigma = corr2cov(vol,rho); % Risk budget budget = [0.3;0.3;0.195;0.205];```

Obtain the long-only, fully invested risk budgeting portfolio to use as benchmark.

```% Long-only fully invested risk budgeting portfolio w_simple = riskBudgetingPortfolio(Sigma,budget); % Compute the risk contribution of the weight allocation RC_simple = portfolioRiskContribution(w_simple,Sigma); % Table with weights and risk contributions T_simple = table(w_simple,RC_simple,budget, ... VariableNames={'RB Portfolio','RB Contribution','Budget'})```
```T_simple=4×3 table RB Portfolio RB Contribution Budget ____________ _______________ ______ 0.45053 0.3 0.3 0.30035 0.3 0.3 0.14668 0.195 0.195 0.10244 0.205 0.205 ```

As desired, the risk contribution of the risk budgeting portfolio matches the `budget`.

Add Constraints to Risk Parity or Budgeting Portfolio

When you add constraints, other than the long-only, fully invested constraints, to the risk parity formulation, you must find the portfolio allocation that satisfies all the constraints and minimizes the deviation from the target risk budget.

The percent risk contribution of asset $\mathit{i}$ is defined as

${\mathrm{RC}}_{\mathit{i}}\left(\mathit{w}\right)=\frac{{\mathit{w}}_{\mathit{i}}{\left(\Sigma \mathit{w}\right)}_{\mathit{i}}}{{\mathit{w}}^{\mathit{T}}\Sigma \mathit{w}}$,

and the goal is to find the portfolio that minimizes the deviation of ${\mathrm{RC}}_{\mathit{i}}\left(\mathit{w}\right)$ to ${\mathit{b}}_{\mathit{i}}$, the target risk budget of asset $\mathit{i}$. For risk parity problems, ${\mathit{b}}_{\mathit{i}}=\frac{1}{\mathit{n}}$, where $\mathit{n}$ is the number of assets.

A common way to measure deviation is to use a norm. In this example, use the 2-norm. The risk parity or budgeting problem with constraints results in

`$\begin{array}{l}\underset{\mathit{w}}{\mathrm{min}}\text{\hspace{0.17em}\hspace{0.17em}}{\sum _{\mathit{i}}\left(\frac{{w}_{i}{\left(\Sigma w\right)}_{i}}{{w}^{T}\Sigma w}-{\mathit{b}}_{\mathit{i}}\right)}^{2}\\ \mathit{s}.\mathit{t}.\text{\hspace{0.17em}}\text{\hspace{0.17em}}\mathit{w}\in \Omega \end{array}$`

where $\Omega$ represents the feasible set that is defined by the desired constraints. The objective function is the sum of squares of the deviation of the risk contributions from the target. Notice that the objective function is nonconvex.

Next, introduce the constraint ${\mathit{x}}_{\mathit{i}}\le 0.3$, which means that no more than 30% of the capital can be invested in each asset.

```% Define the Portfolio object p = Portfolio(AssetCovar=Sigma); % Set bound constraints p = setBounds(p,0,0.3); % Set budget constraint p = setBudget(p,1,1);```

Create a function handle for the nonconvex objective

${\sum _{\mathit{i}}\left(\frac{{w}_{i}{\left(\Sigma w\right)}_{i}}{{w}^{T}\Sigma w}-{\mathit{b}}_{\mathit{i}}\right)}^{2}$.

```% Define objective function objFun = @(w) sum(((w.*(Sigma*w))/(w'*Sigma*w) - budget).^2);```

Solve the problem using `estimateCustomObjectivePortfolio` and `riskBudgetingPortfolio`.

```% Risk budgeting portfolio with extra constraints w_extra = estimateCustomObjectivePortfolio(p,objFun); % Risk contribution RC_extra = portfolioRiskContribution(w_extra,Sigma); % Table with weights and risk contributions T_extra = table(w_extra,RC_extra,budget, ... VariableNames={'RB Portfolio','RB Contribution','Budget'})```
```T_extra=4×3 table RB Portfolio RB Contribution Budget ____________ _______________ ______ 0.3 0.15505 0.3 0.3 0.24998 0.3 0.2465 0.30862 0.195 0.1535 0.28635 0.205 ```

Now that you have added additional constraints, the risk contribution of the resulting portfolio does not match the budget. Yet, the solution to the problem is minimizing the deviation of the risk contribution to the target risk budget. Because the risk budgeting portfolio without the extra constraints assigns weights larger than 30% to the first and second assets, the solution to the problem that minimizes the deviation assigns as much as possible to the first and second assets and distributes the rest to the other assets.

As explained in Role of Convexity in Portfolio Problems, because the objective function is nonconvex, this formulation cannot be solved by the `Portfolio` object solvers if you add cardinality constraints or conditional bounds to the problem.

Compare Risk Parity and Mean-Variance Portfolios

You can examine the difference in the allocation between the traditional minimum variance portfolio and the risk parity portfolio.

First compute the minimum variance portfolio. The traditional mean-variance framework requires the assets mean return to be defined before you compute any of the portfolios on the efficient frontier.

```% Define assets mean p.AssetMean = [0.1; 0.1; 0.15; 0.2]; % Minimum variance portfolio wMinVar = estimateFrontierLimits(p,'min');```

To compute the risk parity portfolio, make sure all assets contribute equally to the risk. Set ${\mathit{b}}_{\mathit{i}}=\frac{1}{\mathit{n}}$ and update the objective function.

```% Update budget budget = 1/p.NumAssets*ones(p.NumAssets,1); % Update objective objFun = @(w) sum(((w.*(Sigma*w))/(w'*Sigma*w) - budget).^2);```

Solve the risk parity problem using `estimateCustomObjectivePortfolio`.

```% Risk parity portfolio with extra constraints wRP = estimateCustomObjectivePortfolio(p,objFun);```

Compare the weight allocation concentrations.

```% Plot pie charts tiledlayout(1,2); % Minimum variance portfolio nexttile pie(wMinVar) title('Minimum Variance Portfolio',Position=[0,1.5]); % Risk parity portfolio nexttile pie(wRP) title('Risk Parity Portfolio',Position=[0,1.5]); % Add legend lgd = legend({'1','2','3','4'}); lgd.Layout.Tile = 'east';```

The portfolio allocation of the minimum variance portfolio sets all assets with the smallest risk to their maximum (30%). On the other hand, the risk parity allocation sets only the first two assets to 30% and the last two are more balanced. This result is a simple example of how the risk parity allocation helps to diversify a portfolio.