EfficientFrontier

Documentation for EfficientFrontier.

EfficientFrontier.EventType
    struct Event{T<:AbstractFloat}

Events that assets go IN/OUT(DN or UP), or inequalities go binded (EO, as equality) or not (OE, original ineq), with fields:

        From::Status
        To::Status
        id::Int     #asset ID
        L::T        #L
EfficientFrontier.ProblemType
    Problem(E, V; u, d, G, g, A, b, equilibrate)
    Problem(E, V, u; equilibrate)
    Problem(E, V, u, d; equilibrate)
    Problem(E, V, u, d, G, g; equilibrate)
    Problem(E, V, u, d, G, g, A, b; equilibrate)

Setup a Portfolio Selection model: for mean vector E and variance matrix V

\[ min (1/2)z′Vz s.t. z′E = μ Az = b ∈ R^{M} Gz ≤ g ∈ R^{J} d ≤ z ≤ u ∈ R^{N}\]

Default values: u = +∞, d = 0, G = [], g = [], A = ones(1,N), b = [1], and equilibrate = false

Example

    using EfficientFrontier
    V = [1/100 1/80 1/100
        1/80 1/16 1/40
        1/100 1/40 1/25]    #variance matrix
    E = [109 / 100; 23 / 20; 119 / 100] #mean vector
    P = Problem(E, V)   #Default models, non-shortsale
    aCL = EfficientFrontier.ECL(P)  #compute all Critical Lines
    aEF = eFrontier(aCL, P)     #compute the Efficient Frontier
    mu = (aEF.mu[1]+aEF.mu[end])/2  #mu at the middle of Efficient Frontier
    z = ePortfolio(mu, aEF)     #weight of the efficient portfolio given mu

See Documentation for EfficientFrontier.jl

See also EfficientFrontier.ECL

EfficientFrontier.SettingsType
    Settings(P::Problem)        The default Settings to given Problem
    Settings(; kwargs...)       The default Settings is set by Float64 type
    Settings{T<:AbstractFloat}(; kwargs...)

kwargs are from the fields of Settings{T<:AbstractFloat} for Float64 and BigFloat

        tol::T         #general scalar
        tolNorm::T     #for norms
        tolS::T        #for s from Clarabel, or tol for Simplex
        tolL::T        #for L
        tolG::T        #for Greeks (beta and gamma)
        muShft::T      #shift the max mu to (1-muShft)*mu
        rule::Symbol    #rule for Simplex {:Dantzig, :maxImprovement}
EfficientFrontier.StatusType
    @enum Status

Status: assets go IN/OUT(DN or UP), or inequalities go binded (EO, as equality) or not (OE, original ineq), with fields:

        IN  #within the lower and upper bound
        DN  #down, lower bound
        UP  #upper bound
        OE  #original <= not binded
        EO  #edge, <= as =
EfficientFrontier.sCLType
    sCL(P::Problem)         define an empty Vector of struct sCL for Problem P

    struct sCL{T<:AbstractFloat}

Critical Line segment, with fields: default T = Float64

        S::Vector{Status}       # (N+J)x1
        K::Integer              #number of IN assets
        L1::T                   #higher lambda
        I1::Vector{Event{T}}    #go in/out events at L1
        L0::T                   #lower lambda
        I0::Vector{Event{T}}    #go in/out events at L0
        alpha::Vector{T}        # K x 1
        beta::Vector{T}         # K x 1
EfficientFrontier.sEFType
    struct sEF

Efficient Frontier, with fields:

        Ap::Matrix{Float64}     # v=a₂μ²+a₁μ+a₀, each row [a₂ a₁ a₀]
        mu::Vector{Float64}     #higher mean
        sgm::Vector{Float64}    #higher sigma
        Z::Matrix{Float64}      #weights, each corner portfolio in one row
        ic::Vector{Int64}       #id of related critical line
EfficientFrontier.ECL!Method
   ECL!(aCL::Vector{sCL{T}}, PS::Problem{T}; numSettings = Settings(PS), incL=false)  where T

compute all the Critical Line Segments as L decreasing to 0 (increasing to +Inf if incL=true), given the first one in aCL[end]. Return value: true if done

EfficientFrontier.ECLMethod
    aCL = ECL(PS::Problem; numSettings = Settings(PS), init::Function=SimplexCL!)

compute all the Critical Line Segments. Init the CL by Simplex Method (combinatorial search init=cbCL!)

the return aCL has the follwing structure

    struct sCL{T<:AbstractFloat}    #critical line segment
        S::Vector{Status}       # (N+J)x1
        K::Integer              #number of IN assets
        L1::T                   #higher lambda
        I1::Vector{Event{T}}    #go in/out events at L1
        L0::T                   #lower lambda
        I0::Vector{Event{T}}    #go in/out events at L0
        alpha::Vector{T}        # K x 1
        beta::Vector{T}         # K x 1
    end

See https://github.com/PharosAbad/EfficientFrontier.jl/wiki

See also Problem, Settings

EfficientFrontier.cbCL!Method
    cbCL!(aCL::Vector{sCL{T}}, PS::Problem{T}; nS=Settings(PS), oneCL=true, K=PS.M+PS.J+1) where T

compute one or all (oneCL=false, K=PS.M) the Critical Line Segments by enumerating (combinations of Status). Save the CL(s) to aCL if done

EfficientFrontier.computeCL!Method
    computeCL!(aCL::Vector{sCL{T}}, S::Vector{Status}, PS::Problem{T}, nS::Settings{T}) where T

compute the Critical Line Segment for S::Vector{Status}, save to aCL[end]. Return value: true if done.

EfficientFrontier.eFrontierMethod
    aEF = eFrontier(aCL::Vector{sCL{T}}, PS::Problem{T}; tolNorm = 2^-26) where T

compute the Full Efficient Frontier by connecting Critical Line Segments

the return aEF has the follwing structure

    struct sEF    #Efficient Frontier       Float64 is OK
        Ap::Matrix{Float64}     # v=a₂μ²+a₁μ+a₀, each row [a₂ a₁ a₀]
        mu::Vector{Float64}     #higher mean
        sgm::Vector{Float64}    #higher sigma
        Z::Matrix{Float64}      #weights, each corner portfolio in one row
        ic::Vector{Int64}       #id of related critical line
    end
EfficientFrontier.ePortfolioMethod
    z = ePortfolio(mu, aEF::sEF)

compute the efficient portfolio given mu, returns portfolio weights z (Nx1 vector of NaN if mu is out of range)