Regime Adjusted Exponential Weighted Variance: private API

Types

PortfolioOptimisers.RegimeAdjustedVarianceStateType
struct RegimeAdjustedVarianceState{__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} <: AbstractPartialFitState

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

Functions

PortfolioOptimisers.get_regime_stateMethod
get_regime_state(
    _::RootMeanSquaredAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<: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
PortfolioOptimisers.get_regime_stateMethod
get_regime_state(
    method::FirstMomentRegimeAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<: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
PortfolioOptimisers.get_regime_stateFunction
get_regime_state(
    method::LogRegimeAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}
) -> Any
get_regime_state(
    method::LogRegimeAdjusted,
    z2_valid::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<: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
hac_squared_returns!(
    cache::RegimeAdjustedVarianceState,
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<: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::RegimeAdjustedVarianceState: 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!Method
process_observation!(
    cache::RegimeAdjustedVarianceState,
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
    estimation_mask::Union{Nothing, AbstractVector{<:Bool}},
    active_mask::Union{Nothing, AbstractVector{<:Bool}}
) -> Any

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. A regime_method of nothing advances no regime state, so the variance stays the plain exponentially weighted recursion.

Arguments

  • cache::RegimeAdjustedVarianceState: 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

  • cache::RegimeAdjustedVarianceState: The cache to read on and to pass to the next observation. The arrays are mutated in place, but regime_state and n_regime_obs are immutable fields that Accessors.@reset replaces, so the caller must rebind the cache to this return value. A caller that discards it freezes the regime state at its initial value.

Related

source
PortfolioOptimisers.regime_adjusted_variance_pass!Function
regime_adjusted_variance_pass!(
    f,
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
    dims::Int64,
    estimation_mask::Union{Nothing, AbstractMatrix{<:Bool}},
    active_mask::Union{Nothing, AbstractMatrix{<:Bool}}
) -> Any
regime_adjusted_variance_pass!(
    f,
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
    dims::Int64,
    estimation_mask::Union{Nothing, AbstractMatrix{<:Bool}},
    active_mask::Union{Nothing, AbstractMatrix{<:Bool}},
    state::Union{Nothing, RegimeAdjustedVarianceState}
) -> Any

Run one forward pass of the online variance update over the observations of X, and call f after each observation.

The pass owns the argument validation, the orientation and the cache, so the two verbs that read it, var and variance_series, state the recursion once. f receives the observation index and the cache as it stands after that observation, which is what makes a point-in-time series a single forward pass rather than one refit per observation.

Arguments

  • f: Function of (i, cache) called after observation i is processed. A caller that wants only the final cache reads the method that takes no f.
  • ce: Regime-adjusted exponentially weighted variance estimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × 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.
  • state: Optional cache to continue from. The default nothing builds the cold cache, which is what a fit over a whole sample needs. partial_fit! passes the estimator's own state instead, so the pass continues where the last call stopped.

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).
  • If state is not nothing, it holds as many assets as X.

Returns

  • cache::RegimeAdjustedVarianceState: The cache after the last observation.

Related

source
regime_adjusted_variance_pass!(
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
    dims::Int64,
    estimation_mask::Union{Nothing, AbstractMatrix{<:Bool}},
    active_mask::Union{Nothing, AbstractMatrix{<:Bool}}
) -> Any
regime_adjusted_variance_pass!(
    ce::RegimeAdjustedExpWeightedVariance,
    X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
    dims::Int64,
    estimation_mask::Union{Nothing, AbstractMatrix{<:Bool}},
    active_mask::Union{Nothing, AbstractMatrix{<:Bool}},
    state::Union{Nothing, RegimeAdjustedVarianceState}
) -> Any

Run one forward pass of the online variance update over the observations of X, and read no intermediate cache.

This is the callback method with a callback that does nothing, so a verb that wants the last cache alone states no callback of its own. var and partial_fit! read the pass this way, and variance_series reads the callback method.

Arguments

  • ce: Regime-adjusted exponentially weighted variance estimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × 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.
  • state: Optional cache to continue from. The default nothing builds the cold cache, which is what a fit over a whole sample needs. partial_fit! passes the estimator's own state instead, so the pass continues where the last call stopped.

Returns

  • cache::RegimeAdjustedVarianceState: The cache after the last observation.

Related

source
PortfolioOptimisers.regime_adjusted_varianceFunction
regime_adjusted_variance(
    cache::RegimeAdjustedVarianceState,
    ce::RegimeAdjustedExpWeightedVariance
) -> Any

Read the regime-adjusted variance out of a cache, as it stands.

Applies the exponentially weighted bias correction, blanks every asset that is not ready, and scales by the square of the regime multiplier. The cache is read, never written, so the same cache answers this call after every observation of a forward pass.

Where ce.regime_method is nothing, process_observation! advances no regime state, so cache.n_regime_obs stays at zero, which is below every admissible regime_min_obs. The multiplier is then one and the variance is the plain recursion.

Where ce.regime_lohi_mult is not nothing, the multiplier is clamped to that (lo, hi) range before it is squared. Where it is nothing, no clamp runs.

Arguments

  • cache::RegimeAdjustedVarianceState: Online variance computation cache.
  • ce::RegimeAdjustedExpWeightedVariance: Variance estimator configuration.

Returns

  • variance::Vector{<:Number}: Per-asset regime-adjusted variance vector of length assets. An asset with fewer than ce.min_obs observations, or one that is not active, is NaN.

Related

source
PortfolioOptimisers.variance_seriesMethod
variance_series(
    ce::RegimeAdjustedExpWeightedVariance,
    X::MatNum;
    dims::Int = 1,
    estimation_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    active_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    kwargs...
) -> Matrix{<:Number}

Compute the point-in-time regime-adjusted exponentially weighted variance series.

Row t holds what var returns for the first t observations of X, so no row reads an observation after its own. The update is a recursion over one observation, so this method overrides the expanding-window fallback with a single forward pass: it reads the cache after each observation instead of refitting.

Arguments

  • ce: Regime-adjusted exponentially weighted variance estimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × 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

  • val::Matrix{<:Number}: Variance series, shaped as (T, N) if dims == 1 or (N, T) if dims == 2. An asset with fewer than ce.min_obs observations at row t is NaN there.

Related

source
Base.copyMethod
copy(
    x::RegimeAdjustedVarianceState
) -> Union{RegimeAdjustedVarianceState{Nothing}, RegimeAdjustedVarianceState{__T_ret_buffer} where __T_ret_buffer<:DataStructures.CircularBuffer}

Copies a RegimeAdjustedVarianceState, so the copy shares no array with the original.

The copy method of the AbstractPartialFitState interface, which partial_fit calls before it folds. Every array field is copied, and the two scalar fields pass through. The circular buffer of recent centred returns is rebuilt at the same capacity, and each observation it holds is copied into it, so a fold on the copy pushes into a buffer of its own.

This family answers copy and refuses merge_states. The two methods are independent: the merge asks whether two blocks fold into one, and the copy asks only that a fold on one estimator leaves another alone.

Algorithm

  1. Rebuild the circular buffer at the capacity of x.ret_buffer, and push a copy of each observation it holds. Take nothing when x.ret_buffer is nothing, which is the estimator that runs no HAC correction.
  2. Name the constructor, and pass a copy of each array field and the two scalar fields unchanged.

Arguments

  • x: The cache to copy.

Returns

  • state::RegimeAdjustedVarianceState: A fresh cache, equal to x, whose arrays are fresh.

Related

source