Skip to content

Commit 8acd04f

Browse files
committed
remove Ipopt from weak dependencies and use HiGHS instead, in Portfolio Problems
1 parent 94bc64c commit 8acd04f

9 files changed

Lines changed: 73 additions & 99 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### 0.2.12 (Upcoming Release)
22

3+
- Remove Ipopt from weak dependencies and use HiGHS instead in Portfolio problems.
34

45
### 0.2.11
56

Project.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
99
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1010
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1111

12-
[weakdeps]
13-
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
14-
15-
[extensions]
16-
OperationsResearchModelsIpoptExt = "Ipopt"
1712

1813
[compat]
1914
HiGHS = "1.4"

docs/Project.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3-
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"

docs/make.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Documenter, OperationsResearchModels
2-
using Ipopt
32

43
makedocs(
54
format = Documenter.HTML(

ext/OperationsResearchModelsIpoptExt.jl

Lines changed: 0 additions & 84 deletions
This file was deleted.

src/knapsack.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@ Defines the knapsack problem.
4545
# Output
4646
- `KnapsackResult`: The custom data type that holds selected items, model, and objective value.
4747
"""
48-
struct KnapsackProblem
49-
values::Vector{Float64}
50-
weights::Vector{Float64}
51-
capacity::Float64
48+
struct KnapsackProblem{T <: Real}
49+
values::Vector{T}
50+
weights::Vector{T}
51+
capacity::T
52+
5253
end
5354

5455

src/portfolio.jl

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module Portfolio
22

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

55
import ..OperationsResearchModels: solve
66

@@ -50,4 +50,70 @@ 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' * Covmat * w
65+
Subject to:
66+
- sum(w) == 1 (the weights must sum to 1)
67+
- sum(w[i] * means[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+
- Covmat is the covariance matrix of asset returns
73+
- means is the vector of expected returns for each asset
74+
- thresholdreturn is the minimum expected return required for the portfolio
75+
76+
77+
# Arguments
78+
79+
- `problem::PortfolioProblem`: The problem in type of PortfolioProblem
80+
81+
# Returns
82+
83+
- `PortfolioResult`: The result of the portfolio optimization problem, containing the optimal weights, expected return, and the JuMP model used to solve the problem.
84+
85+
# Example
86+
```julia
87+
using OperationsResearchModels
88+
89+
problem = PortfolioProblem(rand(100, 5), 0.01)
90+
result = solve(problem)
91+
println("Optimal Weights: ", result.weights)
92+
println("Expected Return: ", result.expectedreturn)
93+
```
94+
"""
95+
function solve(p::PortfolioProblem)::PortfolioResult
96+
model = Model(HiGHS.Optimizer)
97+
98+
MOI.set(model, MOI.Silent(), true)
99+
100+
means = mean(p.returns, dims = 1)
101+
covmat = cov(p.returns)
102+
103+
_, m = size(p.returns)
104+
105+
@variable(model, 0 <= w[1:m] <= 1)
106+
@constraint(model, sum(w) == 1)
107+
@constraint(model, sum(w[i] * means[i] for i in 1:m) >= p.thresholdreturn)
108+
@objective(model, Min, w' * covmat * w)
109+
110+
optimize!(model)
111+
112+
weights = value.(w)
113+
expectedreturn = sum(weights[i] * means[i] for i in 1:m)
114+
115+
return PortfolioResult(weights, expectedreturn, model)
116+
end
117+
118+
53119
end # end of module

test/Project.toml

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

test/testportfolio.jl

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

0 commit comments

Comments
 (0)