Non-Optimisation Risk Measures: private API
PortfolioOptimisers.TCM_Sk — Type
const TCM_Sk{T1, T2} = Union{<:ThirdCentralMoment{<:Any, T1, T2}, <:Skewness{<:Any, <:Any, <:Any, T1, T2}}Parameterised union of ThirdCentralMoment and Skewness sharing the same observation-weight (T1) and target-mean (T2) type parameters.
Used for unified dispatch on moment-target calculation methods.
Related
PortfolioOptimisers.resolve_deferred_quantities — Method
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
- Return
xunchanged. 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
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
- Read the slots
xdeclares withdeferred_slots, givingslots. - Read the resolved calibration slots with
resolve_calibration_slots, givingcalibrated. - Return
xunchanged when both are empty. A type with neither kind of slot needs no method of its own. - Resolve every entry of
slotswithresolve_deferred_child, threadingprandslvto each, givingresolved. - Refuse a slot the recursion left unresolved with
assert_declared_slot_resolver. - Hand
merge(calibrated, resolved)torebuild_with_slots, which returnsxitself when no entry moved and a rebuilt copy when one did.
Returns
xitself when no slot moved, and a rebuilt copy ofxwhen one did.
Related
resolve_deferred_quantities(
r::ThirdCentralMoment,
pr::AbstractPriorResult
) -> ThirdCentralMoment
resolve_deferred_quantities(
r::ThirdCentralMoment,
pr::AbstractPriorResult,
) -> ThirdCentralMoment
Resolve a Deferred Quantity in ThirdCentralMoment'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
PortfolioOptimisers.calc_moment_target — Method
calc_moment_target(::TCM_Sk{Nothing, Nothing}, ::Any, x::VecNum)
calc_moment_target(r::TCM_Sk{<:StatsBase.AbstractWeights, Nothing}, ::Any, x::VecNum)
calc_moment_target(r::TCM_Sk{<:Any, <:VecNum}, w::VecNum, ::Any)
calc_moment_target(r::TCM_Sk{<:Any, <:VecScalar}, w::VecNum, ::Any)
calc_moment_target(r::TCM_Sk{<:Any, <:Number}, ::Any, ::Any)Compute the centering target for ThirdCentralMoment and Skewness risk measures.
Dispatches on the observation-weight type T1 and mean type T2 of TCM_Sk:
- No weights, no mu: arithmetic mean of
x. AbstractWeights, no mu: weighted mean ofx.VecNummu: dot product $\boldsymbol{w}^\intercal \boldsymbol{\mu}$.VecScalarmu: $\boldsymbol{w}^\intercal \boldsymbol{\mu}_v + \mu_s$.Numbermu: the scalarr.mudirectly.
Related
PortfolioOptimisers.calc_deviations_vec — Function
calc_deviations_vec(
r::Union{Skewness{<:Any, <:Any, <:Any, T1, T2}, ThirdCentralMoment{<:Any, T1, T2}} where {T1, T2},
w::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}
) -> Any
calc_deviations_vec(
r::Union{Skewness{<:Any, <:Any, <:Any, T1, T2}, ThirdCentralMoment{<:Any, T1, T2}} where {T1, T2},
w::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
fees::Union{Nothing, Fees}
) -> Any
Compute the vector of deviations from the centering target for ThirdCentralMoment and Skewness risk measures.
Related
PortfolioOptimisers.calc_deviations_vec — Method
calc_deviations_vec(
r::Union{Skewness{<:Any, <:Any, <:Any, T1, T2}, ThirdCentralMoment{<:Any, T1, T2}} where {T1, T2},
x::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}
) -> Any
Compute the vector of deviations from the centering target for a precomputed returns series for ThirdCentralMoment and Skewness risk measures.
Single-argument form used by the precomputed-returns functor r(x::VecNum).
Related
PortfolioOptimisers.supports_precomputed_returns — Method
supports_precomputed_returns(r::ThirdCentralMoment) -> Any
Return whether ThirdCentralMoment 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