Variance Skew Kurtosis: private API
PortfolioOptimisers.bigger_is_better — Method
bigger_is_better(_::Skewness) -> Bool
Return true because higher skewness is preferred over lower skewness.
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::VarianceSkewKurtosis,
pr::AbstractPriorResult
) -> VarianceSkewKurtosis
resolve_deferred_quantities(
r::VarianceSkewKurtosis,
pr::AbstractPriorResult,
slv
) -> VarianceSkewKurtosis
Resolve every Deferred Quantity held by VarianceSkewKurtosis r against prior result pr.
Two levels, in order. Each child resolves whatever it holds of its own, then the container's pe fans out into every child slot still unstated — sigma and its chol on vr, sk and mu on sk, kt and mu on kt — all from one fit.
A child that names its own quantity keeps it. This is the map's precedence rule applied one level down, and it treats a deferred child slot exactly as it already treats a stated one.
The composed measure adds a variance, a skewness and a kurtosis term, so a caller who wants the three to describe one distribution names pe on the container and states nothing on the children.
Related
PortfolioOptimisers.supports_precomputed_returns — Method
supports_precomputed_returns(r::Skewness) -> Any
Return whether Skewness 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
PortfolioOptimisers.supports_precomputed_returns — Method
supports_precomputed_returns(
_::VarianceSkewKurtosis
) -> Bool
Return false: VarianceSkewKurtosis carries a weights-only variance term r.vr(w) with no bare-series form.
Related