# Worst case risk analysis

Generate data for worst-case risk analysis.

using Random
using LinearAlgebra
Random.seed!(2);
n = 5;
r = abs.(randn(n, 1)) / 15;
Sigma = 0.9 * rand(n, n) .- 0.15;
Sigma_nom = Sigma' * Sigma;
Sigma_nom .-= (maximum(Sigma_nom) - 0.9)
Sigma_nom .+= (1e-4 - eigmin(Sigma_nom)) * I(n) # ensure positive-definite
5×5 Matrix{Float64}:
0.815627  0.810538  0.552307  0.705074  0.305739
0.810538  0.900299  0.503982  0.653689  0.264473
0.552307  0.503982  0.520053  0.555206  0.239068
0.705074  0.653689  0.555206  0.65939   0.30417
0.305739  0.264473  0.239068  0.30417   0.253124

Form and solve portfolio optimization problem. Here we minimize risk while requiring a 0.1 return.

using Convex, SCS
w = Variable(n);
ret = dot(r, w);
problem = minimize(risk, [sum(w) == 1, ret >= 0.1, norm(w, 1) <= 2])
solve!(problem, SCS.Optimizer; silent = true)
Problem statistics
problem is DCP         : true
number of variables    : 1 (5 scalar elements)
number of constraints  : 3 (3 scalar elements)
number of coefficients : 35
number of atoms        : 13

Solution summary
termination status : OPTIMAL
primal status      : FEASIBLE_POINT
dual status        : FEASIBLE_POINT
objective value    : 0.2666

Expression graph
minimize
└─ sum (convex; positive)
└─ * (convex; positive)
├─ [1;;]
└─ qol_elem (convex; positive)
├─ …
└─ …
subject to
├─ == constraint (affine)
│  └─ + (affine; real)
│     ├─ sum (affine; real)
│     │  └─ …
│     └─ [-1;;]
├─ ≥ constraint (affine)
│  └─ + (affine; real)
│     ├─ sum (affine; real)
│     │  └─ …
│     └─ [-0.1;;]
└─ ≤ constraint (convex)
└─ + (convex; real)
├─ sum (convex; positive)
│  └─ …
└─ [-2;;]

wval = vec(evaluate(w))
5-element Vector{Float64}:
-0.5000121289959703
0.525728210844552
0.340754030857417
1.273230184000672e-7
0.6335297535662603

Form and solve worst-case risk analysis problem.

Sigma = Semidefinite(n);
Delta = Variable(n, n);
problem = maximize(
risk,
[
Sigma == Sigma_nom + Delta,
diag(Delta) == 0,
abs(Delta) <= 0.2,
Delta == Delta',
],
);
solve!(problem, SCS.Optimizer; silent = true)
Problem statistics
problem is DCP         : true
number of variables    : 2 (50 scalar elements)
number of constraints  : 5 (105 scalar elements)
number of coefficients : 92
number of atoms        : 19

Solution summary
termination status : OPTIMAL
primal status      : FEASIBLE_POINT
dual status        : FEASIBLE_POINT
objective value    : 0.7635

Expression graph
maximize
└─ sum (affine; real)
└─ * (affine; real)
├─ * (affine; real)
│  ├─ …
│  └─ …
└─ 5×1 Matrix{Float64}
subject to
├─ == constraint (affine)
│  └─ + (affine; real)
│     ├─ 5×5 real variable (id: 855…776)
│     └─ Convex.NegateAtom (affine; real)
│        └─ …
├─ == constraint (affine)
│  └─ + (affine; real)
│     ├─ diag (affine; real)
│     │  └─ …
│     └─ Convex.NegateAtom (constant; negative)
│        └─ …
├─ ≤ constraint (convex)
│  └─ + (convex; real)
│     ├─ abs (convex; positive)
│     │  └─ …
│     └─ Convex.NegateAtom (constant; negative)
│        └─ …
⋮

println(
"standard deviation = ",
round(sqrt(wval' * Sigma_nom * wval), sigdigits = 2),
);
println(
"worst-case standard deviation = ",
round(sqrt(evaluate(risk)), sigdigits = 2),
);
println("worst-case Delta = ");
println(round.(evaluate(Delta), sigdigits = 2));
standard deviation = 0.52
worst-case standard deviation = 0.87
worst-case Delta =
[3.2e-9 -0.2 -0.2 -0.085 -0.2; -0.2 2.5e-8 0.16 -0.016 0.14; -0.2 0.16 1.1e-8 -0.13 0.1; -0.085 -0.016 -0.13 -1.5e-10 -0.096; -0.2 0.14 0.1 -0.096 -2.1e-8]