Median Absolute Deviation Risk
PortfolioOptimisers.MedianCenteringFunction — Type
abstract type MedianCenteringFunction <: AbstractAlgorithmAbstract supertype for centering functions used in the Median Absolute Deviation risk measure.
Related
PortfolioOptimisers.MedianCentering — Type
struct MedianCentering <: MedianCenteringFunctionCentres the returns series using the (weighted) median before computing the Median Absolute Deviation.
Related
PortfolioOptimisers.MeanCentering — Type
struct MeanCentering <: MedianCenteringFunctionCentres the returns series using the (weighted) mean before computing the Median Absolute Deviation.
Related
PortfolioOptimisers.MedAbsDevMu — Type
const MedAbsDevMu = Union{<:MuSlot, <:MedianCenteringFunction}Union of valid centring-target types for MedianAbsoluteDeviation.
Accepts a numeric scalar/vector target, an estimator that computes one (a Deferred Quantity — see MuSlot), or a MedianCenteringFunction (e.g. mean or median centering).
The field has two resolution points, and both are forced. A centring strategy resolves in calc_moment_target, at the point of use, because it centres the portfolio series and so needs the asset weights. A Deferred Quantity resolves in factory, because it needs the returns matrix, which calc_moment_target never sees. There is no Nothing state: the default is MedianCentering().
The two are different quantities, not two spellings of one. The median is not linear, so median(w'X) ≠ w' * median(X) — MedianCentering() and mu = MedianExpectedReturns() do not agree. Nor does MeanCentering() agree with a mean estimator when fees are set: it centres net of fees, a resolved vector is gross.
Related
PortfolioOptimisers.MedianAbsoluteDeviation — Type
struct MedianAbsoluteDeviation{__T_settings, __T_w, __T_mu, __T_flag} <: HierarchicalRiskMeasureRepresents the Median Absolute Deviation (MAD) risk measure for hierarchical portfolio optimisation.
MedianAbsoluteDeviation computes the median (or mean) absolute deviation of portfolio returns about a specified centre, providing a robust alternative to variance for measuring dispersion.
Mathematical definition
Let $\mu$ be the chosen centre (median or mean of returns, or a user-supplied value). Define the deviations $\delta_t = x_t - \mu$. The MAD is:
\[\begin{align} \mathrm{MAD}(\boldsymbol{x}) &= \mathrm{median}_{1 \leq t \leq T}(|\delta_t|)\,. \end{align}\]
Where:
- $\mathrm{MAD}(\boldsymbol{x})$: Median absolute deviation of portfolio returns.
- $\boldsymbol{x}$: Portfolio returns vector $T \times 1$.
- $T$: Number of observations.
- $\mu$: Chosen centre (median, mean, or user-supplied value).
- $\delta_t = x_t - \mu$: Deviation of return at period $t$ from the centre.
When flag = true (default), the result is scaled by a consistency factor $(\Phi^{-1}(3/4))^{-1} \approx 1.4826$ so that the MAD is a consistent estimator of the standard deviation under normality.
Fields
settings: Risk measure settings.
w: Optional observation weights vectorobservations × 1, or a concrete subtype ofDynamicAbstractWeights. Ifnothing, the computation is unweighted.
mu: Centre the absolute deviation is taken about. It is aMedianCenteringFunctionthat centres the portfolio series at the point of use, a scalar or a vectorassets × 1, or a Deferred Quantity — an expected returns estimator or a prior estimator that computes the centre against the optimisation's own prior, atfactorytime (seeMedAbsDevMuandresolve_deferred_quantities). There is nonothingstate; the default isMedianCentering.
flag: Algorithm selection flag.
Constructors
MedianAbsoluteDeviation(; settings::HierarchicalRiskMeasureSettings = HierarchicalRiskMeasureSettings(), w::Option{<:ObsWeights} = nothing, mu::MedAbsDevMu = MedianCentering(), flag::Bool = true) -> MedianAbsoluteDeviationKeywords correspond to the struct's fields.
Validation
- If
muis aVecNum:!isempty(mu)andall(isfinite, mu). - If
muis aNumber:isfinite(mu). - If
wis notnothing,!isempty(w).
A stated mu is pinned: it crosses a Cross-Validation fold or a subset view as the whole universe's answer, so it does not follow the refit the optimisation runs on. A caller who wants it to follow the fit names a Deferred Quantity in mu, or keeps a MedianCenteringFunction, which recomputes the centre from the portfolio series at every call.
Functor
(r::MedianAbsoluteDeviation)(w::VecNum, X::MatNum, fees = nothing)Computes the MAD of the portfolio returns series.
Arguments
w::VecNum: Portfolio weights vector.X::MatNum: Asset returns matrix ($T \times N$).fees: Optional fee structure.
View parameters
When port_opt_view is called on this type, the following @vprop-tagged fields are automatically subset to the selected indices:
mu: A stated value is sliced to the selected indices viaport_opt_view. A Deferred Quantity passes through unsliced, and then fits on the subset.
Examples
julia> MedianAbsoluteDeviation()MedianAbsoluteDeviation settings ┼ HierarchicalRiskMeasureSettings │ scale ┴ Float64: 1.0 w ┼ nothing mu ┼ MedianCentering() flag ┴ Bool: trueRelated
References
- [117] P. J. Rousseeuw and C. Croux. Alternatives to the median absolute deviation. Journal of the American Statistical Association 88, 1273–1283 (1993).
PortfolioOptimisers.resolve_deferred_quantities — Method
resolve_deferred_quantities(
r::MedianAbsoluteDeviation,
pr::AbstractPriorResult
) -> MedianAbsoluteDeviation
Resolve a Deferred Quantity in MedianAbsoluteDeviation's mu slot against prior result pr.
This is the only thing factory does to mu. The field is tagged @vprop and not @pprop, so the prior never fills it — a bare MedianAbsoluteDeviation() inside a JuMPOptimiser keeps median-centring rather than silently taking pr.mu.
Related
PortfolioOptimisers.nothing_scalar_array_view — Method
nothing_scalar_array_view(
x::MedianCenteringFunction,
_
) -> MedianCenteringFunction
Return the MedianCenteringFunction x unchanged.
Identity pass-through: centering functions are not sliced by asset index.
Related
PortfolioOptimisers.port_opt_view — Method
port_opt_view(x, i, args...; kwargs...) -> nothing_scalar_array_view(x, i)Sub-select an estimator, result, or algorithm to the asset/observation index i.
port_opt_view is the index-selection counterpart of factory: where factory threads runtime values down a composed struct tree, port_opt_view threads an index selection — restricting every data-bearing field and composed child to the subset i. It is the mechanism that makes meta-optimisers (NestedClustered, SubsetResampling) and cross-validation variants operate on subproblems with identical struct shapes.
Callers do not normally call port_opt_view directly; it is driven by meta-optimisers and cross-validation internals. It is public (not exported) because extension authors who implement a new composed estimator may need to define a method. Use @vprop on data-bearing fields to have the method generated automatically.
This universal fallback handles leaf values: arrays are sliced via nothing_scalar_array_view; scalars, nothing, estimators without data fields, and algorithms pass through unchanged. Composed structs that recurse into children define their own (more specific) method — emitted by @vprop or hand-written.
The threaded tail args... (typically the returns matrix X for the JuMP families) and any kwargs are accepted and dropped here, so a macro-threaded port_opt_view(child, i, X) never MethodErrors on a leaf field.
Algorithm
- Drop
args...andkwargs.... This method is the leaf of the recursion, so it threads nothing further. - Return
nothing_scalar_array_viewofxati, whose own algorithm names the rule for each leaf type.
Related
PortfolioOptimisers.calc_moment_target — Method
calc_moment_target(::MedianAbsoluteDeviation{<:Any, Nothing, <:MeanCentering, ...}, ::Any, x::VecNum)
calc_moment_target(r::MedianAbsoluteDeviation{<:Any, <:ObsWeights, <:MeanCentering, ...}, ::Any, x::VecNum)
calc_moment_target(::MedianAbsoluteDeviation{<:Any, Nothing, <:MedianCentering, ...}, ::Any, x::VecNum)
calc_moment_target(r::MedianAbsoluteDeviation{<:Any, <:ObsWeights, <:MedianCentering, ...}, ::Any, x::VecNum)
calc_moment_target(r::MedianAbsoluteDeviation{<:Any, <:Any, <:VecNum, ...}, w::VecNum, ::Any)
calc_moment_target(r::MedianAbsoluteDeviation{<:Any, <:Any, <:Number, ...}, ::Any, ::Any)
calc_moment_target(r::MedianAbsoluteDeviation{<:Any, <:Any, <:VecScalar, ...}, w::VecNum, ::Any)Compute the centering target for MedianAbsoluteDeviation risk measure calculations.
Dispatches on the type of r.w and r.mu:
- No weights +
MeanCentering: arithmetic mean ofx. ObsWeights+MeanCentering: weighted mean ofx.- No weights +
MedianCentering: median ofx. ObsWeights+MedianCentering: weighted median ofx.VecNummu: dot product $\boldsymbol{w}^\intercal \boldsymbol{\mu}$.Numbermu: the scalarr.mudirectly.VecScalarmu: $\boldsymbol{w}^\intercal \boldsymbol{\mu}_v + \mu_s$.
Related
PortfolioOptimisers.calc_deviations_vec — Function
calc_deviations_vec(
r::MedianAbsoluteDeviation,
w::AbstractVector{<:Union{var"#s89", var"#s88"} where {var"#s89"<:Number, var"#s88"<:AbstractJuMPScalar}},
X::AbstractMatrix{<:Union{var"#s89", var"#s88"} where {var"#s89"<:Number, var"#s88"<:AbstractJuMPScalar}}
) -> Any
calc_deviations_vec(
r::MedianAbsoluteDeviation,
w::AbstractVector{<:Union{var"#s89", var"#s88"} where {var"#s89"<:Number, var"#s88"<:AbstractJuMPScalar}},
X::AbstractMatrix{<:Union{var"#s89", var"#s88"} where {var"#s89"<:Number, var"#s88"<:AbstractJuMPScalar}},
fees::Union{Nothing, Fees}
) -> Any
Compute the vector of deviations from the centering target for MedianAbsoluteDeviation risk measures.
Related
PortfolioOptimisers.calc_deviations_vec — Method
calc_deviations_vec(
r::MedianAbsoluteDeviation,
x::AbstractVector{<:Union{var"#s89", var"#s88"} where {var"#s89"<:Number, var"#s88"<:AbstractJuMPScalar}}
) -> Any
Compute the vector of deviations from the centering target for a precomputed returns series for MedianAbsoluteDeviation.
Single-argument form used by the precomputed-returns functor r(x::VecNum) (ADR 0007).
Related
PortfolioOptimisers.weight_independent_target — Method
weight_independent_target(
_::MedianCenteringFunction
) -> Bool
Return true: MedianCenteringFunction targets are weight-independent centering functions and can be evaluated on a bare return series.
Related
PortfolioOptimisers.supports_precomputed_returns — Method
supports_precomputed_returns(
r::MedianAbsoluteDeviation
) -> Any
Return whether MedianAbsoluteDeviation 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
References
- [117]
- P. J. Rousseeuw and C. Croux. Alternatives to the median absolute deviation. Journal of the American Statistical Association 88, 1273–1283 (1993).