Conditional X at Risk: private API
PortfolioOptimisers.RMCVaR — Type
const RMCVaR{T} = Union{...}Parameterised union of ConditionalValueatRisk and DistributionallyRobustConditionalValueatRisk sharing the same observation-weight type parameter T.
Used for unified dispatch on CVaR computation methods.
Related
PortfolioOptimisers.RMCVaRRg — Type
const RMCVaRRg{T} = Union{...}Parameterised union of ConditionalValueatRiskRange and DistributionallyRobustConditionalValueatRiskRange sharing the same observation-weight type parameter T.
Used for unified dispatch on CVaR-range computation methods.
Related
PortfolioOptimisers.RMCDaR — Type
const RMCDaR{T} = Union{...}Parameterised union of ConditionalDrawdownatRisk and DistributionallyRobustConditionalDrawdownatRisk sharing the same observation-weight type parameter T.
Used for unified dispatch on CDaR computation 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(
x::DistributionallyRobustConditionalValueatRisk,
pr::AbstractPriorResult
) -> DistributionallyRobustConditionalValueatRisk
resolve_deferred_quantities(
x::DistributionallyRobustConditionalValueatRisk,
pr::AbstractPriorResult,
slv
) -> DistributionallyRobustConditionalValueatRisk
Resolve the significance level alpha, the ambiguity radius r and the tail weight l of a DistributionallyRobustConditionalValueatRisk against prior result pr.
All three slots take a Calibration Rule in place of the number, so all three resolve here. The struct is rebuilt through rebuild_with_slots, and the inner constructor it calls is what re-runs the positivity check on the calibrated number: a rule that returns a value the slot does not admit is refused at fold time, by the same guard a caller's own number meets.
alpha resolves first, because the tail weight reads it. TailTermParity prices a tail term at the measure's own significance level, so alpha and l are a travelling pair and the number reaches the l slot in its CalibrationContext. A stated number, a plain function and a rule that reads no sibling all ignore the field, so the order costs nothing where no rule reads a sibling. The radius reads neither of the two, so its own order is free.
The effective observation weights are computed locally as sel(r.w, pr.w) and threaded to the rule, so a rule that reads a weighted sample size sees the weights the optimisation settled on. The measure carries no solver, so the rule receives none. That holds on both routes: the third argument carries the effective solver for a measure that has a slot for one, and this measure has none.
The series both slots price travels in the same context. It is the returns, which is the default calibration_series states, so this site names what the default context already holds. It is written all the same, for the reason every site writes it: the marker belongs to the measure, and no rule carries one of its own to be corrected.
A measure whose two slots both hold numbers is returned unchanged, so the common case allocates nothing.
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(
x::DistributionallyRobustConditionalValueatRiskRange,
pr::AbstractPriorResult
) -> DistributionallyRobustConditionalValueatRiskRange
resolve_deferred_quantities(
x::DistributionallyRobustConditionalValueatRiskRange,
pr::AbstractPriorResult,
slv
) -> DistributionallyRobustConditionalValueatRiskRange
Resolve the two ambiguity radii and the two tail weights of a DistributionallyRobustConditionalValueatRiskRange against prior result pr.
Each tail keeps its own pair, so four slots resolve here. It carries the reading of the scalar measure's method unchanged: the rebuild re-runs every positivity check, the effective observation weights are computed locally, and a measure whose four slots all hold numbers is returned unchanged.
Each end's tail weight reads that end's own probability. alpha and beta resolve first, and each is stated in the context of the tail weight beside it: l_a reads alpha and l_b reads beta. A skewed sample therefore resolves the two tail weights to two different numbers, which is the whole point of TailTermParity on a Range measure. The two radii read neither probability, so the four remaining slots resolve in one pass.
A radius names no end of the distribution, so a rule placed in the loss-side pair and the same rule placed in the gain-side pair resolve independently, and neither ambiguity slot defaults from the other.
Both ends price one series, which is the returns, so the same marker stands in the context of all four slots. The series is a property of the measure and not of an end, where the significance level is a property of the end.
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(
x::DistributionallyRobustConditionalDrawdownatRisk,
pr::AbstractPriorResult
) -> DistributionallyRobustConditionalDrawdownatRisk
resolve_deferred_quantities(
x::DistributionallyRobustConditionalDrawdownatRisk,
pr::AbstractPriorResult,
slv
) -> DistributionallyRobustConditionalDrawdownatRisk
Resolve the significance level alpha, the ambiguity radius r and the tail weight l of a DistributionallyRobustConditionalDrawdownatRisk against prior result pr.
It carries the reading of resolve_deferred_quantities on the value-at-risk measure unchanged, alpha first and the tail weight reading it off its own CalibrationContext. A drawdown series holds one entry per observation, so a rule reads the same sample size here as it does there.
The series does not carry over, and the context is what says so. This measure prices the absolute drawdown series, so calibration_series states AbsoluteDrawdownSeries and the marker travels beside alpha to both ambiguity slots. TailTermParity then prices the mean drawdown of each column against the $\mathrm{CDaR}_{\alpha}$ of that column, and the radius rules read the error scale off the drawdown sample. The keys :l and :r name this measure's slots and the value-at-risk twin's slots alike, so nothing else could have told a rule which quantity it stands in front of.
Related
PortfolioOptimisers.conditional_drawdown_at_risk — Function
conditional_drawdown_at_risk(dd::VecNum, alpha::Real, ::Nothing) -> Number
conditional_drawdown_at_risk(dd::VecNum, alpha::Real, w::VecNum) -> NumberAggregate a drawdown series into its Conditional Drawdown-at-Risk at level alpha.
This is the shared aggregation kernel behind ConditionalDrawdownatRisk, DistributionallyRobustConditionalDrawdownatRisk and RelativeConditionalDrawdownatRisk: the measures differ only in the drawdown series they feed it (absolute_drawdown_vec and relative_drawdown_vec respectively), so the tail averaging lives here once.
dd is consumed in place — the unweighted method reorders it via partialsort!. Callers pass a freshly computed drawdown vector.
Dispatch on the third argument selects the weighting scheme, so callers resolve observation weights with get_observation_weights and let dispatch do the rest.
::Nothing: unweighted, the mean of the drawdowns beyond thealpha-quantile by rank.w::VecNum: weighted, the weighted mean of the tail, with the boundary observation contributing only its partial weight.
Arguments
dd::VecNum: Drawdown series, all entries ≤ 0. Consumed in place.alpha::Real: Significance level,0 < alpha < 1.w: Resolved observation weights, ornothingfor the unweighted aggregation.
Returns
Number: Conditional Drawdown-at-Risk, returned as a positive loss.
Related