Variance from covariance: private API

PortfolioOptimisers.variance_seriesMethod
variance_series(ce::AbstractCovarianceEstimator, X::MatNum; dims::Int = 1, kwargs...)

Compute the point-in-time variance series, one row per observation.

Row t holds the variance of each asset estimated from observations 1 to t alone, so a caller that reads row t - 1 holds a variance that observation t did not enter. That is what a weight paired with observation t needs: a variance carrying the date-t squared residual would down-weight an asset for its own shock, and would correlate the weights with the residuals.

This method is the fallback that gives every AbstractCovarianceEstimator a series, so a member needs no method of its own to answer correctly. It refits on an expanding window, at a cost of one fit per observation. A member whose estimate is a recursion overrides it with a single forward pass.

Mathematical definition

\[\begin{align} \mathbf{V}_{ti} &= \hat{\sigma}_i^2\left(\mathbf{X}_{1:t}\right)\,. \end{align}\]

Where:

  • $\mathbf{V}_{ti}$: Variance of asset $i$ after observation $t$.
  • $\hat{\sigma}_i^2$: Variance of asset $i$, as ce estimates it.
  • $\mathbf{X}_{1:t}$: First $t$ observations of the data matrix.
  • $T$: Number of observations.

Algorithm

  1. Orient X so that the observations lie on the rows.
  2. For each observation t, call Statistics.var(ce, X[1:t, :]; dims = 1, kwargs...) and write the result into row t.
  3. Return the series, transposed when dims == 2.

Arguments

  • ce: 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.
  • kwargs...: Additional keyword arguments passed to the variance estimator. A keyword carrying one entry per observation is passed unsliced, so an estimator that takes one must override this method.

Validation

  • dims in (1, 2).

Returns

  • val::Matrix{<:Number}: Variance series, shaped as (T, N) if dims == 1 or (N, T) if dims == 2.

Examples

julia> X = [0.01 0.02; 0.03 0.04; 0.02 0.03];julia> PortfolioOptimisers.variance_series(SimpleVariance(), X)3×2 Matrix{Float64}: NaN       NaN   0.0002    0.0002   0.0001    0.0001

Row 1 is a fit on a single observation, so an estimator that needs two returns NaN there.

Related

source