Regime Adjusted Exponential Weighted Covariance

Types

PortfolioOptimisers.RegimeAdjustedTargetType
abstract type RegimeAdjustedTarget <: AbstractAlgorithm

Abstract supertype for all regime-adjustment target structures used in RegimeAdjustedExpWeightedCovariance.

A target defines how the regime-adjusted covariance update is structured (e.g., which baseline covariance form is shrunk toward).

Interfaces

In order to implement a new regime-adjustment target, subtype RegimeAdjustedTarget and optionally implement min_active_assets.

min_active_assets interface

  • min_active_assets(target::RegimeAdjustedTarget) -> Int: Returns the minimum number of active assets required to use this target. Defaults to 1.

Arguments

  • target: The concrete target instance.

Returns

  • n::Int: Minimum required active assets.

Examples

julia> struct MyTarget <: PortfolioOptimisers.RegimeAdjustedTarget endjulia> PortfolioOptimisers.min_active_assets(MyTarget())1

Related

source
PortfolioOptimisers.PortfolioTargetType
struct PortfolioTarget{__T_w} <: RegimeAdjustedTarget

Regime-adjustment target that uses a portfolio-weighted baseline covariance structure.

Fields

  • w: Optional portfolio weights for the portfolio target, as one vector over the assets or as a matrix whose rows are portfolios. If nothing, inverse-volatility weights are used, and they are rebuilt from the running variance at each observation.

Constructors

PortfolioTarget(;    w::Option{<:Union{<:VecNum, <:MatNum}} = nothing) -> PortfolioTarget

Keywords correspond to the struct's fields. The bound is the pair of shapes the fit can honour, because Statistics.cov(ce::RegimeAdjustedExpWeightedCovariance, X::MatNum; dims::Int = 1, estimation_mask::Option{<:AbstractMatrix{<:Bool}} = nothing, active_mask::Option{<:AbstractMatrix{<:Bool}} = nothing, kwargs...) reads a bare matrix and carries no asset names. The count of assets, the sign of each weight and the sum of each row are checked at the fit, where the universe is known.

Validation

  • If w is not nothing, !isempty(w).

Examples

julia> PortfolioTarget()PortfolioTarget  w ┴ nothing

Related

source
PortfolioOptimisers.RegimeAdjustedExpWeightedCovarianceType
struct RegimeAdjustedExpWeightedCovariance{__T_decay, __T_cor_decay, __T_min_obs, __T_hac_lags, __T_regime_method, __T_regime_decay, __T_regime_min_obs, __T_regime_target, __T_regime_lohi_mult, __T_min_val, __T_centred, __T_cache} <: AbstractCovarianceEstimator

Online exponentially weighted covariance estimator with regime-state adjustment.

At each observation it updates a running exponentially weighted covariance, and it forms a one-step-ahead statistic that compares the realised risk of that observation against the risk the state predicted before it. The statistic is smoothed by regime_decay into a scalar regime state, and the covariance is scaled by the square of the multiplier that state names.

The estimator is the covariance twin of RegimeAdjustedExpWeightedVariance. It shares that type's RegimeAdjustedMethod family, and it adds a RegimeAdjustedTarget, which states what the statistic measures: one portfolio direction, the marginal volatilities alone, or the whole covariance structure.

This estimator is mask-aware, so a prior fitted with it keeps a young asset investable and zero-fills the rows the asset was missing through scenario_fill: every consumer of a Prior Result reads its returns matrix, and a scenario-based measure then reads a zero return where the asset had none and understates that asset's risk over those rows, while the covariance stays the estimate this recursion made from the rows it saw. The fill is silent at or below the fitting prior's own fill_limit field, a share of that asset's own observations, warns above it, and refuses any fill under strict; fill_limit defaults to nothing, and this family carries no CoveragePolicy to derive a limit from, so every fill is named.

A regime_method of nothing turns the adjustment off: no regime state advances, so the multiplier stays at one and the estimator is the plain exponentially weighted recursion.

Mathematical definition

Write $\lambda$ for decay and $\lambda_c$ for cor_decay. Where cor_decay is nothing, one recursion carries the whole matrix:

\[\begin{align} S_{t} &= \lambda S_{t-1} + (1-\lambda) \boldsymbol{u}_{t} \boldsymbol{u}_{t}^{\intercal}\,. \end{align}\]

Where:

  • $S_{t}$: Raw exponentially weighted covariance state at time $t$, seeded at zero.
  • $\boldsymbol{u}_{t}$: Observation $t$, centred where centred is false, and HAC-adjusted where hac_lags is not nothing.

Where cor_decay is not nothing, the variance and the correlation run at their own decays and are recombined:

\[\begin{align} v_{i,t} &= \lambda v_{i,t-1} + (1-\lambda) u_{i,t}^{2}\,, \\ Q_{ij,t} &= \lambda_c Q_{ij,t-1} + (1-\lambda_c) \frac{u_{i,t} u_{j,t}}{\sqrt{v_{i,t} v_{j,t}}}\,, \\ \rho_{ij,t} &= \frac{Q_{ij,t}}{\sqrt{Q_{ii,t} Q_{jj,t}}}\,. \end{align}\]

Where:

  • $v_{i,t}$: Raw exponentially weighted variance of asset $i$.
  • $Q_{ij,t}$: Raw exponentially weighted correlation state.
  • $\rho_{ij,t}$: Correlation, normalised from $Q$.

A zero seed damps the state, so the read-out removes the damping before it reports:

\[\begin{align} \hat{\Sigma}_{ij} &= \mathrm{mult}(s_T)^{2}\, \frac{S_{ij,T}}{\sqrt{(1-\lambda^{n_i})(1-\lambda^{n_j})}}\,. \end{align}\]

Where:

  • $\hat{\mathbf{\Sigma}}$: Estimated covariance matrix.
  • $n_i$: Count of valid observations of asset $i$. A pairwise count corrects $Q$.
  • $\mathrm{mult}(s_T)$: Regime multiplier of the smoothed regime state $s_T$, clamped to regime_lohi_mult where that field is not nothing.

Fields

  • decay: Exponential decay factor for the exponentially weighted estimator.
  • cor_decay: Exponential decay factor for the correlation smoother.
  • 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, or nothing to apply no regime adjustment.
  • 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_target: Target structure for the regime-adjusted covariance update.
  • 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

RegimeAdjustedExpWeightedCovariance(;    decay::Number                                         = exp2(-inv(40.0)),    cor_decay::Option{<:Number}                           = nothing,    min_obs::Integer                                      = round(Int, max(1, inv(log2(inv(decay))), isnothing(cor_decay) ? 1 : inv(log2(inv(cor_decay))))),    hac_lags::Option{<:Integer}                           = nothing,    regime_method::Option{<:RegimeAdjustedMethod}         = FirstMomentRegimeAdjusted(),    regime_decay::Number                                  = exp2(-2 * log2(inv(decay))),    regime_min_obs::Integer                               = round(Int, max(1, inv(log2(inv(decay))) / 2)),    regime_target::RegimeAdjustedTarget                   = PortfolioTarget(),    regime_lohi_mult::Option{<:Tuple{<:Number, <:Number}} = nothing,    min_val::Number                                       = sqrt(eps()),    centred::Bool                                         = false,    cache::Option{<:AbstractPartialFitState}              = nothing) -> RegimeAdjustedExpWeightedCovariance

Keywords correspond to the struct's fields. Where cor_decay is not nothing, the default min_obs reads the slower of the two decays.

Validation

  • decay > 0.
  • If cor_decay is not nothing, cor_decay > 0, finite, and non-empty.
  • min_obs > 0 and regime_min_obs > 0.
  • If hac_lags is not nothing, hac_lags > 0.
  • If regime_lohi_mult is not nothing, 0 < regime_lohi_mult[1] < regime_lohi_mult[2].

Examples

julia> ce = RegimeAdjustedExpWeightedCovariance();julia> ce.decay  exp2(-inv(40.0))truejulia> isnothing(ce.cor_decay)true

Related

source

Functions

Statistics.covMethod
Statistics.cov(
    ce::RegimeAdjustedExpWeightedCovariance,
    X::MatNum;
    dims::Int = 1,
    estimation_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    active_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    kwargs...
) -> MatNum

Compute the regime-adjusted exponentially weighted covariance matrix.

Iterates over the observation dimension of X, updating an online covariance cache at each step. After the last observation, removes the damping of the zero seed and scales the result by the square of the regime multiplier.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance 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 covariance entries 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

  • sigma::MatNum: Covariance matrix assets x assets.

Examples

julia> X = [0.01 -0.02; -0.015 0.03; 0.02 -0.01; -0.005 0.012];julia> ce = RegimeAdjustedExpWeightedCovariance(; decay = 0.9, min_obs = 2, regime_min_obs = 2);julia> size(cov(ce, X))(2, 2)

Related

source
Statistics.corMethod
Statistics.cor(
    ce::RegimeAdjustedExpWeightedCovariance,
    X::MatNum;
    dims::Int = 1,
    estimation_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    active_mask::Option{<:AbstractMatrix{<:Bool}} = nothing,
    kwargs...
) -> MatNum

Compute the regime-adjusted exponentially weighted correlation matrix.

This is the covariance of the same call, rescaled to a unit diagonal. The regime multiplier scales the whole matrix, so it cancels in the rescale and the correlation does not read it.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance 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 covariance entries 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

  • rho::MatNum: Correlation matrix assets x assets.

Examples

julia> X = [0.01 -0.02; -0.015 0.03; 0.02 -0.01; -0.005 0.012];julia> ce = RegimeAdjustedExpWeightedCovariance(; decay = 0.9, min_obs = 2, regime_min_obs = 2);julia> LinearAlgebra.diag(cor(ce, X))2-element Vector{Float64}: 1.0 1.0

Related

source
PortfolioOptimisers.partial_fit!Method
partial_fit!(
    est::Union{AbstractEstimator, CovarianceEstimator},
    X::Union{AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}, AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}};
    dims,
    active_mask,
    estimation_mask
) -> Any

Folds observations into the sample buffer an estimator carries.

The buffering arm of partial_fit!, and the method every estimator carrying a SampleBufferState reaches. A family that folds exactly writes methods of its own, and each of them narrows the cache type parameter of its own estimator to the state that fold reads, so a buffer never meets them and this method is what remains. The state's type is therefore the whole route, and nothing refuses the step.

It is one method over both arms of the interface rather than two, because the families that refuse the step declare one method over both arms too, and a pair of narrower methods here would be ambiguous against each of them. So the arm is chosen by the type of X inside the body, which is statically resolved at every call site.

A buffer carries the per-observation masks beside the observations, so a CoveragePolicy mask threads through the wrapper as it does through an estimator's own accumulator, and the read-out hands it back to the batch verb. A wrapped estimator folded under a policy therefore answers what a batch fit over the same window under the same policy answers, and the unwrapped and wrapped paths agree.

Algorithm

  1. Read the buffer out of the cache field with assert_sample_buffer, which refuses an estimator that was never wrapped in Online.
  2. Fold a matrix and its masks through the block arm of partial_fit!, and a vector and its masks through the single-observation arm.
  3. Rebind est.cache with Accessors.@reset, and return the estimator.

Arguments

  • est: Estimator whose buffer is folded forward.
  • X: Observations to fold. A matrix holds one observation per row when dims == 1, and one per column when dims == 2. A vector is a single observation across the assets, and dims is ignored.
  • dims: Dimension along which to perform the computation.
  • active_mask: The active mask of the block, of the shape of X, or of one entry per asset when X is one observation, or nothing.
  • estimation_mask: The estimation mask, on the same terms as active_mask.

Validation

  • est carries a SampleBufferState. An ArgumentError is thrown otherwise.
  • The masks, when they are not nothing, have the shape of X. A DimensionMismatch is thrown otherwise.
  • A buffer holding observations is given the masks it already records. An ArgumentError is thrown otherwise.
  • dims in (1, 2).

Returns

  • est: The estimator, with its cache field rebound to the buffer after the last observation.

Related

source
PortfolioOptimisers.partial_fit!Method
partial_fit!(
    est::Union{AbstractEstimator, CovarianceEstimator},
    X::Union{AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}, AbstractVector{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}}};
    dims,
    active_mask,
    estimation_mask
) -> Any

Folds observations into the sample buffer an estimator carries.

The buffering arm of partial_fit!, and the method every estimator carrying a SampleBufferState reaches. A family that folds exactly writes methods of its own, and each of them narrows the cache type parameter of its own estimator to the state that fold reads, so a buffer never meets them and this method is what remains. The state's type is therefore the whole route, and nothing refuses the step.

It is one method over both arms of the interface rather than two, because the families that refuse the step declare one method over both arms too, and a pair of narrower methods here would be ambiguous against each of them. So the arm is chosen by the type of X inside the body, which is statically resolved at every call site.

A buffer carries the per-observation masks beside the observations, so a CoveragePolicy mask threads through the wrapper as it does through an estimator's own accumulator, and the read-out hands it back to the batch verb. A wrapped estimator folded under a policy therefore answers what a batch fit over the same window under the same policy answers, and the unwrapped and wrapped paths agree.

Algorithm

  1. Read the buffer out of the cache field with assert_sample_buffer, which refuses an estimator that was never wrapped in Online.
  2. Fold a matrix and its masks through the block arm of partial_fit!, and a vector and its masks through the single-observation arm.
  3. Rebind est.cache with Accessors.@reset, and return the estimator.

Arguments

  • est: Estimator whose buffer is folded forward.
  • X: Observations to fold. A matrix holds one observation per row when dims == 1, and one per column when dims == 2. A vector is a single observation across the assets, and dims is ignored.
  • dims: Dimension along which to perform the computation.
  • active_mask: The active mask of the block, of the shape of X, or of one entry per asset when X is one observation, or nothing.
  • estimation_mask: The estimation mask, on the same terms as active_mask.

Validation

  • est carries a SampleBufferState. An ArgumentError is thrown otherwise.
  • The masks, when they are not nothing, have the shape of X. A DimensionMismatch is thrown otherwise.
  • A buffer holding observations is given the masks it already records. An ArgumentError is thrown otherwise.
  • dims in (1, 2).

Returns

  • est: The estimator, with its cache field rebound to the buffer after the last observation.

Related

source
Statistics.covMethod
Statistics.cov(
    ce::RegimeAdjustedExpWeightedCovariance,
    state::RegimeAdjustedCovarianceState;
    kwargs...
) -> MatNum

Read the regime-adjusted covariance out of a state held by hand.

This is regime_adjusted_covariance under the family's public verb, so a state a caller keeps outside an estimator answers the same call as one the estimator holds. The state is read and never written.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator.
  • state: Running state of an incremental fit.
  • kwargs: Additional keyword arguments (ignored).

Returns

  • sigma::MatNum: Covariance matrix assets x assets.

Examples

julia> X = [0.01 -0.02; -0.015 0.03; 0.02 -0.01; -0.005 0.012];julia> ce = partial_fit!(RegimeAdjustedExpWeightedCovariance(; decay = 0.9, min_obs = 2,                                                             regime_min_obs = 2), X);julia> isequal(cov(ce, ce.cache), cov(ce))true

Related

source
Statistics.covMethod
Statistics.cov(ce::RegimeAdjustedExpWeightedCovariance; kwargs...) -> MatNum

Read the regime-adjusted covariance out of the estimator's own state.

The one-argument form is what an incremental fit answers: partial_fit! leaves the state in the cache field, and this verb turns it into the ordinary answer. An estimator that has been given no observation carries no state, so the call is refused rather than answered with a zero.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator carrying a state.
  • kwargs: Additional keyword arguments (ignored).

Validation

  • ce.cache is not nothing. An ArgumentError is thrown otherwise.

Returns

  • sigma::MatNum: Covariance matrix assets x assets.

Examples

julia> X = [0.01 -0.02; -0.015 0.03; 0.02 -0.01; -0.005 0.012];julia> ce = partial_fit!(RegimeAdjustedExpWeightedCovariance(; decay = 0.9, min_obs = 2,                                                             regime_min_obs = 2), X);julia> size(cov(ce))(2, 2)julia> cov(RegimeAdjustedExpWeightedCovariance())ERROR: ArgumentError: `ce` holds no partial-fit state, so there is nothing to read. Call `partial_fit!(ce, X)` first, or `cov(ce, X)` for a fit over a whole sample.[...]

Related

source
Statistics.corMethod
Statistics.cor(
    ce::RegimeAdjustedExpWeightedCovariance,
    state::RegimeAdjustedCovarianceState;
    kwargs...
) -> MatNum

Read the regime-adjusted correlation out of a state held by hand.

The rescale of Statistics.cov(ce::RegimeAdjustedExpWeightedCovariance, state::RegimeAdjustedCovarianceState; kwargs...) to a unit diagonal. The state is read and never written.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator.
  • state: Running state of an incremental fit.
  • kwargs: Additional keyword arguments (ignored).

Returns

  • rho::MatNum: Correlation matrix assets x assets.

Examples

julia> X = [0.01 -0.02; -0.015 0.03; 0.02 -0.01; -0.005 0.012];julia> ce = partial_fit!(RegimeAdjustedExpWeightedCovariance(; decay = 0.9, min_obs = 2,                                                             regime_min_obs = 2), X);julia> isequal(cor(ce, ce.cache), cor(ce))true

Related

source
Statistics.corMethod
Statistics.cor(ce::RegimeAdjustedExpWeightedCovariance; kwargs...) -> MatNum

Read the regime-adjusted correlation out of the estimator's own state.

The one-argument form is what an incremental fit answers: partial_fit! leaves the state in the cache field, and this verb turns it into the ordinary answer. An estimator that has been given no observation carries no state, so the call is refused rather than answered with a zero.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator carrying a state.
  • kwargs: Additional keyword arguments (ignored).

Validation

  • ce.cache is not nothing. An ArgumentError is thrown otherwise.

Returns

  • rho::MatNum: Correlation matrix assets x assets.

Examples

julia> X = [0.01 -0.02; -0.015 0.03; 0.02 -0.01; -0.005 0.012];julia> ce = partial_fit!(RegimeAdjustedExpWeightedCovariance(; decay = 0.9, min_obs = 2,                                                             regime_min_obs = 2), X);julia> size(cor(ce))(2, 2)julia> cor(RegimeAdjustedExpWeightedCovariance())ERROR: ArgumentError: `ce` holds no partial-fit state, so there is nothing to read. Call `partial_fit!(ce, X)` first, or `cor(ce, X)` for a fit over a whole sample.[...]

Related

source
Statistics.covMethod
Statistics.cov(
    ce::RegimeAdjustedExpWeightedCovariance,
    X::MatNum,
    pnl::Option{<:AssetPanel};
    dims::Int = 1,
    kwargs...
) -> MatNum

Compute the regime-adjusted exponentially weighted covariance from a window of an Asset Panel.

This estimator is mask-aware, so it overrides the reduce-and-expand root of the verb and reads the panel's two masks itself: the active mask drives the freeze and the reset, and the estimation mask restricts which assets feed the regime statistic. The answer therefore lives on the whole universe rather than on the Coverage Universe, and a young asset that lists inside the window is answered from the observations it has.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × observations when dims = 2.
  • pnl: Optional AssetPanel, whose active mask the Coverage Universe of the fit is derived from. nothing makes the rule finiteness alone.
  • dims: Dimension along which to perform the computation.
  • kwargs: Additional keyword arguments (ignored).

Returns

  • sigma::MatNum: Covariance matrix of size assets × assets.

Related

source
Statistics.corMethod
Statistics.cor(
    ce::RegimeAdjustedExpWeightedCovariance,
    X::MatNum,
    pnl::Option{<:AssetPanel};
    dims::Int = 1,
    kwargs...
) -> MatNum

Compute the regime-adjusted exponentially weighted correlation from a window of an Asset Panel.

This is the covariance of the same call, rescaled to a unit diagonal, and it reads the panel's two masks through the same override.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × observations when dims = 2.
  • pnl: Optional AssetPanel, whose active mask the Coverage Universe of the fit is derived from. nothing makes the rule finiteness alone.
  • dims: Dimension along which to perform the computation.
  • kwargs: Additional keyword arguments (ignored).

Returns

  • rho::MatNum: Correlation matrix of size assets × assets.

Related

source
Statistics.varMethod
Statistics.var(
    ce::RegimeAdjustedExpWeightedCovariance,
    X::MatNum,
    pnl::Option{<:AssetPanel};
    dims::Int = 1,
    kwargs...
) -> MatNum

Compute the marginal variance of the regime-adjusted exponentially weighted covariance from a window of an Asset Panel.

This is the diagonal of the covariance of the same call, and it reads the panel's two masks through the same override.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × observations when dims = 2.
  • pnl: Optional AssetPanel, whose active mask the Coverage Universe of the fit is derived from. nothing makes the rule finiteness alone.
  • dims: Dimension along which to perform the computation.
  • kwargs: Additional keyword arguments (ignored).

Returns

  • var::MatNum: Marginal variance, as a row where dims is 1 and as a column otherwise.

Related

source
Statistics.stdMethod
Statistics.std(
    ce::RegimeAdjustedExpWeightedCovariance,
    X::MatNum,
    pnl::Option{<:AssetPanel};
    dims::Int = 1,
    kwargs...
) -> MatNum

Compute the marginal volatility of the regime-adjusted exponentially weighted covariance from a window of an Asset Panel.

This is the square root of the diagonal of the covariance of the same call, and it reads the panel's two masks through the same override.

Arguments

  • ce: Regime-adjusted exponentially weighted covariance estimator.
  • X: Data matrix observations × assets if the dims keyword does not exist or dims = 1, assets × observations when dims = 2.
  • pnl: Optional AssetPanel, whose active mask the Coverage Universe of the fit is derived from. nothing makes the rule finiteness alone.
  • dims: Dimension along which to perform the computation.
  • kwargs: Additional keyword arguments (ignored).

Returns

  • std::MatNum: Marginal volatility, as a row where dims is 1 and as a column otherwise.

Related

source
PortfolioOptimisers.min_active_assetsFunction
min_active_assets(_::RegimeAdjustedTarget) -> Int64

Returns the minimum number of active assets required for this regime-adjustment target.

Arguments

  • ::RegimeAdjustedTarget: Regime-adjustment target (unused by this default method).

Returns

  • 1::Int: The default minimum is one active asset.

Related

source
min_active_assets(_::MahalanobisTarget) -> Int64

Returns the minimum number of active assets required for the Mahalanobis target.

Arguments

  • ::MahalanobisTarget: Mahalanobis regime-adjustment target (unused).

Returns

  • 2::Int: At least two active assets are required.

Related

source
PortfolioOptimisers.merge_statesMethod
merge_states(
    a::RegimeAdjustedCovarianceState,
    b::RegimeAdjustedCovarianceState
)

Refuses a pair of regime-adjusted covariance states, because this family does not merge.

A block fitted from a cold start is not what the same block contributes after another one. The regime statistic scores each observation against the state that stands before it, so a cold block loses every comparison its first min_obs observations would have made, and a correlation state that is normalised by a running variance carries that variance with it.

Fold the second block into the first with partial_fit! instead. A sequential fit is exact, and it is the route this family gives.

Algorithm

  1. Refuse the pair with assert_mergeable_states, which names a type mismatch and an asset-count mismatch first, as the AbstractPartialFitState interface asks of every family.
  2. Throw an ArgumentError naming the reason this family does not merge.

Arguments

  • a: The first state.
  • b: The second state.

Validation

Returns

  • Never returns. An ArgumentError is thrown.

Related

source