Skip to content

Commit 79e223f

Browse files
committed
move Ipopt to extensions
1 parent 5b27e25 commit 79e223f

File tree

5 files changed

+84
-68
lines changed

5 files changed

+84
-68
lines changed

Project.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ authors = ["Mehmet Hakan Satman <mhsatman@gmail.com>"]
55

66
[deps]
77
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
8-
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
98
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
109
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1110
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1211

12+
[weakdeps]
13+
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
14+
15+
[extensions]
16+
OperationsResearchModelsIpoptExt = "Ipopt"
17+
1318
[compat]
1419
HiGHS = "1.4"
15-
Ipopt = "1.7"
1620
JuMP = "1"
1721
LinearAlgebra = "1"
1822
Statistics = "1"
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
module OperationsResearchModelsIpoptExt
2+
3+
using OperationsResearchModels
4+
using Ipopt
5+
using JuMP
6+
using LinearAlgebra
7+
using Statistics
8+
9+
10+
import OperationsResearchModels: solve
11+
import OperationsResearchModels.Portfolio: PortfolioProblem, PortfolioResult
12+
13+
"""
14+
solve(problem)
15+
16+
# Description
17+
18+
Solves a portfolio optimization problem given by an object of in type `PortfolioProblem`.
19+
The optimization problem is formulated as a quadratic programming problem where the objective
20+
is to minimize the portfolio variance (risk) subject to constraints on the expected return and the weights.
21+
22+
Mathematically, the problem can be stated as:
23+
24+
Minimize: w' * Covmat * w
25+
Subject to:
26+
- sum(w) == 1 (the weights must sum to 1)
27+
- sum(w[i] * means[i] for i in 1:m) >= thresholdreturn
28+
- 0 <= w[i] <= 1 for all i (weights must be between 0 and 1)
29+
30+
Where:
31+
- w is the vector of asset weights
32+
- Covmat is the covariance matrix of asset returns
33+
- means is the vector of expected returns for each asset
34+
- thresholdreturn is the minimum expected return required for the portfolio
35+
36+
# Note
37+
38+
Ipopt is used to solve the quadratic programming problem. Make sure to have
39+
Ipopt installed and properly configured in your Julia environment to use this function.
40+
41+
42+
# Arguments
43+
44+
- `problem::PortfolioProblem`: The problem in type of PortfolioProblem
45+
46+
# Returns
47+
48+
- `PortfolioResult`: The result of the portfolio optimization problem, containing the optimal weights, expected return, and the JuMP model used to solve the problem.
49+
50+
"""
51+
function solve(p::PortfolioProblem)::PortfolioResult
52+
model = Model(Ipopt.Optimizer)
53+
54+
MOI.set(model, MOI.Silent(), true)
55+
56+
means = mean(p.returns, dims = 1)
57+
covmat = cov(p.returns)
58+
59+
_, m = size(p.returns)
60+
61+
@variable(model, 0 <= w[1:m] <= 1)
62+
@constraint(model, sum(w) == 1)
63+
@constraint(model, sum(w[i] * means[i] for i in 1:m) >= p.thresholdreturn)
64+
@objective(model, Min, w' * covmat * w)
65+
66+
optimize!(model)
67+
68+
weights = value.(w)
69+
expectedreturn = sum(weights[i] * means[i] for i in 1:m)
70+
71+
return PortfolioResult(weights, expectedreturn, model)
72+
end
73+
74+
end

src/portfolio.jl

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module Portfolio
22

3-
using JuMP, Ipopt, Statistics, LinearAlgebra
3+
using JuMP, Statistics, LinearAlgebra
44

55
import ..OperationsResearchModels: solve
66

@@ -50,69 +50,4 @@ end
5050

5151

5252

53-
"""
54-
solve(problem)
55-
56-
# Description
57-
58-
Solves a portfolio optimization problem given by an object of in type `PortfolioProblem`.
59-
The optimization problem is formulated as a quadratic programming problem where the objective
60-
is to minimize the portfolio variance (risk) subject to constraints on the expected return and the weights.
61-
62-
Mathematically, the problem can be stated as:
63-
64-
Minimize: w' * Σ * w
65-
Subject to:
66-
- sum(w) == 1 (the weights must sum to 1)
67-
- sum(w[i] * μ[i] for i in 1:m) >= thresholdreturn
68-
- 0 <= w[i] <= 1 for all i (weights must be between 0 and 1)
69-
70-
Where:
71-
- w is the vector of asset weights
72-
- Σ is the covariance matrix of asset returns
73-
- μ is the vector of expected returns for each asset
74-
- thresholdreturn is the minimum expected return required for the portfolio
75-
76-
# Arguments
77-
78-
- `problem::PortfolioProblem`: The problem in type of PortfolioProblem
79-
80-
# Returns
81-
82-
- `PortfolioResult`: The result of the portfolio optimization problem, containing the optimal weights, expected return, and the JuMP model used to solve the problem.
83-
84-
"""
85-
function solve(p::PortfolioProblem)::PortfolioResult
86-
87-
model = Model(Ipopt.Optimizer)
88-
89-
MOI.set(model, MOI.Silent(), true)
90-
91-
means = mean(p.returns, dims = 1)
92-
93-
covmat = cov(p.returns)
94-
95-
_, m = size(p.returns)
96-
97-
@variable(model, 0 <= w[1:m] <= 1)
98-
99-
@constraint(model, sum(w) == 1)
100-
101-
@constraint(model, sum(w[i] * means[i] for i in 1:m) >= p.thresholdreturn)
102-
103-
@objective(model, Min, w' * covmat * w)
104-
105-
optimize!(model)
106-
107-
weights = value.(w)
108-
109-
expectedreturn = sum(weights[i] * means[i] for i in 1:m)
110-
111-
return PortfolioResult(weights, expectedreturn, model)
112-
113-
end
114-
115-
116-
117-
11853
end # end of module

test/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[deps]
2+
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
23
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

test/testportfolio.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using Ipopt
2+
13
@testset "Portfolio Optimization" begin
24
@testset "Markowitz Portfolio Optimization - Example 1" begin
35
eps = 1e-5

0 commit comments

Comments
 (0)