Skip to content
13

Kurtosis

PortfolioOptimisers.Kurtosis Type
julia
struct Kurtosis{__T_settings, __T_w, __T_mu, __T_kt, __T_N, __T_alg1, __T_alg2} <: RiskMeasure

Represents the square root kurtosis risk measure in PortfolioOptimisers.jl.

Computes portfolio risk as the square root of the fourth central moment (kurtosis) of the return distribution, optionally using custom weights, expected returns, and a kurtosis (fourth moment) matrix. This risk measure can be evaluated using either the full or semi (downside) deviations, depending on the algorithm provided.

Mathematical definition

Let x=Xw be the T×1 vector of portfolio returns, and let μ be the chosen centre (mean, weighted mean, or user-supplied value). Define the centred deviations:

δt=xtμ.

The square-root kurtosis (full moment) is:

Kurt(w)=1Tt=1Tδt4.

Equivalently, using the N2×N2 cokurtosis matrix K^ and the Kronecker product :

Kurt(w)=(ww)K^(ww)4.

For the semi (downside) variant, only non-positive deviations contribute:

SKurt(w)=1Tt=1Tmin(δt,0)4.

Where:

  • w: N×1 asset weights vector.

  • X: T×N asset returns matrix.

  • K^: N2×N2 cokurtosis matrix.

  • : Kronecker product.

Fields

  • settings: Risk measure settings.

  • w: Optional portfolio weights.

  • mu: Optional mean for centering.

  • kt: Cokurtosis matrix features^2 × features^2.

  • N: Optional number of eigenvalues per asset for the approximate cokurtosis formulation.

  • alg1: First algorithm variant.

  • alg2: Second algorithm variant.

Constructors

julia
Kurtosis(;
    settings::RiskMeasureSettings = RiskMeasureSettings(),
    w::Option{<:ObsWeights} = nothing,
    mu::Option{<:Num_VecNum_VecScalar} = nothing,
    kt::Option{<:MatNum} = nothing,
    N::Option{<:Integer} = nothing,
    alg1::AbstractMomentAlgorithm = Full(),
    alg2::VarianceFormulation = SOCRiskExpr(),
) -> Kurtosis

Keywords correspond to the struct's fields.

Validation

  • If mu is not nothing:

    • ::Number: isfinite(mu).

    • ::VecNum: !isempty(mu) and all(isfinite, mu).

  • If w is not nothing, !isempty(w).

  • If kt is not nothing:

    • !isempty(kt) and size(kt, 1) == size(kt, 2).

    • If mu is not nothing:

      • ::VecNum: length(mu)^2 == size(kt, 1).

      • ::VecScalar: length(mu.v)^2 == size(kt, 1).

  • If N is not nothing: must be positive.

JuMP Formulations

Exact

This formulation is used when N is nothing.

Approximate

This formulation is used when N is an integer, the larger the value of N, the more accurate and expensive it becomes.

Examples

julia
julia> Kurtosis()
Kurtosis
  settings ┼ RiskMeasureSettings
           │   scale ┼ Float64: 1.0
           │      ub ┼ nothing
           │     rke ┴ Bool: true
         w ┼ nothing
        mu ┼ nothing
        kt ┼ nothing
         N ┼ nothing
      alg1 ┼ Full()
      alg2 ┴ SOCRiskExpr()

Related

source
PortfolioOptimisers.factory Method
julia
factory(
    r::Kurtosis,
    pr::HighOrderPrior,
    args...;
    kwargs...
) -> Kurtosis{RiskMeasureSettings{__T_scale, __T_ub, __T_rke}, _A, _B, _C, _D, <:AbstractMomentAlgorithm, <:SecondMomentFormulation} where {__T_scale, __T_ub, __T_rke, _A, _B, _C, _D}

Create an instance of Kurtosis by selecting the cokurtosis matrix, expected returns, and weights from the risk-measure instance or falling back to a HighOrderPrior result.

Related

source
PortfolioOptimisers.factory Method
julia
factory(
    r::Kurtosis,
    pr::LowOrderPrior,
    args...;
    kwargs...
) -> Kurtosis{RiskMeasureSettings{__T_scale, __T_ub, __T_rke}, _A, _B, _C, _D, <:AbstractMomentAlgorithm, <:SecondMomentFormulation} where {__T_scale, __T_ub, __T_rke, _A, _B, _C, _D}

Create an instance of Kurtosis from a LowOrderPrior result (cokurtosis matrix is not used).

Related

source
PortfolioOptimisers.calc_moment_target Method
julia
calc_moment_target(::Kurtosis{<:Any, Nothing, Nothing, ...}, ::Any, x::VecNum)
calc_moment_target(r::Kurtosis{<:Any, <:ObsWeights, Nothing, ...}, ::Any, x::VecNum)
calc_moment_target(r::Kurtosis{<:Any, <:Any, <:VecNum, ...}, w::VecNum, ::Any)
calc_moment_target(r::Kurtosis{<:Any, <:Any, <:VecScalar, ...}, w::VecNum, ::Any)
calc_moment_target(r::Kurtosis{<:Any, <:Any, <:Number, ...}, ::Any, ::Any)

Compute the target value for kurtosis moment calculations.

Dispatches on the type of r.w and r.mu to select the appropriate centring target. Follows the same rules as calc_moment_target.

Related

source
PortfolioOptimisers.calc_deviations_vec Function
julia
calc_deviations_vec(
    r::Kurtosis,
    w::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    X::AbstractMatrix{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}}
) -> Any
calc_deviations_vec(
    r::Kurtosis,
    w::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    X::AbstractMatrix{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    fees::Union{Nothing, Fees}
) -> Any

Compute the vector of deviations from the target value for Kurtosis risk measures.

See calc_deviations_vec for details.

Related

source
PortfolioOptimisers.calc_deviations_vec Method
julia
calc_deviations_vec(
    r::Kurtosis,
    x::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}}
) -> Any

Compute the vector of deviations from the target value for a precomputed returns series for Kurtosis.

Single-argument form used by the precomputed-returns functor r(x::VecNum) (ADR 0007).

Related

source
PortfolioOptimisers.port_opt_view Method
julia
port_opt_view(
    r::Kurtosis,
    i,
    args...
) -> Kurtosis{RiskMeasureSettings{__T_scale, __T_ub, __T_rke}, _A, _B, _C, _D, <:AbstractMomentAlgorithm, <:SecondMomentFormulation} where {__T_scale, __T_ub, __T_rke, _A, _B, _C, _D}

Return a view of Kurtosis r sliced to asset indices i.

Slices both the cokurtosis matrix kt and the expected returns mu for cluster-based optimisation.

Related

source
PortfolioOptimisers.supports_precomputed_returns Method
julia
supports_precomputed_returns(r::Kurtosis) -> Any

Return whether Kurtosis r supports precomputed-return evaluation.

Delegates to weight_independent_target on r.mu: true iff the target is Nothing, a Number, or a MedianCenteringFunction; false for per-asset targets.

Related

source