Moment Risk Measures: private API

PortfolioOptimisers.MomentMeasureAlgorithmType
abstract type MomentMeasureAlgorithm <: AbstractAlgorithm

Abstract supertype for all moment-based risk measure algorithms.

Defines the interface for algorithms that compute portfolio risk using statistical moments (e.g., mean, variance, skewness, kurtosis) of the return distribution. All concrete moment risk measure algorithms should subtype MomentMeasureAlgorithm to ensure consistency and composability within the risk measure framework.

Related

source
PortfolioOptimisers.LowOrderMomentMeasureAlgorithmType
abstract type LowOrderMomentMeasureAlgorithm <: MomentMeasureAlgorithm

Abstract supertype for all low-order moment-based risk measure algorithms.

Defines the interface for algorithms that compute portfolio risk using low-order statistical moments (e.g., mean, variance, mean absolute deviation) of the return distribution. All concrete low-order moment risk measure algorithms should subtype LowOrderMomentMeasureAlgorithm to ensure consistency and composability within the risk measure framework.

Related

source
PortfolioOptimisers.UnstandardisedLowOrderMomentMeasureAlgorithmType
abstract type UnstandardisedLowOrderMomentMeasureAlgorithm <: LowOrderMomentMeasureAlgorithm

Abstract supertype for low-order moment risk measure algorithms that are not standardised by the variance.

Defines the interface for algorithms that compute portfolio risk using low-order statistical moments without normalising by the variance. All concrete unstandardised low-order moment risk measure algorithms should subtype UnstandardisedLowOrderMomentMeasureAlgorithm to ensure consistency and composability within the risk measure framework.

Related

source
PortfolioOptimisers.HighOrderMomentMeasureAlgorithmType
abstract type HighOrderMomentMeasureAlgorithm <: MomentMeasureAlgorithm

Abstract supertype for all high-order moment-based risk measure algorithms.

Defines the interface for algorithms that compute portfolio risk using high-order statistical moments (e.g., skewness, kurtosis) of the return distribution. All concrete high-order moment risk measure algorithms should subtype HighOrderMomentMeasureAlgorithm to ensure consistency and composability within the risk measure framework.

Related

source
PortfolioOptimisers.UnstandardisedHighOrderMomentMeasureAlgorithmType
abstract type UnstandardisedHighOrderMomentMeasureAlgorithm <: HighOrderMomentMeasureAlgorithm

Abstract supertype for high-order moment risk measure algorithms that are not standardised by the variance.

Defines the interface for algorithms that compute portfolio risk using high-order statistical moments (such as skewness, kurtosis) without normalising by the variance. All concrete unstandardised high-order moment risk measure algorithms should subtype UnstandardisedHighOrderMomentMeasureAlgorithm to ensure consistency and composability within the risk measure framework.

Related

source
PortfolioOptimisers.calc_moment_targetMethod
calc_moment_target(::LoHiOrderMoment{<:Any, Nothing, Nothing, <:Any},
                   ::Any, x::VecNum)

Compute the target value for moment calculations when neither a target value (mu) nor observation weights are provided in the risk measure.

Arguments

  • r: A LowOrderMoment or HighOrderMoment risk measure with both w and mu fields set to nothing.
  • _: Unused argument (typically asset weights, ignored in this method).
  • x: Returns vector.

Returns

  • tgt::eltype(x): The mean of the returns vector.

Related

source
PortfolioOptimisers.calc_moment_targetMethod
calc_moment_target(r::LoHiOrderMoment{<:Any, <:StatsBase.AbstractWeights, Nothing, <:Any},
                   ::Any, x::VecNum)

Compute the target value for moment calculations when the risk measure provides an observation weights vector but no explicit target value (mu).

Arguments

  • r: A LowOrderMoment or HighOrderMoment risk measure with w set to an observation weights vector and mu set to nothing.
  • _: Unused argument (typically asset weights, ignored in this method).
  • x: Returns vector.

Returns

  • tgt::eltype(x): The weighted mean of the returns vector, using the observation weights from r.w.

Related

source
PortfolioOptimisers.calc_moment_targetMethod
calc_moment_target(r::LoHiOrderMoment{<:Any, <:Any, <:VecNum, <:Any},
                   w::VecNum, ::Any)

Compute the target value for moment calculations when the risk measure provides an explicit expected returns vector (mu).

Arguments

  • r: A LowOrderMoment or HighOrderMoment risk measure with mu set to an expected returns vector.
  • w: Asset weights vector.
  • ::Any: Unused argument (typically the returns vector, ignored in this method).

Returns

  • tgt::eltype(w): The dot product of the asset weights and the expected returns vector.

Related

source
PortfolioOptimisers.calc_moment_targetMethod
calc_moment_target(r::LoHiOrderMoment{<:Any, <:Any, <:VecScalar, <:Any},
                   w::VecNum, ::Any)

Compute the target value for moment calculations when the risk measure provides a VecScalar as the expected returns (mu).

Arguments

  • r: A LowOrderMoment or HighOrderMoment risk measure with mu set to a VecScalar (an object with fields v for the expected returns vector and s for a scalar offset).
  • w: Asset weights vector.
  • ::Any: Unused argument (typically the returns vector, ignored in this method).

Returns

  • tgt::promote_type(eltype(w), eltype(r.mu.v), typeof(r.mu.s)): The sum of the dot product of the asset weights and the expected returns vector plus the scalar offset, LinearAlgebra.dot(w, r.mu.v) + r.mu.s.

Related

source
PortfolioOptimisers.calc_moment_targetMethod
calc_moment_target(r::LoHiOrderMoment{<:Any, <:Any, <:Number, <:Any},
                   ::Any, ::Any)

Compute the target value for moment calculations when the risk measure provides a scalar value for the expected returns (mu).

Arguments

  • r: A LowOrderMoment or HighOrderMoment risk measure with mu set to a scalar value.
  • ::Any: Unused argument (typically asset weights, ignored in this method).
  • ::Any: Unused argument (typically the returns vector, ignored in this method).

Returns

  • tgt::Number: The scalar value of r.mu.

Related

source
PortfolioOptimisers.calc_deviations_vecFunction
calc_deviations_vec(r::LoHiOrderMoment, w::VecNum,
                X::MatNum; fees::Option{<:Fees} = nothing)

Compute the vector of deviations from the target value for moment-based risk measures.

Arguments

  • r: A LowOrderMoment or HighOrderMoment risk measure specifying the moment calculation algorithm and target.
  • w: Asset weights vector.
  • X: Return matrix.
  • fees: Optional fees object to adjust net returns.

Returns

  • val::AbstractVector: The vector of deviations between net portfolio returns and the computed moment target.

Details

  • Computes net portfolio returns using the provided weights, return matrix, and optional fees.
  • Computes the target value for the moment calculation using calc_moment_target.
  • Returns the element-wise difference between net returns and the target value.

Related

source
PortfolioOptimisers.calc_deviations_vecMethod
calc_deviations_vec(
    r::Union{HighOrderMoment{T1, T2, T3, T4}, LowOrderMoment{T1, T2, T3, T4}} where {T1, T2, T3, T4},
    x::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}
) -> Any

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

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

Related

source
PortfolioOptimisers.resolve_deferred_quantitiesMethod
resolve_deferred_quantities(x, ) -> StandardDeviation
resolve_deferred_quantities(x, , ) -> StandardDeviation

Resolve every Deferred Quantity held by x against prior result pr, returning a struct of the same type whose deferred slots hold plain values.

This resolves the deferred state and nothing else. A slot left unstated stays nothing, so whichever fallback the consumer already applies — sel on the factory path, chol_sigma_selector and its siblings on the JuMP path — keeps working unchanged. The two paths are separate: a JuMP model builder reads the risk measure's slots directly and never calls factory, so both entry points resolve.

Given a prior result the rule has two halves. Container recursion is derived from deferred_slots, so a type that only holds children needs no method at all. A type that resolves a quantity of its own defines a method, which overrides the derived one. Writing that half per type — rather than per field — is what lets slots that travel together be resolved together: a deferred sigma supplies chol from the same fit, so the pair is never mixed across two sources.

slv is the effective solver, and it is what a Calibration Rule in the same struct reads. It carries the value the optimisation settled on, so a rule resolves against one solver on both routes. On the factory route the @cprop selection has already put that solver on the struct, so the argument stays at its default. On the JuMP route no selection runs, so set_risk_constraints! reads the solver off the estimator and threads it here. A type that carries a solver of its own settles it locally as sel(x.slv, slv), beside the observation weights it already settles that way, and a type that carries none gives its rules none on either route.

Algorithm

  1. Return x unchanged. This method is the arm for a second argument that is not a prior result: with no prior in hand nothing can be fitted, so the deferred state travels on.

A more specific method dominates this one on a prior result: the one that deferred_slots derives for a container, and the hand-written one of a type that resolves a quantity of its own.

Related

source
resolve_deferred_quantities(x, pr::AbstractPriorResult, slv = nothing)

Resolve the children that deferred_slots declared and the slots that calibration_slots declared, and return x itself when none of them changed.

This is the derived half of the resolution rule. A container declares its children once and both entry points follow: factory reaches them through @fprop, and the JuMP builders reach them through this method. Neither needs a forwarding method per container.

A type that resolves a quantity of its own overrides this with its own method, which is more specific. So the derivation carries container recursion alone, and never guesses how a matrix, a tensor or the centre a moment was taken about comes out of a fit.

Both channels end in one rebuild: a measure that carries both kinds of slot must not be rebuilt twice. resolve_calibration_slots states the calibration half and returns its resolved slots rather than a rebuilt object, and the two answers merge here. The deferred half merges last, so it wins a key both channels declare. A container names one child in both, and the child the recursion resolved is the one to keep.

slv is the effective solver, and the recursion threads it to every child. A container states no solver of its own, so it changes none: each child settles the one it was handed against the one it carries.

Algorithm

  1. Read the slots x declares with deferred_slots, giving slots.
  2. Read the resolved calibration slots with resolve_calibration_slots, giving calibrated.
  3. Return x unchanged when both are empty. A type with neither kind of slot needs no method of its own.
  4. Resolve every entry of slots with resolve_deferred_child, threading pr and slv to each, giving resolved.
  5. Refuse a slot the recursion left unresolved with assert_declared_slot_resolver.
  6. Hand merge(calibrated, resolved) to rebuild_with_slots, which returns x itself when no entry moved and a rebuilt copy when one did.

Returns

  • x itself when no slot moved, and a rebuilt copy of x when one did.

Related

source
resolve_deferred_quantities(
    r::LowOrderMoment,
    pr::AbstractPriorResult
) -> LowOrderMoment
resolve_deferred_quantities(
    r::LowOrderMoment,
    pr::AbstractPriorResult,
    
) -> LowOrderMoment

Resolve a Deferred Quantity in LowOrderMoment's mu slot against prior result pr. The measure carries one prior-derived slot, so the slot itself admits the estimator and there is no fan-out to make.

Related

source
PortfolioOptimisers.resolve_deferred_quantitiesMethod
resolve_deferred_quantities(x, ) -> StandardDeviation
resolve_deferred_quantities(x, , ) -> StandardDeviation

Resolve every Deferred Quantity held by x against prior result pr, returning a struct of the same type whose deferred slots hold plain values.

This resolves the deferred state and nothing else. A slot left unstated stays nothing, so whichever fallback the consumer already applies — sel on the factory path, chol_sigma_selector and its siblings on the JuMP path — keeps working unchanged. The two paths are separate: a JuMP model builder reads the risk measure's slots directly and never calls factory, so both entry points resolve.

Given a prior result the rule has two halves. Container recursion is derived from deferred_slots, so a type that only holds children needs no method at all. A type that resolves a quantity of its own defines a method, which overrides the derived one. Writing that half per type — rather than per field — is what lets slots that travel together be resolved together: a deferred sigma supplies chol from the same fit, so the pair is never mixed across two sources.

slv is the effective solver, and it is what a Calibration Rule in the same struct reads. It carries the value the optimisation settled on, so a rule resolves against one solver on both routes. On the factory route the @cprop selection has already put that solver on the struct, so the argument stays at its default. On the JuMP route no selection runs, so set_risk_constraints! reads the solver off the estimator and threads it here. A type that carries a solver of its own settles it locally as sel(x.slv, slv), beside the observation weights it already settles that way, and a type that carries none gives its rules none on either route.

Algorithm

  1. Return x unchanged. This method is the arm for a second argument that is not a prior result: with no prior in hand nothing can be fitted, so the deferred state travels on.

A more specific method dominates this one on a prior result: the one that deferred_slots derives for a container, and the hand-written one of a type that resolves a quantity of its own.

Related

source
resolve_deferred_quantities(x, pr::AbstractPriorResult, slv = nothing)

Resolve the children that deferred_slots declared and the slots that calibration_slots declared, and return x itself when none of them changed.

This is the derived half of the resolution rule. A container declares its children once and both entry points follow: factory reaches them through @fprop, and the JuMP builders reach them through this method. Neither needs a forwarding method per container.

A type that resolves a quantity of its own overrides this with its own method, which is more specific. So the derivation carries container recursion alone, and never guesses how a matrix, a tensor or the centre a moment was taken about comes out of a fit.

Both channels end in one rebuild: a measure that carries both kinds of slot must not be rebuilt twice. resolve_calibration_slots states the calibration half and returns its resolved slots rather than a rebuilt object, and the two answers merge here. The deferred half merges last, so it wins a key both channels declare. A container names one child in both, and the child the recursion resolved is the one to keep.

slv is the effective solver, and the recursion threads it to every child. A container states no solver of its own, so it changes none: each child settles the one it was handed against the one it carries.

Algorithm

  1. Read the slots x declares with deferred_slots, giving slots.
  2. Read the resolved calibration slots with resolve_calibration_slots, giving calibrated.
  3. Return x unchanged when both are empty. A type with neither kind of slot needs no method of its own.
  4. Resolve every entry of slots with resolve_deferred_child, threading pr and slv to each, giving resolved.
  5. Refuse a slot the recursion left unresolved with assert_declared_slot_resolver.
  6. Hand merge(calibrated, resolved) to rebuild_with_slots, which returns x itself when no entry moved and a rebuilt copy when one did.

Returns

  • x itself when no slot moved, and a rebuilt copy of x when one did.

Related

source
resolve_deferred_quantities(
    r::HighOrderMoment,
    pr::AbstractPriorResult
) -> HighOrderMoment
resolve_deferred_quantities(
    r::HighOrderMoment,
    pr::AbstractPriorResult,
    
) -> HighOrderMoment

Resolve a Deferred Quantity in HighOrderMoment's mu slot against prior result pr. The measure carries one prior-derived slot, so the slot itself admits the estimator and there is no fan-out to make.

Related

source
PortfolioOptimisers.moment_riskFunction
moment_risk(r::LoHiOrderMoment, val::VecNum)
moment_risk(r::Kurtosis, val::VecNum)
moment_risk(r::Skewness, val::VecNum)
moment_risk(r::MedianAbsoluteDeviation, val::VecNum)
moment_risk(r::ThirdCentralMoment, val::VecNum)

Shared post-deviation kernel for the moment-family risk measures. Given the vector of deviations val (net portfolio returns minus the measure's target, from calc_deviations_vec), compute the measure's scalar value. Dispatch selects the per-algorithm reduction (lower/full, the power, the standardisation, the formulation).

Both functor arities funnel through this kernel: r(w, X, fees) calls moment_risk(r, calc_deviations_vec(r, w, X, fees)), and the single-argument precomputed-returns form r(x::VecNum) calls moment_risk(r, calc_deviations_vec(r, x)), so the two share one definition of the math.

Related

source