Skip to content
13

Regime Adjusted Exponential Weighted Variance

Types

PortfolioOptimisers.RegimeAdjustedMethod Type
julia
abstract type RegimeAdjustedMethod <: AbstractEstimator

Abstract supertype for all regime adjustment methods in PortfolioOptimisers.jl.

All concrete subtypes should subtype RegimeAdjustedMethod and implement the regime_multiplier interface.

Interfaces

In order to implement a new regime adjustment method that works seamlessly with the library, subtype RegimeAdjustedMethod and implement the following method:

regime_multiplier interface

  • regime_multiplier(method::RegimeAdjustedMethod, regime_state::Number) -> Number: Computes the variance scaling multiplier from the smoothed regime state.

Arguments

  • method: The concrete regime adjustment method instance.

  • regime_state::Number: The current smoothed regime state value.

Returns

  • mult::Number: The multiplicative scaling factor applied to the variance.

Examples

julia
julia> struct MyRegimeMethod <: PortfolioOptimisers.RegimeAdjustedMethod end

julia> function PortfolioOptimisers.regime_multiplier(::MyRegimeMethod, s::Number)
           return abs(s)
       end

julia> PortfolioOptimisers.regime_multiplier(MyRegimeMethod(), -1.5)
1.5

Related

source
PortfolioOptimisers.LogRegimeAdjusted Type
julia
struct LogRegimeAdjusted{__T_x, __T_y, __T_kappa} <: RegimeAdjustedMethod

Regime adjustment method that scales variance exponentially with the smoothed log-deviation of standardised squared returns from its expected value under stationarity.

Mathematical definition

The regime state s is defined as s¯=1Ttlnmax(zt2,ε)κ, where κ=ψ(x)+lny (ψ = digamma) is the stationary expectation of lnz2 under a χ2(1) distribution scaled by y, and ε is a small positive threshold.

κ=ψ(x)+lny,s=1Ttlnmax(zt2,ε)κ,mult=exp(xs).

Where:

  • κ: Stationary expectation of lnz2 under the specified distribution.

  • ψ: Digamma function.

  • x, y: Parameters of LogRegimeAdjusted.

  • s: Smoothed log-deviation regime state.

  • T: Number of observations.

  • zt2: Standardised squared return at time t.

  • ε: Small positive threshold for numerical stability.

  • mult: Variance scaling multiplier.

Fields

  • x: Shape parameter of the log regime adjustment.

  • y: Scale parameter of the log regime adjustment.

  • kappa: Precomputed normalisation constant digamma(x) + log(y) for the log regime adjustment.

Constructors

julia
LogRegimeAdjusted(;
    x::Number = 0.5,
    y::Number = 2.0
) -> LogRegimeAdjusted

Keywords correspond to the struct's fields. The kappa field is derived from x and y and cannot be set directly.

Validation

  • x is valid (i.e., x >= 0, finite, and non-empty).

  • y is valid (i.e., y >= 0, finite, and non-empty).

Examples

julia
julia> LogRegimeAdjusted()
LogRegimeAdjusted
      x ┼ Float64: 0.5
      y ┼ Float64: 2.0
  kappa ┴ Float64: -1.2703628454614782

Related

source
PortfolioOptimisers.FirstMomentRegimeAdjusted Type
julia
struct FirstMomentRegimeAdjusted{__T_x} <: RegimeAdjustedMethod

Regime adjustment method that scales variance by the ratio of the mean absolute deviation of standardised returns to the first-moment normalisation constant x.

Mathematical definition

The regime state s and multiplier are:

s=1x1Ttmax(zt2,0),mult=s.

Where:

  • s: Regime state (ratio of mean absolute deviation to normalisation constant x).

  • x=2/π: Expected value of |z| for a standard normal z.

  • T: Number of observations.

  • zt: Standardised return at time t.

  • mult: Variance scaling multiplier.

Fields

  • x: First-moment normalisation constant for the regime adjustment.

Constructors

julia
FirstMomentRegimeAdjusted(;
    x::Number = sqrt(2 * inv(π))
) -> FirstMomentRegimeAdjusted

Keywords correspond to the struct's fields.

Validation

  • x is valid (i.e., x >= 0, finite, and non-empty).

Examples

julia
julia> FirstMomentRegimeAdjusted()
FirstMomentRegimeAdjusted
  x ┴ Float64: 0.7978845608028654

Related

source
PortfolioOptimisers.RootMeanSquaredAdjusted Type
julia
struct RootMeanSquaredAdjusted <: RegimeAdjustedMethod

Regime adjustment method that scales variance by the square root of the mean of the standardised squared returns.

Mathematical definition

s=1Ttzt2,mult=max(s,0).

Where:

  • s: Mean of standardised squared returns.

  • T: Number of observations.

  • zt: Standardised return at time t.

  • mult: Variance scaling multiplier.

Related

source
PortfolioOptimisers.RegimeAdjustedExpWeightedVariance Type
julia
struct RegimeAdjustedExpWeightedVariance{__T_decay, __T_min_obs, __T_hac_lags, __T_regime_method, __T_regime_decay, __T_regime_min_obs, __T_regime_lohi_mult, __T_min_val, __T_centred} <: AbstractCovarianceEstimator

Online exponentially weighted variance estimator with regime-state adjustment.

At each observation, it updates a running exponentially weighted variance and computes a standardised squared innovation . After accumulating enough observations, it smooths a regime state using regime_decay, then scales the final variance by regime_multiplier(regime_method, regime_state)².

Mathematical definition

EWM variance update (decay λ):

vt=λvt1+(1λ)(rtr¯)2.

Standardised innovation:

zt2=(rtr¯)2/vt.

Regime state smoothed with regime_decay λr (g defined by RegimeAdjustedMethod):

st=λrst1+(1λr)g(zt2).

Final variance:

σ^2=mult(sT)2vT.

Where:

  • vt: Exponentially weighted variance at time t.

  • λ: EWM decay parameter (decay field).

  • rt: Return at time t.

  • r¯: Mean return.

  • zt2: Standardised squared innovation (rtr¯)2/vt.

  • st: Smoothed regime state at time t.

  • λr: Regime decay parameter (regime_decay field).

  • g(): Regime state transformation (see RegimeAdjustedMethod).

  • σ^2: Final regime-adjusted variance.

  • mult(sT): Variance scaling multiplier (see RegimeAdjustedMethod).

  • T: Number of observations.

Fields

  • decay: Exponential decay factor for the exponentially weighted estimator.

  • min_obs: Minimum number of observations required before the estimator produces a valid result.

  • hac_lags: Optional number of lags for Heteroskedasticity and Autocorrelation Consistent (HAC) kernel correction of squared returns. If nothing, no HAC correction is applied.

  • regime_method: Regime adjustment method used to compute the per-observation regime state.

  • regime_decay: Exponential decay factor for smoothing the regime state.

  • regime_min_obs: Minimum number of regime observations required before the regime multiplier is applied.

  • regime_lohi_mult: Optional (lo, hi) tuple bounding the regime multiplier range. If nothing, no clamping is applied.

  • min_val: Minimum threshold to prevent division by zero or degenerate estimates.

  • centred: Whether to treat the returns as pre-centred (mean zero). If false, the location is estimated online.

Constructors

julia
RegimeAdjustedExpWeightedVariance(;
    decay::Number             = exp2(-inv(40.0)),
    min_obs::Integer          = round(Int, max(1, inv(log2(inv(decay))))),
    hac_lags::Option{<:Integer} = nothing,
    regime_method::RegimeAdjustedMethod = FirstMomentRegimeAdjusted(),
    regime_decay::Number      = exp2(-2 / inv(log2(inv(decay)))),
    regime_min_obs::Integer   = round(Int, max(1, inv(log2(inv(decay))) / 2)),
    regime_lohi_mult::Option{<:Tuple{<:Number, <:Number}} = (0.7, 1.6),
    min_val::Number           = sqrt(eps()),
    centred::Bool             = false
) -> RegimeAdjustedExpWeightedVariance

Keywords correspond to the struct's fields.

Validation

  • decay > 0.

  • min_obs > 0.

  • If hac_lags is not nothing, hac_lags > 0.

  • regime_min_obs > 0.

  • If regime_lohi_mult is not nothing, 0 < regime_lohi_mult[1] < regime_lohi_mult[2].

Examples

julia
julia> ce = RegimeAdjustedExpWeightedVariance();

julia> ce.decay  exp2(-inv(40.0))
true

julia> ce.min_obs
40

Related

source
PortfolioOptimisers.RegimeAdjustedVarianceCache Type
julia
struct RegimeAdjustedVarianceCache{__T_ret_buffer, __T_variance, __T_X2, __T_X_old_i, __T_z2, __T_location, __T_obs_count, __T_old_obs_count, __T_active, __T_regime_state, __T_n_regime_obs} <: AbstractResult

Internal mutable cache for the online variance update in RegimeAdjustedExpWeightedVariance.

This type is an implementation detail and is not intended for direct use.

Fields

  • ret_buffer: Optional circular buffer of recent centred returns for HAC kernel correction.

  • variance: Running per-asset variance vector.

  • X2: Working array for current (possibly HAC-adjusted) squared returns.

  • X_old_i: Working array for lagged centred returns.

  • z2: Standardised squared innovations used for regime state computation.

  • location: Exponentially smoothed location (mean) vector.

  • obs_count: Per-asset count of observations processed.

  • old_obs_count: Per-asset observation count from the previous step.

  • active: Boolean mask indicating which assets are currently active.

  • regime_state: Current smoothed regime state value.

  • n_regime_obs: Number of observations used to update the regime state.

Related

source
PortfolioOptimisers.regime_multiplier Function
julia
regime_multiplier(
    method::LogRegimeAdjusted,
    regime_state::Number
) -> Any

Computes the variance scaling multiplier for the log regime adjustment method.

Arguments

  • method::LogRegimeAdjusted: Log regime adjustment method.

  • regime_state::Number: Current smoothed regime state.

Returns

  • mult::Number: Variance scaling multiplier exp(method.x * regime_state).

Related

source
julia
regime_multiplier(
    _::FirstMomentRegimeAdjusted,
    regime_state::Number
) -> Number

Computes the variance scaling multiplier for the first-moment regime adjustment method.

Arguments

  • ::FirstMomentRegimeAdjusted: First-moment regime adjustment method (unused).

  • regime_state::Number: Current smoothed regime state.

Returns

  • mult::Number: Variance scaling multiplier equal to regime_state directly.

Related

source
julia
regime_multiplier(
    _::RootMeanSquaredAdjusted,
    regime_state::Number
) -> Any

Computes the variance scaling multiplier for the root-mean-squared regime adjustment method.

Arguments

  • ::RootMeanSquaredAdjusted: Root-mean-squared regime adjustment method (unused).

  • regime_state::Number: Current smoothed regime state.

Returns

  • mult::Number: Variance scaling multiplier sqrt(max(regime_state, 0)).

Related

source
PortfolioOptimisers.get_regime_state Function
julia
get_regime_state(
    _::RootMeanSquaredAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    _
) -> Any

Computes the scalar regime state for the root-mean-squared adjustment from valid standardised squared innovations.

Arguments

  • ::RootMeanSquaredAdjusted: Root-mean-squared regime adjustment method (unused).

  • z2_valid::VecNum: Vector of valid (non-NaN) standardised squared innovations.

  • ::Any: Ignored minimum value argument.

Returns

  • s::Number: Mean of z2_valid.

Related

source
julia
get_regime_state(
    method::FirstMomentRegimeAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    _
) -> Any

Computes the scalar regime state for the first-moment adjustment from valid standardised squared innovations.

Arguments

  • method::FirstMomentRegimeAdjusted: First-moment regime adjustment method.

  • z2_valid::VecNum: Vector of valid (non-NaN) standardised squared innovations.

  • ::Any: Ignored minimum value argument.

Returns

  • s::Number: Mean absolute deviation mean(sqrt(max.(z², 0))) / method.x.

Related

source
julia
get_regime_state(
    method::LogRegimeAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}}
) -> Any
get_regime_state(
    method::LogRegimeAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    min_val::Number
) -> Any

Computes the scalar regime state for the log adjustment from valid standardised squared innovations.

Arguments

  • method::LogRegimeAdjusted: Log regime adjustment method.

  • z2_valid::VecNum: Vector of valid (non-NaN) standardised squared innovations.

  • min_val::Number: Minimum threshold applied before taking logarithms.

Returns

  • s::Number: Mean log deviation mean(log(max.(z², min_val))) - method.kappa.

Related

source
PortfolioOptimisers.hac_squared_returns! Function
julia
hac_squared_returns!(
    cache::RegimeAdjustedVarianceCache,
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    finite_mask::AbstractVector{<:Bool}
) -> Any

Computes (possibly HAC-corrected) squared returns for the current observation and stores the result in cache.X2.

Arguments

  • cache::RegimeAdjustedVarianceCache: Online variance computation cache.

  • ce::RegimeAdjustedExpWeightedVariance: Variance estimator configuration.

  • X::VecNum: Current centred returns vector.

  • finite_mask::AbstractVector{<:Bool}: Boolean mask of finite entries in X.

Returns

  • X2::VecNum: The HAC-adjusted squared returns stored in cache.X2.

Related

source
PortfolioOptimisers.process_observation! Function
julia
process_observation!(
    cache::RegimeAdjustedVarianceCache,
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractVector{<:Union{var"#s20", var"#s19"} where {var"#s20"<:Number, var"#s19"<:AbstractJuMPScalar}},
    estimation_mask::Union{Nothing, AbstractVector{<:Bool}},
    active_mask::Union{Nothing, AbstractVector{<:Bool}}
)

Processes a single observation row (or column) to update the online variance cache.

Updates the running location, variance, and standardised squared innovations in cache, then advances the smoothed regime state.

Arguments

  • cache::RegimeAdjustedVarianceCache: Online variance computation cache (mutated).

  • ce::RegimeAdjustedExpWeightedVariance: Variance estimator configuration.

  • X::VecNum: Returns vector for the current observation.

  • estimation_mask::Option{<:AbstractVector{<:Bool}}: Optional mask restricting which assets contribute to the regime state update.

  • active_mask::Option{<:AbstractVector{<:Bool}}: Optional mask of currently active assets. Inactive assets have their variance and counts reset.

Returns

  • nothing.

Related

source
Statistics.var Method
julia
Statistics.var(
    ce::RegimeAdjustedExpWeightedVariance,
    X::MatNum;
    dims::Int = 1,
    estimation_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    active_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    kwargs...
) -> Vector{<:Number}

Compute the regime-adjusted exponentially weighted variance for each asset.

Iterates over the observation dimension of X, updating an online variance cache at each step. After processing all observations, applies a bias-correction factor and scales the result by the square of the regime multiplier derived from the smoothed regime state.

Arguments

  • ce: Regime-adjusted exponentially weighted variance estimator.

  • X: Data matrix observations × features if the dims keyword does not exist or dims = 1, features × observations when dims = 2.

  • dims: Dimension along which to perform the computation.

  • estimation_mask: Optional boolean matrix with the same size as X. When provided, only assets where estimation_mask[i, :] (or [:, i]) is true contribute to the regime state update for observation i.

  • active_mask: Optional boolean matrix with the same size as X. When provided, assets that become inactive have their variance and observation count reset.

  • kwargs: Additional keyword arguments (ignored).

Validation

  • dims in (1, 2).

  • If estimation_mask is not nothing, size(X) == size(estimation_mask).

  • If active_mask is not nothing, size(X) == size(active_mask).

Returns

  • var::Vector{<:Number}: Per-asset regime-adjusted exponentially weighted variance vector of length features. Assets with fewer than ce.min_obs observations return NaN.

Related

source