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::T, V; u, d, G, g, A, b, equilibrate) where T
    Problem(E::T, V, u; equilibrate) where T
    Problem(E::T, V, u, d; equilibrate) where T
    Problem(E::T, V, u, d, G, g; equilibrate) where T
    Problem(E::T, V, u, d, G, g, A, b; equilibrate) where T

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(aEF, mu)     #weight of the efficient portfolio given mu

See Documentation for EfficientFrontier.jl

See also EfficientFrontier.ECL

EfficientFrontier.SettingsType
    Settings(P::Problem; kwargs...)        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 identifying S
        tolL::T        #for L
        tolG::T        #for Greeks (beta and gamma)
        muShft::T      #shift the mu to (1 +/- muShft)*mu
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, settings=SettingsQP(PS), settingsLP=SettingsLP(PS))  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]. The settings is the LightenQP.Settings setting from LightenQP Return value: true if done

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

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 Documentation for EfficientFrontier.jl

See also Problem, Settings

EfficientFrontier.EVdataFunction
    EVdata(ds::Symbol, verbose=true)

extract some data sets

:Abad           Abad's equilibrum data
:Markowitz      Markowitz and Todd (2000), chapter 13, pp.337
:Ungil          from https://github.com/ungil/Markowitz.jl/blob/master/examples/frontier.jl
EfficientFrontier.SimplexCL!Method
    SimplexCL!(aCL::Vector{sCL{T}}, PS::Problem{T}; nS=Settings(PS), settings=SettingsQP(PS), settingsLP=SettingsLP(PS)) where T

compute the Critical Line Segments by Simplex method, for the highest expected return. Save the CL to aCL if done

settings        : for LightenQP solver, chance for a QP solver needed is <=0.1% (when the corner portfolio is degenarated, or infinite many solutions to SimplexLP encounted)
settingsLP      : `SimplexLP.Settings`, for SimplexLP solver, we always first try the SimplexLP, and a chance of >=99.9% we find the critical line

See also cbCL!, Problem, Settings, SettingsQP

EfficientFrontier.cbCL!Method
    cbCL!(aCL::Vector{sCL{T}}, PS::Problem{T}; nS=Settings(PS), oneCL=true, K=PS.M+PS.J+1, kwargs...) 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

See also SimplexCL!, Problem, Settings

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}; nS=Settings(PS)) where T

compute the Full Efficient Frontier by Status-Segment Method

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

See also EfficientFrontier.ECL, ePortfolio, Problem, Settings

EfficientFrontier.ePortfolioMethod
    z = ePortfolio(aEF::sEF, mu)
    z = ePortfolio(P::Problem, mu; nS=Settings(P))

ePortfolio(aEF::sEF, mu) compute the efficient portfolio given mu when Efficient Frontier is known, returns portfolio weights z (Nx1 vector of NaN if mu is out of range)

ePortfolio(P::Problem, mu; nS=Settings(P)) compute the efficient portfolio for P given mu, returns portfolio weights z (Nx1 vector of NaN if mu is out of range) If mu is a vector, z is a matrix, its row k is the portfolio weights for mu[k]. Here you can not set init::Function

See also EfficientFrontier.ECL, eFrontier, Problem, Settings

LightenQP.fPortfolioMethod
    x, status = fPortfolio(P::Problem; settings=SettingsQP, L=0)
    x, status = fPortfolio(P::Problem, mu; settings=SettingsQP, check=true)

compute frontier portfolio at given L or mu, using LightenQP's numerical solver fPortfolio

L=-Inf          :FP(L=-Inf), LMFP (Lowest Mean Frontier Portfolio)
L=+Inf          :FP(L=+Inf), HMFP (Highest Mean Frontier Portfolio) HVEP (Highest Variance Efficient Portfolio)
L=L0            :FP(L=L0), the frontier (minimum variance) portfolio at L=L0. L=0, LVEP (Lowest Variance Efficient Portfolio, also called GMVP, Global Minimum Variance Portfolio)
mu=-Inf         :FP(L=-Inf), LMFP (Lowest Mean Frontier Portfolio)
mu=+Inf         :FP(L=+Inf), HMFP (Highest Mean Frontier Portfolio) == HVEP (Highest Variance Efficient Portfolio)
mu=mu0          :FP(mu=mu0), the frontier (minimum variance) portfolio at mu=mu0

if check=false, we do not check if mu is feasible or not (between lowest and highest mean)

See also ePortfolio, Problem, SettingsQP, LightenQP.fPortfolio