Robust Optimization Example Using CVXPY

Robust Optimization Example Using CVXPY

Robust optimization is a technique used to handle uncertainty in optimization problems.

In contrast to standard optimization, where we assume exact data, robust optimization considers that some of the data (like costs, constraints, or coefficients) are uncertain and vary within known bounds.

This ensures that the solution is feasible and performs well even in the worst-case scenario of these uncertainties.

In this example, we will solve a robust portfolio optimization problem where we aim to minimize the worst-case risk (variance) of a portfolio under uncertain returns.

Problem Description: Robust Portfolio Optimization

Imagine we have an investor who wants to allocate their capital across several assets.

The investor is uncertain about the expected returns of these assets but knows that the returns lie within a given uncertainty range.
The goal is to find an optimal portfolio allocation that minimizes the worst-case risk (variance) while ensuring the expected return exceeds a certain threshold.

Variables:

  • $( x )$: Vector of asset weights (the proportion of capital allocated to each asset).

Objective:

Minimize the worst-case variance of the portfolio.

Constraints:

  • The total portfolio allocation should sum to $1$ (i.e., $( \sum x_i = 1 )$).
  • The expected return should be at least a target value $( R_{\text{min}} )$.
  • The asset returns are uncertain but lie within a given uncertainty set.

We will now define and solve this robust optimization problem in $Python$ using $CVXPY$.

Step-by-Step Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import cvxpy as cp
import numpy as np

# Step 1: Define the problem data
n = 4 # Number of assets
np.random.seed(42)

# Covariance matrix of returns (representing risk/variance)
Sigma = np.array([
[0.1, 0.02, 0.04, 0.01],
[0.02, 0.08, 0.03, 0.02],
[0.04, 0.03, 0.09, 0.03],
[0.01, 0.02, 0.03, 0.07]
])

# Expected returns (uncertain)
mu = np.array([0.1, 0.12, 0.14, 0.08]) # Nominal expected returns
delta_mu = np.array([0.02, 0.03, 0.02, 0.01]) # Uncertainty in returns

# Minimum target return
R_min = 0.11

# Step 2: Define the decision variables
x = cp.Variable(n) # Portfolio weights

# Step 3: Define the robust constraints and objective

# Constraint 1: The total portfolio allocation should sum to 1
constraints = [cp.sum(x) == 1, x >= 0]

# Robust constraint: Expected return should be at least R_min for the worst-case returns
worst_case_return = mu - delta_mu # Worst-case scenario for returns
constraints.append(worst_case_return @ x >= R_min)

# Objective: Minimize the worst-case portfolio variance
portfolio_variance = cp.quad_form(x, Sigma)
objective = cp.Minimize(portfolio_variance)

# Step 4: Define and solve the optimization problem
problem = cp.Problem(objective, constraints)
problem.solve()

# Step 5: Output the results
print("Status:", problem.status)
print("Optimal portfolio allocation:", x.value)
print("Minimum worst-case risk (variance):", portfolio_variance.value)

Explanation

  1. Problem Data:

    • We define a covariance matrix Sigma, representing the variance and correlation between the returns of the assets. The diagonal elements represent the variance of individual assets, while the off-diagonal elements represent the covariance between pairs of assets.
    • The vector mu contains the nominal (expected) returns for each asset, and delta_mu represents the uncertainty in these returns.
    • The target return $( R_{\text{min}} )$ is set to $0.11$, meaning the investor wants the portfolio to yield at least an $11$% return, even in the worst-case scenario.
  2. Decision Variables:

    • The variable x represents the portfolio weights, i.e., the proportion of the total capital allocated to each asset.
  3. Constraints:

    • The total allocation must sum to $1$ (cp.sum(x) == 1), meaning all the capital must be invested.
    • The worst-case expected return (worst_case_return @ x) should be at least $( R_{\text{min}} )$, ensuring the portfolio remains profitable under uncertainty.
    • We also require non-negative portfolio weights (x >= 0), assuming no short selling.
  4. Objective:

    • The objective is to minimize the portfolio’s worst-case variance (cp.quad_form(x, Sigma)), which is a quadratic form representing the portfolio’s risk.
  5. Solution:

    • We solve the problem using problem.solve(). If the problem is feasible, it will return the optimal portfolio weights that minimize the worst-case risk while satisfying the constraints.

Output

1
2
3
Status: optimal
Optimal portfolio allocation: [0.02536232 0.29347826 0.67753623 0.00362319]
Minimum worst-case risk (variance): 0.062065217391304356

Interpretation of Results

  • Optimal Portfolio Allocation:
    The optimal portfolio weights allocate the investor’s capital across the four assets.
    For instance, $25$% of the total capital is allocated to the first asset, $29$% to the second, and so on.

  • Minimum Worst-Case Risk:
    The worst-case risk (variance) of the portfolio is minimized at around $0.062$, indicating the portfolio has been optimized to minimize risk under uncertain returns.

Conclusion

This example demonstrated how to use $CVXPY$ to solve a robust optimization problem in the context of portfolio optimization.

Robust optimization allows us to account for uncertainty in the data (such as uncertain returns in this case) and find solutions that are robust to worst-case scenarios.

The problem ensures that the portfolio achieves the target return even in the worst case while minimizing the overall risk.

This technique is useful in finance and other fields where uncertainty is present, and decision-makers seek solutions that perform well under a range of possible conditions.