Initializing help system before first use

Robust portfolio optimization

Topics covered in this section:

Problem description

The single-period portfolio selection problem is about selecting assets from a given list in order to create a portfolio that has the greatest expected value. The assets are bought at the market price and their value is subject to variation. The investment budget is fixed, and each selected asset is bought using a percentage of the available budget. The market price for each asset is known at the time of buying and corresponds to the payment to be made by the trader to buy one unit. The future asset value is not known, but we assume the distribution characteristics of the random variable is known. The trader is risk averse and wants to have some guarantees about the worst case value of the portfolio. She considers that in the worst case the downward variation of an asset value reaches 1.5 times the variance of the asset. In other words, the trader assumes it is very unlikely that the value of an asset decreases by more than 1.5 times its variance.

Example: Let's assume that asset #20 has a market price of 100$ and its variability is +/- 10$. Then the considered worst case value of the asset is 85$.

In this context, the objective of the trader is to maximize the expected value of her portfolio, but without taking too much risk. A conservative trader would definitely spend all her budget in the asset with the highest worst case value in order to be highly protected against the worst possible outcome. Unfortunately, this strategy would dramatically reduce the expected value of the portfolio. Another extreme policy would be an opportunistic trader who spends all her budget in the asset with the highest expected value, without paying much attention to the worst case realization. Both approaches are extreme and do not take into account the fact that it is quite unlikely to see all asset values going down (or going up) to the same degree. In practice traders often aim for portfolios with a guaranteed probability of having a value greater than a minimum target value. This is also known as chance constrained optimization. In the 'Results' section (Results) we will show how robust optimization can be used to provide solutions with a large expected value without sacrificing protection against worst case realization.

Mathematical formulation

The set S contains the available assets, and the index s∈S represents an asset from this set. The market price of the asset s is noted PRICEs, and its variability range is given by VARs. For each asset s∈S, the variable xs represents the fraction of the budget spent to buy asset s. The variable w is used to represent the worst case value of the portfolio. The variable devs describes the possible variation of the value of the asset s. The value N describes the worst case the trader will consider and corresponds to the maximum decrease of the asset value expressed as a multiple of its standard deviation.

Highest protection

A conservative trader will want to maximize the worst case value of her portfolio. If she wants to get the best protection against worst case realization, then she will try to maximize the worst case value of her portfolio. In our example, this worst case realizes when the value of every asset decreases by N times its standard deviation.

max w
s.t. w ≤ s∈S (PRICEs + N·devs)·xs (with devs = - VARs)
s∈S xs = 1
0 ≤ xs ≤ 1

Budgeted protection

As we will see in the discussion of the results (Section Results), achieving a high protection against worst case realization incurs an important loss of value in the average case. And hence, this strategy may not be such a clever choice because average cases are more likely to happen. The trader therefore might want to improve her model by adding a control parameter to limit the protection level. The overall variation budget G is defined by the following formula:

G =
s∈S
(N· VARs) 2

The ellipsoidal uncertainty set
Let k be the percentage value representing the protection level. The possible asset value decrease is controlled by the uncertainty set U(k) that is defined as follows:

U(k) = { e :
s∈S
es2 ≤ (k·G)2 }

Robust constraints
The resulting robust optimization problem can then be stated as:

max w
s.t. w ≤ ∑s∈S (PRICEs + es) · xs  (∀ e∈U(k))
s∈S xs = 1
0 ≤ xs ≤ 1

Implementation

The following Mosel model implements the mathematical model from the previous section. Notice how the ellipsoid uncertainty set is added to the original problem to create a robust optimization problem.

Also, take a look at how the Monte-Carlo simulation method is applied to quantify the quality of the solution: in NMC=5000 iterations we draw random values for the expected value of every asset by applying a normal distribution centered around its price (mean value) and using its known variance. We count the occurrence of objective function values (or more precisely, which value range the resulting solution value belongs to) to determine the probabilities of different solution qualities. This method is particularly helpful to gain some insight about the solution quality when it is difficult to determine the exact shape of the distribution function of a random variable.

model "Robust portfolio optimization"
  uses "mmrobust", "random"
  uses "mmsystem"

  parameters
    ZEROTOL=1e-6
    SEED=12345
    NMC=500000
    N=1.5                              ! Worst case metric
  end-parameters

  declarations
    Problems: set of mpproblem
    ProtectLevel: set of real

    mp_problemA: mpproblem             ! Worst case optimization
    mp_problemB: array(ProtectLevel) of mpproblem  ! Robust optimization
    NSHARES = 25                       ! Max number of shares
    Shares = 1..NSHARES                ! Set of shares

    PRICE: array(Shares) of real       ! Expected return on investment
    VAR: array(Shares) of real         ! Uncertainty measure (deviation) per SHARE

    expReturn: mpvar                   ! Expected portfolio value
    wstReturn: mpvar                   ! Worst case portfolio value
    frac: array(Shares) of mpvar       ! Fraction of capital used per share
    frac_sol: array(Shares,Problems) of real
    obj: mpvar

    e: array(Shares) of uncertain      ! Deviation of share values
    PRICEthr: array(Problems,Shares) of real    ! The price threshold

  end-declarations

!***************************Configuration*************************
 setparam("XPRS_LOADNAMES",true)

!***************************Subroutines***************************
 !**** Create the nominal model ****
  procedure create_nominalmodel
    ! Nominal model
    expReturn = (sum(s in Shares) PRICE(s)*frac(s))
    wstReturn = sum(s in Shares) ( PRICE(s) - N*VAR(s) )*frac(s)

    ! Spend all the budget
    sum(s in Shares) frac(s) = 1
  end-procedure

 !**** Optimize for the worst case realization ****
  procedure solve_det
    obj = wstReturn
    maximize(obj)
  end-procedure

 !**** Optimize for a given protection level ****
  procedure solve_rob(k: real)
    ! The value variation domain

    assert(k>=0  and k<=1)
    sum(s in Shares) (e(s) / (N*VAR(s)))^2 <= (k)^2

    ! The robust constraint
    obj <= sum(s in Shares) (PRICE(s) + e(s)) * frac(s)

    maximize(obj)
  end-procedure

!***************************Main model***************************
  !**** Input data generation ****
  setmtrandseed(12345)
  cnt := 0
  forall(s in Shares, cnt as counter) do
    PRICE(s) := round((100*(NSHARES-cnt+1)/NSHARES))
    c := (1+sqrt((NSHARES-s)/NSHARES))/3
    VAR(s) := round(PRICE(s)*c*100)/100
  end-do

  writeln("\n *** Input Data *** ")
  writeln
  writeln("Shares | Mean | S.Dev. | Worst value")
  forall(s in Shares)
    writeln(strfmt(s,6), " |", strfmt(PRICE(s),5), " |", strfmt(VAR(s),7,2),
      " |", strfmt(PRICE(s)-N*VAR(s),6,3))
  writeln

  !**** Optimize the worst case ****
  with mp_problemA do
    create_nominalmodel
    solve_det
    forall(s in Shares) frac_sol(s,mp_problemA) := frac(s).sol*100
    ! Price set by opponent is worst case price
    forall(s in Shares) PRICEthr(mp_problemA,s) := PRICE(s) - N*VAR(s)
  end-do

  !**** Optimize the 'budgeted' worst case ****
  Ks := [0.0,     ! No variation on average
         0.01,    ! +/-  1% variation on the list
         0.10,    ! +/- 10% variation on the list
         0.25,    ! +/- 25%
         1.0]     ! +/-100% variation on the list
  forall(k in Ks) do
    create(mp_problemB(k))
    with mp_problemB(k) do
      create_nominalmodel
      solve_rob(k)
      forall(s in Shares) frac_sol(s,mp_problemB(k)) := frac(s).sol*100
      forall(s in Shares) PRICEthr(mp_problemB(k),s) := (PRICE(s) + getsol(e(s)))
    end-do
  end-do

  !**** Print results ****
  writeln("\n *** Portfolio allocation results *** ")
  write("\n                                  |  protection level")
  write("\nShares | Wst price | Price |  A   |")
  forall(k in Ks) write(" ", strfmt(k*100,3), "% |" ) ; writeln
  forall(s in Shares) do
    write(strfmt(s,6), " |", strfmt(PRICE(s)-N*VAR(s),10,0), " |",
      strfmt(PRICE(s),6), " | ")
    forall(mp in Problems) do
      if (frac_sol(s,mp)>1) then
        write(strfmt(frac_sol(s,mp),3,0), "% | ")
      else
        write("     | ")
      end-if
    end-do
    writeln
  end-do

  writeln("\n *** Worst case price *** ")
  write("\n                                  |  protection level")
  write("\nShares | Wst price | Price |  A   |")
  forall(k in Ks) write(" ", strfmt(k*100,3), "% |" ) ; writeln
  forall(s in Shares) do
    write(strfmt(s,6), " |", strfmt(PRICE(s)-N*VAR(s),10,0), " |",
      strfmt(PRICE(s),6), " | ")
    forall(mp in Problems) do
      if (frac_sol(s,mp)>1) then
        write(strfmt(PRICEthr(mp,s),3,0), "* | ")
      else
        write(strfmt(PRICEthr(mp,s),4,0), " | ")
        ! write("     | ")
      end-if
    end-do
    writeln
  end-do

  !**** Simulate results (Monte-Carlo simulation) ****
  writeln("\nRunning Monte-Carlo simulation...")
  Values := {0,20,40,60,80,100}
  declarations
    cntV: dynamic array(Problems,Values) of real
    s1: real
    s2: real
  end-declarations
  forall(mp in Problems) do
    expRev(mp) := 0.0 ; wstRev(mp) := 0.0 ; expDev(mp) := 0.0
    forall(v in Values) cntV(mp,v) := 0
    c := 0.0 ! Number of draws
    s1 := 0 ; s2 := 0;
    forall(i in 1..NMC, c as counter) do
      totalVal := 0.0 ; totalRisk := 0.0
      forall(s in Shares | frac_sol(s,mp)>0) do
       	! draw a price
        p := normal(PRICE(s),VAR(s))
        ! calculate share revenue
        r := frac_sol(s,mp)*p/100
        ! calculate total revenue
        totalVal += r ! summing up revenue
      end-do
      forall(v in Values) do
        if (totalVal>v) then
          cntV(mp,v) += 1
        end-if
      end-do
      expRev(mp) += totalVal
      s1 += totalVal
      s2 += totalVal^2
    end-do
    expRev(mp) := expRev(mp) / c
    expDev(mp) := sqrt(NMC*s2 - s1^2)/(NMC)
    forall(v in Values) cntV(mp,v) := cntV(mp,v) / c
  end-do

  !**** Print simulation results ****
  write("\n                                   |  protection level")
  write("\n                            |  A   |")

  forall(k in Ks) write(" ", strfmt(k*100,3), "% |" )
  write("\n            Expected value  |")
  forall(mp in Problems) write(strfmt(round(expRev(mp)),5), " |")
  write("\n        Standard deviation  |")
  forall(mp in Problems) write(strfmt(round(expDev(mp)),5), " |")

  writeln
  forall(v in Values) do
    write("\n             P (value>"+textfmt(v,3)+"   |")
    forall(mp in Problems) write(strfmt(cntV(mp,v),5,2) , "  |")
  end-do

end-model

Results

In order to understand how the uncertainty set impacts the solution we will solve the portfolio allocation problem for various protection levels k and compare the proposed budget allocation against the conservative approach.

The trader knows that she can expect a portfolio value in the range of 0 to 100. She therefore wishes to calculate for various ranges the probability that the value of the portfolio will belong to this range. She also wants to reach a portfolio value of 60 with high probability.

Input Data

Table Asset value distribution shows the asset mean value which is also the market price (Mean), the standard variation of the value (S. Dev), and the considered worst case value with N=1.5 (Worst value).

Table 11: Asset value distribution
Shares Mean S.Dev. Worst value
1 100 65.99 1.015
2 96 62.69 1.965
3 92 59.43 2.855
4 88 56.22 3.670
5 84 53.04 4.440
6 80 49.91 5.135
7 76 46.83 5.755
8 72 43.79 6.315
9 68 40.80 6.800
10 64 37.86 7.210
11 60 34.97 7.545
12 56 32.13 7.805
13 52 29.34 7.990
14 48 26.61 8.085
15 44 23.94 8.090
16 40 21.33 8.005
17 36 18.79 7.815
18 32 16.31 7.535
19 28 13.91 7.135
20 24 11.58 6.630
21 20 9.33 6.005
22 16 7.18 5.230
23 12 5.13 4.305
24 8 3.20 3.200
25 4 1.33 2.005

A quick glance at the input data reveals that asset #15 would be the best choice for the conservative trader because it has the highest worst case value, whereas asset #1 would be the preferred investment for an optimistic trader since it has the largest best case value.

Analysis

In order to understand how the robust optimization behaves compared to the nominal problem, we solve the nominal problem (A) and 5 robust optimization problems parameterized by the protection level k (ranging from 0 to 1=100%). With a protection level of k=0 the deviation budget is also zero, and hence the solution is a very optimistic one.

In a second step, we use a Monte-Carlo method to simulate the actual value of the assets selected by these solutions and calculate the probability with which the portfolio value lies in the various revenue ranges.

Table Results of the parameterized robust optimization presents the portfolio selection suggestion for each of these problems. For the sake of simplicity we list only those assets that are selected in at least one solution. The conservative solution (A) is to allocate all budget to the asset with highest worst case value. The optimistic solution (k=0.0) is to allocate the whole budget to the asset with the highest expected value. With an increasing protection level the suggested solutions improve the balance between assets with a high largest expected value and those with a high worst case value.

Table 12: Results of the parameterized robust optimization
Shares Wst price Price A k=0.0% k=1% k=10% k=25% k=100%
1 1 100 100% 100% 60% 33% 11%
2 2 96 35% 28% 11%
3 3 92 5% 22% 11%
4 4 88 14% 11%
5 4 84 3% 11%
6 5 80 10%
7 6 76 10%
8 6 72 9%
9 7 68 7%
10 7 64 5%
11 8 60 2%
15 8 44 100%

Table Results of the Monte-Carlo simulation presents the results of the Monte-Carlo simulation of the portfolio value for each portfolio selection suggestion. The conservative solution (A) is the one with highest worst case value, and as expected the probability of this portfolio's value to go above 60 is very low. From the trader's point of view this is not a good solution, even in the average case for which she will get a value of 44.

The optimistic solution (k=0%) and the solution with the lowest protection level (k=1%) have the largest expected value. However, the trader cannot use these two solutions because she won't be able to commit to achieving a minimum value of 60 since the probability of obtaining a portfolio value greater than 60 is only 73% for these two solutions.

The behavior of the other solutions (k≥10%) shows that with an increasing deviation budget, the probability of achieving a portfolio value higher than 60 also increases. The worst case value of the portfolio equally increases while the expected value decreases. The volatility of the distribution of the values against the three ranges tends to reduce.

Table 13: Results of the Monte-Carlo simulation
A k=0.0% k=1% k=10% k=25% 100%
Expected value 44 100 100 98 95 83
Standard deviation 24 66 66 45 32 17
P (value≥0) 97% 94% 93% 98% 100% 100%
P (value≥20) 84% 89% 89% 96% 99% 100%
P (value≥40) 57% 82% 82% 90% 96% 99%
P (value≥60) 25% 73% 73% 80% 86% 91%
P (value≥80) 07% 62% 62% 66% 68% 58%
P (value≥100) 01% 50% 50% 48% 44% 17%

The solution with k=100% protects the trader against important losses and allows her to commit to a minimum portfolio value of 60 with a likelyhood of more than 90% and a total expected value of 83. A more risk-prone trader may want to reduce the protection level to say, 10% resulting in a considerably higher average outcome (98) and still having a 90% chance of achieving a portfolio value greater than 40.

References

The presented problem is inspired by the Single-Period Portfolio selection problem described in [Bng09].

Applications of robust optimization to portfolio optimizations models date back to as early as 2000 [Bmn00].


© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.