The Coverage Universe: private API
An asset is in the Coverage Universe of one fit when its return is finite and the active mask of the AssetPanel is true at every row of the window. A prior reduces its returns matrix to that universe, fits every plain estimator on the clean block, and expands every block of its result onto the full asset universe with a NaN frame outside it.
The Asset Panel travels as the third positional argument of every moment verb, and the root method of each verb is that reduce-and-expand. A mask-aware estimator overrides its root and takes the whole window.
The universe and the reduction
PortfolioOptimisers.coverage_mask — Function
coverage_mask(X::MatNum, pnl::Nothing; dims::Int = 1) -> Option{BitVector}
coverage_mask(X::MatNum, pnl::AssetPanel{<:Any, Nothing, Nothing};
dims::Int = 1) -> Option{BitVector}
coverage_mask(X::MatNum, pnl::AssetPanel; dims::Int = 1) -> Option{BitVector}Derive the Coverage Universe of one fit: true at every asset a plain moment estimator can be fitted on.
An asset is in the Coverage Universe when its return is finite and the panel's active mask is true at every row of the window. The estimation mask is not read: it names the assets that enter a cross-sectional estimate, and a moment is not one. A static panel carries no mask, so the rule there is finiteness alone, as it is with no panel at all.
The all-covered case returns nothing rather than a mask of every true. That sentinel skips both the slice and the expansion, exactly as the nothing of investable_mask skips the optimiser's two halves.
The rule has one cost, and no docstring may hide it. One non-finite return, or one inactive row, inside the window puts the asset outside the Coverage Universe for that fit. A caller with a holiday fills it at the price level with PriceGapFill, or reaches for a mask-aware estimator, which takes the whole window and emits its own frame.
The two scans are independent, and only the asset axes must agree. A prior that reweights observations works on the axis its nested prior answered, and a nested prior may drop rows, so X and the panel can carry different observation counts and no row of one pairs with a row of the other. Pairing them by position would read the wrong date, and pairing them by the tail would assume a warm-up that no contract states. Reading each over its own rows assumes nothing. It is conservative where the two axes differ: an asset that the panel reports inactive at a row the sample no longer holds is outside the Coverage Universe of that fit.
Algorithm
- Orient
Xtoobservations × assetswithdims_oriented. - Scan each column of
X. An asset stays in while its return is finite at every row. - Scan each column of the active mask, where a panel carries one. An asset stays in while the mask is
trueat every row. - Throw an
IsEmptyErrorwhen no asset is covered. A moment over no asset has no answer to give. - Return
nothingwhen every asset is covered, and the mask otherwise.
Arguments
X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.pnl: OptionalAssetPanel, whose active mask the Coverage Universe of the fit is derived from.nothingmakes the rule finiteness alone.dims: Dimension along which to perform the computation.
Validation
dims in (1, 2).- The asset axis of
pnl.amskmust be the asset axis of the orientedX. - At least one asset must be covered.
Returns
cmsk::Option{BitVector}:trueat every covered asset, ornothingwhen every asset is covered.
Related
coverage_mask(X::MatNum, iv::MatNum, pnl::Option{<:AssetPanel};
dims::Int = 1) -> Option{BitVector}Derive the Coverage Universe of one ImpliedVolatility fit, which reads an implied volatility surface beside its returns.
The estimator fits on the assets whose returns qualify under coverage_mask and whose implied volatilities are finite at every row of the window. An implied volatility series is padded NaN where it is silent, exactly as a return is, so an asset the estimator cannot price is named by the same rule that names an asset it cannot estimate, and reduce-and-expand writes its NaN row and column.
This narrows the asset universe by reading a second input. It is not a second mask and not a different Coverage Universe: nothing on the implied volatility axis is named, and every consumer of the expanded moment reads it exactly as it reads an absent return.
The narrowing sits in the estimator's own reduce-and-expand, rather than at the carrier that assembled iv. A caller reaching Statistics.cov(ce, X; iv = …) with a surface of their own has crossed no carrier boundary, and neither has a nested estimator receiving the forwarded iv; both are downstream of this reduction, so both see a block whose implied volatilities are complete.
Algorithm
- Orient
Xandivtoobservations × assetswithdims_oriented. - Derive the Coverage Universe of
Xwithcoverage_mask. - Scan each column of
iv. An asset stays in while its implied volatility is finite at every row. - Intersect the two, and hand the result to
coverage_sentinelwith a refusal that names the implied volatilities.
Arguments
X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.iv: Implied volatility surfaceobservations × assets.pnl: OptionalAssetPanel, whose active mask the Coverage Universe of the fit is derived from.nothingmakes the rule finiteness alone.dims: Dimension along which to perform the computation.
Validation
dims in (1, 2).- The asset axis of
pnl.amskmust be the asset axis of the orientedX. - At least one asset must be covered.
Returns
cmsk::Option{BitVector}:trueat every covered asset, ornothingwhen every asset is covered.
Related
PortfolioOptimisers.coverage_sentinel — Function
coverage_sentinel(cmsk::BitVector) -> Option{BitVector}
coverage_sentinel(cmsk::BitVector, msg::AbstractString) -> Option{BitVector}Refuse an empty Coverage Universe, and collapse a complete one onto the nothing sentinel.
This is the tail that every coverage_mask method shares, so the refusal and the sentinel are written once and cannot drift apart. A method that reads an input the two-argument one does not passes its own msg, because the reason an asset left the Coverage Universe is the one thing the tail cannot know: coverage_mask reads an implied volatility surface as well, and a message naming only the returns and the Asset Panel would send its caller looking in the wrong place.
Algorithm
- Throw an
IsEmptyErrorcarryingmsgwhencmskholds notrue. - Return
nothingwhencmskholds nofalse. - Return
cmskotherwise.
Arguments
cmsk: The raw coverage mask, one entry per asset.msg: The refusal message, naming every input the mask was derived from.
Validation
- At least one asset must be covered.
Returns
cmsk::Option{BitVector}:cmskitself, ornothingwhen every asset is covered.
Related
PortfolioOptimisers.coverage_reduction — Method
coverage_reduction(X::MatNum, pnl::Option{<:AssetPanel};
dims::Int = 1) -> Tuple{Option{BitVector}, MatNum}Reduce a returns matrix to its Coverage Universe, and return the mask beside the clean block.
The reduction keeps the caller's orientation, so the plain moment verb that receives the block sees exactly the matrix it saw before the Asset Panel existed, and its own dims still describes it. The nothing sentinel returns X itself, so a complete window allocates nothing.
Algorithm
- Derive the Coverage Universe with
coverage_mask. - Return
(nothing, X)on the sentinel. - Slice the asset axis of
Xotherwise: its columns whendims = 1, and its rows whendims = 2.
Arguments
X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.pnl: OptionalAssetPanel, whose active mask the Coverage Universe of the fit is derived from.nothingmakes the rule finiteness alone.dims: Dimension along which to perform the computation.
Validation
dims in (1, 2).
Returns
(cmsk, Xc)::Tuple{Option{BitVector}, MatNum}: The Coverage Universe, andXreduced to it.
Related
PortfolioOptimisers.coverage_reduction — Method
coverage_reduction(rd::AbstractReturnsResult;
dims::Int = 1) -> Tuple{Option{BitVector}, AbstractReturnsResult}
coverage_reduction(X::MatNum, rd::AbstractReturnsResult;
dims::Int = 1) -> Tuple{Option{BitVector}, AbstractReturnsResult}
coverage_reduction(cmsk::Nothing,
rd::AbstractReturnsResult) -> Tuple{Nothing, AbstractReturnsResult}
coverage_reduction(cmsk::BitVector,
rd::AbstractReturnsResult) -> Tuple{BitVector, AbstractReturnsResult}Reduce a returns carrier to the Coverage Universe of its own window.
This is the carrier-level door of the seam. coverage_reduction(X::MatNum, pnl::Option{<:AssetPanel}) hands a moment estimator a clean block, and this hands a consumer of the whole carrier a clean carrier: nx, X, the benchmark, the implied volatility surface and the AssetPanel are all sliced at the same asset index by port_opt_view. Pre-selection is the caller: fit_preprocessing over an AbstractAssetSelector reduces here, so every selector ranks among live assets alone.
Four methods, and every branch is dispatch rather than a condition, as it is in coverage_reduction(opt::AbstractOptimisationEstimator, rd::ReturnsResult). The first hands the carrier's returns matrix back as the leading argument; the second derives the mask; the nothing method is the all-covered path and returns the carrier untouched; the BitVector method takes the view.
The split between the first two is the family's refusal. A carrier whose X is not an observations × assets matrix has no asset axis to reduce — PredictionReturnsResult collapsed it into one portfolio return series — so it matches no method and the call is a MethodError naming the carrier. That refusal comes before the panel is read, so a carrier that satisfies neither the {nx, X} contract nor the {nx, X, pnl} one is named by its returns matrix rather than by a missing field.
An all-dead window throws an IsEmptyError where the mask is derived, so the refusal is coverage_mask's and every caller has it for free.
Algorithm
- Hand
rd.Xback as the leading argument, which refuses a carrier with no asset axis. - Derive the Coverage Universe of
Xandrd.pnlwithcoverage_mask. - Return the mask and the carrier unchanged when the mask is
nothing. - Otherwise return the mask beside a
port_opt_viewof the carrier atfindall(cmsk).
Arguments
rd: The returns result to use.X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.cmsk: The Coverage Universe, ornothing.dims: Dimension along which to perform the computation.
Validation
dims in (1, 2).- The carrier must hold an
observations × assetsreturns matrix. - At least one asset must be in the Coverage Universe.
Returns
(cmsk, rdc)::Tuple{Option{BitVector}, AbstractReturnsResult}: The Coverage Universe, and the carrier reduced to it.
Related
PortfolioOptimisers.coverage_reduced_pair — Function
coverage_reduced_pair(A::MatNum, B::MatNum, cmsk::Nothing) -> Tuple{MatNum, MatNum}
coverage_reduced_pair(A::MatNum, B::MatNum, cmsk::BitVector) -> Tuple{MatNum, MatNum}Slice two observations × assets matrices onto the same Coverage Universe.
An estimator that reads a second per-asset panel beside its returns, as ImpliedVolatility reads an implied volatility surface, must slice both, so that the two describe the same universe. The nothing sentinel returns both untouched.
Arguments
A,B: Two matrices, bothobservations × assets.cmsk: The Coverage Universe, ornothing.
Returns
(A, B)::Tuple{MatNum, MatNum}: The two matrices on the Coverage Universe.
Related
PortfolioOptimisers.panel_moment_masks — Function
panel_moment_masks(pnl::Nothing) -> Tuple{Nothing, Nothing}
panel_moment_masks(pnl::AssetPanel) -> TupleRead the two universe masks a mask-aware moment estimator takes, out of an optional Asset Panel.
A mask-aware estimator overrides the panel method of its verb and takes the whole window, so it needs the masks themselves rather than the Coverage Universe that coverage_mask derives. No panel, and a static panel, both carry no mask, so both give the pair of nothing that is the estimator's own unmasked path.
Arguments
pnl: OptionalAssetPanel, whose active mask the Coverage Universe of the fit is derived from.nothingmakes the rule finiteness alone.
Returns
(amsk, emsk)::Tuple: The active mask and the estimation mask, or twonothing.
Related
The expansion
PortfolioOptimisers.coverage_nan_frame — Function
coverage_nan_frame(A::AbstractArray, sz::Dims) -> AbstractArrayAllocate the NaN frame that a moment expands into.
The frame takes its element type from the block through similar, and not from eltype(A). MatNum admits a JuMP scalar as well as a number, so eltype of one splits into two branches at inference and the numeric half is the only one a moment ever takes. Reading the type off the block instead keeps the frame in the block's own element type and leaves no unreachable branch behind.
Algorithm
- Allocate an array of
sz, of the same kind and element type asA. - Fill it with
NaN, and return it.
Arguments
A: The block that will be written into the frame.sz: Size of the frame.
Returns
frame::AbstractArray: An array of sizesz, filled withNaN.
Related
PortfolioOptimisers.coverage_pair_index — Function
coverage_pair_index(cmsk::BitVector) -> Vector{Int}Map the columns of a reduced co-moment tensor onto the columns of the full-universe one.
A coskewness tensor is assets × assets² and a cokurtosis matrix is assets² × assets². Both index an asset pair (a, b) at (a - 1) * N + b, because both are built from kron(o, Y) ⊙ kron(Y, o), whose column (a - 1) * N + b is the elementwise product of column b and column a. The reduced tensor uses the same rule over the reduced width, and its pairs run with a outermost, so the index that this returns is in the order that the reduced columns already have.
Algorithm
- Take the positions of the covered assets.
- Return
(a - 1) * N + bover every ordered pair of them, withaoutermost.
Arguments
cmsk: The Coverage Universe.
Returns
idx::Vector{Int}: The full-universe pair columns of the reduced ones, in the reduced order.
Related
PortfolioOptimisers.expand_columns — Function
expand_columns(A::MatNum, cmsk::Nothing) -> A
expand_columns(A::MatNum, cmsk::BitVector) -> MatNumWrite a block whose columns are the asset axis back into a NaN frame of the full width.
This is one of the three primitives of the expansion, beside expand_rows and expand_vector. expand_moment is the verb-facing name over them, and a prior that carries a block of its own reaches for them directly: a reconstructed returns matrix and a Cholesky factor are observations × assets and factors × assets, so both expand along their columns.
Arguments
A: The block that the reduced fit produced,anything × assets.cmsk: The Coverage Universe, ornothing.
Returns
- The block on the full asset universe, carrying
NaNoutside the Coverage Universe.
Related
PortfolioOptimisers.reduce_columns — Function
reduce_columns(A::MatNum, cmsk::Nothing) -> A
reduce_columns(A::MatNum, cmsk::BitVector) -> MatNumTake the columns of an observations × assets block that a mask keeps.
This is the inverse of expand_columns, and it is written beside it so that the pair cannot drift. coverage_reduction does the same slice for a mask it derives itself; this is for a caller that already holds one — an AugmentedBlackLittermanPrior reduces its returns by the Investable Mask its asset prior answered, which is not the same mask the returns alone would give: a column can be quoted throughout the window and still be unestimable.
A copy and not a view, because the block goes on to a regression, and a SubArray of an open-eltype array is where the compiler stops inferring.
nothing is the all-covered path and returns the block untouched.
Arguments
A: The block to reduce,observations × assets.cmsk: The mask to keep, ornothing.
Returns
- The block over the kept columns.
Related
PortfolioOptimisers.expand_rows — Function
expand_rows(A::MatNum, cmsk::Nothing) -> A
expand_rows(A::MatNum, cmsk::BitVector) -> MatNumWrite a block whose rows are the asset axis back into a NaN frame of the full width.
This is expand_columns along the other axis. A loadings matrix is assets × factors, so it expands along its rows.
Arguments
A: The block that the reduced fit produced,assets × anything.cmsk: The Coverage Universe, ornothing.
Returns
- The block on the full asset universe, carrying
NaNoutside the Coverage Universe.
Related
PortfolioOptimisers.expand_vector — Function
expand_vector(v::VecNum, cmsk::Nothing) -> v
expand_vector(v::VecNum, cmsk::BitVector) -> VecNumWrite a per-asset vector back into a NaN frame of the full width.
This is expand_columns over one axis alone. A mean vector, an intercept vector and a per-asset idiosyncratic variance all take it.
Arguments
v: The per-asset vector that the reduced fit produced.cmsk: The Coverage Universe, ornothing.
Returns
- The vector on the full asset universe, carrying
NaNoutside the Coverage Universe.
Related
PortfolioOptimisers.expand_moment — Function
expand_moment(m, cmsk::Nothing) -> m
expand_moment(m, cmsk::Nothing, dims::Int) -> m
expand_moment(m, cmsk::Nothing, ::Val{:kt}) -> m
expand_moment(sigma::MatNum, cmsk::BitVector) -> MatNum
expand_moment(mu::VecNum, cmsk::BitVector, dims::Int) -> VecNum
expand_moment(mu::MatNum, cmsk::BitVector, dims::Int) -> MatNum
expand_moment(skV::Tuple{<:MatNum, <:MatNum}, cmsk::BitVector) -> Tuple{MatNum, MatNum}
expand_moment(kt::MatNum, cmsk::BitVector, ::Val{:kt}) -> MatNumWrite a moment estimated on the Coverage Universe back into a NaN frame of the full width.
A Prior Result lives on the full asset universe, and an asset that the prior could not estimate carries NaN, so every block a reduced fit produced is expanded before it is carried. This is the second half of the seam whose first half is coverage_reduction, and the nothing sentinel returns the argument untouched.
The four shapes need four methods, because their types do not separate them: a covariance matrix and a cokurtosis matrix are both square, and a mean and a coskewness tensor are both rectangular. The arity and the Val marker separate them instead.
Algorithm
The method that Julia selects is the algorithm.
- A
nothingmask returns the moment untouched, at every arity. - A covariance-like matrix,
assets × assets, is written at(cmsk, cmsk). - A marginal,
1 × assetsunderdims = 1andassets × 1underdims = 2, is written along its asset axis. - A coskewness pair expands its tensor at the rows
cmskand the pair columns ofcoverage_pair_index, and expands its negative spectral skewness matrix as a covariance-like matrix. - A cokurtosis matrix is written at the pair index on both axes.
Arguments
m,sigma,mu,skV,kt: The moment that the reduced fit produced.cmsk: The Coverage Universe, ornothing.dims: The dimension that the marginal was computed along.::Val{:kt}: The marker that names a cokurtosis matrix, which a covariance matrix cannot be told from by type.
Returns
- The moment on the full asset universe, carrying
NaNoutside the Coverage Universe.
Related
PortfolioOptimisers.expand_regression — Function
expand_regression(re, cmsk::Nothing) -> re
expand_regression(re::Regression, cmsk::BitVector) -> RegressionWrite a regression result fitted on the Coverage Universe back onto the full asset universe.
A Prior Result has no mask field, so every block it carries lives on the full asset universe, and the regression result it carries is one of those blocks. Its loadings, its intercepts and its idiosyncratic covariance are all per-asset, so all three expand along their asset axis.
L is read with getfield, as port_opt_view reads it: the swap(L, M) property rule makes re.L return re.M where L is unset, so an expanded result would materialise L as a copy of M and lose the unset-ness that the rule exists to express.
Arguments
re: The regression result the reduced fit produced.cmsk: The Coverage Universe, ornothing.
Returns
re::Regression: The regression result on the full asset universe.
Related
PortfolioOptimisers.expand_idiosyncratic_covariance — Function
expand_idiosyncratic_covariance(esigma::Nothing, cmsk) -> nothing
expand_idiosyncratic_covariance(esigma::VecNum, cmsk::BitVector) -> VecNum
expand_idiosyncratic_covariance(esigma::MatNum, cmsk::BitVector) -> MatNumExpand the idiosyncratic covariance a regression result carries, in either of the two shapes it takes.
The block is a per-asset variance vector where the residuals are taken as uncorrelated, and an assets × assets matrix where they are not. This is the expansion counterpart of idiosyncratic_covariance_view, which slices the same two shapes.
Arguments
esigma: The idiosyncratic covariance, ornothing.cmsk: The Coverage Universe.
Returns
esigma: The idiosyncratic covariance on the full asset universe.
Related
The refusal
PortfolioOptimisers.assert_finite_sample — Function
assert_finite_sample(X::ArrNum) -> nothingRefuse a non-finite sample in a plain moment estimator, and name the two ways out.
A plain moment estimator has no correct answer for an asset whose window carries a gap, so it refuses the whole sample rather than returning a number that reads as an estimate. The message names the two paths a caller has: fit through a prior, which reduces to the Coverage Universe and expands, or reach for a mask-aware estimator, which takes the whole window and emits its own frame.
This is assert_all_finite with the message that this refusal owes its caller. The generic message names the count and the position alone, which tells a caller what is wrong and not what to do about it.
Arguments
X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.
Validation
- Every entry of
Xmust be finite.
Returns
nothing.
Related
The roots of the seven verbs
PortfolioOptimisers.variance_series — Method
variance_series(
ce::AbstractCovarianceEstimator,
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
pnl::Union{Nothing, AssetPanel};
dims,
kwargs...
) -> Matrix
The point-in-time series root of the Asset Panel seam.
variance_series refits its estimator once per observation, so every window meets the refusal of assert_finite_sample on its own. A window is therefore reduced to its own Coverage Universe rather than to the sample's: an asset that lists inside the window is outside the Coverage Universe of every window that reaches back past its listing, and inside the Coverage Universe of none. That is one reduction per row, and it is what a point-in-time series of a gapped panel means.
A mask-aware estimator overrides this method and takes the whole window, as it overrides Statistics.cov(ce::AbstractCovarianceEstimator, X::MatNum, pnl::Option{<:AssetPanel}; dims::Int = 1, kwargs...).
Algorithm
- Orient
Xso that the observations lie on the rows. - Allocate a
NaNframe of the shape ofXwithcoverage_nan_frame. - For each observation
t, take the assets whose window is finite throughout and, when the Asset Panel carries an active mask, active throughout. - Fit the estimator on that block, and write the answer into the covered entries of row
t. An asset outside the window's Coverage Universe keeps itsNaN, and a window that covers no asset leaves the whole row atNaN. - Return the series, transposed when
dims == 2.
Arguments
ce: Covariance estimator.X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.pnl: OptionalAssetPanel, whose active mask the Coverage Universe of the fit is derived from.nothingmakes the rule finiteness alone.dims: Dimension along which to perform the computation.kwargs...: Additional keyword arguments passed to the estimator.
Validation
dims in (1, 2).
Returns
val::Matrix{<:Number}: Variance series on the full asset universe, shaped as(T, N)ifdims == 1or(N, T)ifdims == 2, carryingNaNoutside each window's Coverage Universe.
Related
The available-case seam
An estimator that carries a CoveragePolicy is a mask-aware estimator, so its panel method hands it the whole window and the panel's active mask instead of reducing to the Coverage Universe.
PortfolioOptimisers.coverage_panel_moment — Function
coverage_panel_moment(f, est, cvg, X, pnl, expand; dims::Int = 1, kwargs...)Routes a moment verb's Asset Panel method to the Coverage Universe seam or to the available-case one.
An estimator that carries a CoveragePolicy is a mask-aware estimator in the sense the covariance root of this file states: it takes the whole window and reads pnl.amsk itself, so the panel method must hand it the mask rather than reduce the window to its Coverage Universe. The cvg field is passed as the third argument, so the two seams are chosen by dispatch, and the Nothing method is the reduce-and-expand the root has always run.
expand is the framing the verb needs, because the four moment shapes frame differently: a covariance frames as a matrix, a marginal along its asset axis alone, and a co-moment at the pair index. It is passed rather than chosen here, so that this routing is written once for every verb.
Arguments
f: The plain, panel-free method of the verb.est: The estimator.cvg: The policy the estimator carries, which selects the seam.X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.pnl: OptionalAssetPanel, whose active mask the Coverage Universe of the fit is derived from.nothingmakes the rule finiteness alone.expand: The framing, called asexpand(val, cmsk)on the Coverage Universe seam and unused on the other.dims: Dimension along which to perform the computation.kwargs...: Additional keyword arguments passed to the estimator.
Returns
val: The moment on the full asset universe.
Related
PortfolioOptimisers.coverage_panel_moment — Method
coverage_panel_moment(
f,
est,
::Nothing,
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
pnl::Union{Nothing, AssetPanel},
expand;
dims,
kwargs...
) -> Any
Nothing method of coverage_panel_moment. The Coverage Universe seam: reduce the window with coverage_reduction, fit the plain estimator on the clean block, and frame the answer.
Related
PortfolioOptimisers.coverage_panel_moment — Method
coverage_panel_moment(
f,
est,
::CoveragePolicy,
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
pnl::Union{Nothing, AssetPanel},
;
dims,
kwargs...
) -> Any
CoveragePolicy method of coverage_panel_moment. The available-case seam: hand the estimator the whole window and the panel's active mask, and let it write its own frame.
Related
PortfolioOptimisers.coverage_variance_series — Function
coverage_variance_series(ce, cvg, X, pnl; dims::Int = 1, kwargs...) -> MatNumRoutes a point-in-time variance series to the Coverage Universe seam or to the available-case one.
The series counterpart of coverage_panel_moment, written apart from it because the series refits per observation and frames per row rather than once at the end.
Arguments
ce: Covariance estimator.cvg: The policy the estimator carries, which selects the seam.X: Data matrixobservations × assetsif thedimskeyword does not exist ordims = 1,assets × observationswhendims = 2.pnl: OptionalAssetPanel, whose active mask the Coverage Universe of the fit is derived from.nothingmakes the rule finiteness alone.dims: Dimension along which to perform the computation.kwargs...: Additional keyword arguments passed to the estimator.
Returns
val::Matrix{<:Number}: Variance series on the full asset universe.
Related
PortfolioOptimisers.coverage_variance_series — Method
coverage_variance_series(
ce::AbstractCovarianceEstimator,
::Nothing,
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
pnl::Union{Nothing, AssetPanel};
dims,
kwargs...
) -> Any
Nothing method of coverage_variance_series. The Coverage Universe seam: each window is reduced to its own Coverage Universe and the estimator is fitted on that block, which is the rule variance_series(ce::AbstractCovarianceEstimator, X::MatNum, pnl::Option{<:AssetPanel}; dims::Int = 1, kwargs...) states.
Related
PortfolioOptimisers.coverage_variance_series — Method
coverage_variance_series(
ce::AbstractCovarianceEstimator,
::CoveragePolicy,
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
pnl::Union{Nothing, AssetPanel};
dims,
kwargs...
) -> Any
CoveragePolicy method of coverage_variance_series. Each window is fitted available-case over the whole universe rather than reduced to its own Coverage Universe, so an asset that lists inside the window carries a number from its listing on instead of NaN throughout.
Algorithm
- Orient
X, and the panel's active mask, toobservations × assets. - For each observation
t, fit the estimator on the window1:twith the mask of those rows. - Write the answer into row
t, and return the series, transposed whendims == 2.
Related
PortfolioOptimisers.variance_series — Method
variance_series(
ce::Covariance,
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
pnl::Union{Nothing, AssetPanel};
dims,
kwargs...
) -> Any
Asset Panel method of variance_series for a Covariance, which routes on its cvg field with coverage_variance_series.
Related
PortfolioOptimisers.variance_series — Method
variance_series(
ve::SimpleVariance,
X::AbstractMatrix{<:Union{var"#s136", var"#s53"} where {var"#s136"<:Number, var"#s53"<:AbstractJuMPScalar}},
pnl::Union{Nothing, AssetPanel};
dims,
kwargs...
) -> Any
Asset Panel method of variance_series for a SimpleVariance, which routes on its cvg field with coverage_variance_series.
Related
PortfolioOptimisers.coverage_floor — Function
coverage_floor(cvg::Nothing)
coverage_floor(cvg::CoveragePolicy)
coverage_floor(me::AbstractExpectedReturnsEstimator)
coverage_floor(ce::StatsBase.CovarianceEstimator)
coverage_floor(me::SimpleExpectedReturns)
coverage_floor(ve::SimpleVariance)
coverage_floor(ce::Covariance)
coverage_floor(ce::PortfolioOptimisersCovariance)
coverage_floor(a::Nothing, b::Nothing)
coverage_floor(a::Nothing, b::Real)
coverage_floor(a::Real, b::Nothing)
coverage_floor(a::Real, b::Real)Read the coverage floor an estimator admits on, and take the binding one of two arms.
A CoveragePolicy is a field of one estimator, so the floor a fit admits on is not a property of the fit as a whole until someone reads it off the arms. The one-argument methods do that read: a carrier answers its own cvg, a wrapper forwards to the estimator it holds, and every other estimator answers nothing, which says that this arm states no floor rather than that it states a floor of zero. The two-argument method takes the maximum of two arms, because admission is their conjunction — the Investable Mask needs mu and the diagonal of sigma finite, and coverage_admission reads the same per-asset count for both — so a floor stated on either arm bounds every investable column whatever the other arm does.
The reader is resolve_fill_limit, which turns the floor into the share a scenario_fill may invent in silence. An estimator with no method answers nothing through its root's method, so a policy buried inside a wrapper this verb does not forward through names every fill rather than none: the conservative answer, and never a silence the caller did not ask for.
The two-argument methods are dispatch rather than a branch, so a call site holding two Options finds a method for every arm of its union split.
Arguments
cvg: ACoveragePolicyornothing.me,ve,ce: A moment estimator whose floor is being read.a,b: The floors of two arms, each aRealornothing.
Returns
floor::Option{<:Real}: The coverage floor, ornothingwhen none is stated.
Related
coverage_floor(pe::EmpiricalPrior) -> Any
EmpiricalPrior method of coverage_floor, the binding floor of its two arms.
pe.me and pe.ce may each carry a CoveragePolicy, and either bounds every investable column on its own, because the Investable Mask is the conjunction of the two admissions and both read the same per-asset observation count. The binding floor is therefore the maximum of the floors the arms state, and a mixed configuration needs no rule of its own.
Arguments
pe: The empirical prior estimator.
Returns
floor::Option{<:Real}: The binding coverage floor, ornothingwhen neither arm states one.
Related