JuMP Non-Linear Optimization

You can actually solve this using the new multi-objective support in JuMP: Multi-objective knapsack · JuMP

using JuMP
import DataFrames
import Gurobi
import MultiObjectiveAlgorithms as MOA
import Plots
import Statistics
df = DataFrames.DataFrame(
    bond = [0.06276629, 0.03958098, 0.08456482,0.02759821,0.09584956,0.06363253,0.02874502,0.02707264,0.08776449,0.02950032],
    stock = [0.1759782,0.20386651,0.21993588,0.3090001,0.17365969,0.10465274,0.07888138,0.13220847,0.28409742,0.14343067],
)
R = Matrix(df)
μ = vec(Statistics.mean(R; dims = 1))
Q = Statistics.cov(R)
model = Model(() -> MOA.Optimizer(Gurobi.Optimizer))
set_optimizer_attribute(model, MOA.Algorithm(), MOA.EpsilonConstraint())
set_optimizer_attribute(model, MOA.EpsilonConstraintStep(), 0.0001)
set_silent(model)
@variable(model, 0 <= w[1:size(R, 2)] <= 1)
@constraint(model, sum(w) == 1)
@variable(model, 0 <= variance <= sum(Q))
@constraint(model, variance >= w' * Q * w)
@expression(model, mean_return, μ' * w)
@objective(model, Min, [variance, -mean_return])
optimize!(model)
solution_summary(model)
Plots.scatter(
    [value(variance; result = i) for i in 1:result_count(model)],
    [value(mean_return; result = i) for i in 1:result_count(model)];
    xlabel = "Variance",
    ylabel = "Return",
    label = "",
)

Because it’s new there are a couple of bugs with Ipopt that I need to fix, so you’ll need to use Gurobi for now.

1 Like