The coverage policy

A moment estimator that carries a CoveragePolicy fits each cell of its answer on the observations that cell has, instead of reducing its window to the Coverage Universe. The rule for a delisted asset is an AbstractCoverageAlgorithm, whose two verbs are fold_inactive! at fold time and admits at read-out, and the per-cell denominators live in a PortfolioOptimisers.CoverageCounts the partial-fit state carries.

PortfolioOptimisers.CoveragePolicyType
struct CoveragePolicy{__T_min_coverage, __T_alg} <: AbstractEstimator

Fits each cell of a moment on the observations that cell has, instead of on the Coverage Universe.

The opt-in that replaces all-or-nothing coverage by available-case estimation. It is the cvg field of a moment estimator, it is nothing there by default, and the nothing arm is today's reduce-and-expand path read by dispatch, so a caller who asks for nothing pays nothing. With a policy set, every cell of the answer is fitted on the observations at which every asset of that cell is finite and active, each cell carries its own denominator, and an asset reaches the answer only where admits says so.

min_coverage is also the share a scenario_fill passes in silence. admits reads an asset's coverage share as its own observation count over the number of observations folded, and the fill counts that column's non-finite entries over the same denominator, so the two are complements and the admission test is the fill test. resolve_fill_limit derives 1 - min_coverage wherever a prior's fill_limit is nothing, which never fires: an admitted column satisfies it by construction. So turning a policy on does not turn a warning on, and an available-case walk-forward names nothing while it does what it was configured to do. The default min_coverage = 0 therefore admits a one-observation column and fills it in silence, which is what 0 asks for; a caller who wants to admit broadly and be told anyway states the prior's fill_limit explicitly, tighter than 1 - min_coverage.

Fields

  • min_coverage: min_coverage: Coverage floor, a share in [0, 1]. An asset whose own observation count over the number of observations folded falls below it is NaN in the answer. It is also the share a scenario_fill fills in silence, so the default of 0 fills a one-observation column and says nothing.
  • alg: alg: Coverage algorithm, the rule that decides what happens to a delisted asset.

Constructors

CoveragePolicy(;    min_coverage::Real = 0.0,    alg::AbstractCoverageAlgorithm = DecayCoverage()) -> CoveragePolicy

Keywords correspond to the struct's fields.

Validation

  • 0 <= min_coverage <= 1.

Examples

julia> CoveragePolicy(; min_coverage = 0.25)CoveragePolicy  min_coverage ┼ Float64: 0.25           alg ┴ DecayCoverage()

Related

source
PortfolioOptimisers.AbstractCoverageAlgorithmType
abstract type AbstractCoverageAlgorithm <: AbstractAlgorithm

Abstract supertype of the rules that decide what an available-case fit does with a delisted asset.

All concrete subtypes should subtype AbstractCoverageAlgorithm. The family is the alg field of a CoveragePolicy, and it exists because a delisting has no single right answer: one caller keeps the history until the asset leaves the frame, another throws it away so that a relisting starts cold, and a third holds the asset in the frame for a stated number of observations after it goes.

Interfaces

In order to implement a new concrete type that works seamlessly with the library, subtype AbstractCoverageAlgorithm and implement the following methods:

fold_inactive!

  • fold_inactive!(alg::AbstractCoverageAlgorithm, state::AbstractPartialFitState, ni::AbstractVector{<:Bool}) -> AbstractPartialFitState: The fold-time hook, called once per observation with the assets that have just become inactive.

Arguments

  • alg: The concrete subtype instance.
  • state: The partial-fit state being folded, mutated in place.
  • ni: One entry per asset, true where the asset was active at the previous observation and is inactive at this one.

Returns

  • state::AbstractPartialFitState: The state to fold the observation into.

admits

  • admits(alg::AbstractCoverageAlgorithm, share::Real, active::Bool, stale::Integer, min_coverage::Real) -> Bool: The read-out predicate, called once per asset.

Arguments

  • alg: The concrete subtype instance.
  • share: The asset's coverage share, its own observation count over the number of observations folded.
  • active: Whether the asset was active at the last observation.
  • stale: The number of observations folded since the asset was last finite and active.
  • min_coverage: The coverage floor of the policy.

Returns

  • admitted::Bool: Whether the asset appears in the answer, rather than as NaN.

Examples

julia> struct KeepEverything <: PortfolioOptimisers.AbstractCoverageAlgorithm endjulia> PortfolioOptimisers.admits(::KeepEverything, args...) = true;julia> PortfolioOptimisers.admits(KeepEverything(), 0.0, false, 99, 1.0)true

Related

source
PortfolioOptimisers.DecayCoverageType
struct DecayCoverage <: AbstractCoverageAlgorithm

Keeps a delisted asset's history, and drops the asset from the frame the moment it goes inactive.

This is the default rule, and the cheapest of the three, because it does nothing at fold time. It is also the one whose relisting resumes: an asset that lists, delists and lists again folds into the counts and accumulators it left behind rather than starting from zero.

Related

source
PortfolioOptimisers.ResetCoverageType
struct ResetCoverage <: AbstractCoverageAlgorithm

Throws a delisted asset's history away, so that a relisting starts the asset cold.

The reset zeroes the asset's counts and the row and column of every accumulator that touches it, which is what ExpWeightedCovariance already does for the exponentially weighted family. Use it when a relisted ticker is a different company, or when a corporate action makes the old series incomparable with the new one.

Related

source
PortfolioOptimisers.ExpireCoverageType
struct ExpireCoverage{__T_after} <: AbstractCoverageAlgorithm

Holds a delisted asset in the frame for a stated number of observations, then drops it.

The count is staleness, the number of observations folded since the asset was last finite and active, so a holiday spends it as freely as a delisting does and an asset that quotes again resets it to zero. after = 0 admits exactly what DecayCoverage admits: an asset that is inactive at an observation has its staleness raised by that observation, so no state a fold produces carries an inactive asset at staleness zero.

Fields

  • after: after: Number of observations an inactive asset stays in the frame for, counted from the last observation at which it was finite and active.

Constructors

ExpireCoverage(; after::Integer = 0) -> ExpireCoverage

Keywords correspond to the struct's fields.

Validation

  • after >= 0.

Examples

julia> ExpireCoverage(; after = 21)ExpireCoverage  after ┴ Int64: 21

Related

source
PortfolioOptimisers.fold_inactive!Function
fold_inactive!(alg, state, ni)

Applies a coverage algorithm's fold-time rule to the assets that have just become inactive.

The first of the two verbs of the AbstractCoverageAlgorithm interface. It runs once per observation, before the observation is folded, so a rule that throws history away runs while the state still holds the history to throw.

Arguments

  • alg: The coverage algorithm.
  • state: The partial-fit state, mutated in place.
  • ni: One entry per asset, true where the asset was active at the previous observation and is inactive at this one.

Returns

  • state: The state to fold the observation into.

Related

source
PortfolioOptimisers.admitsFunction
admits(alg, share, active, stale, min_coverage) -> Bool

Decides whether an asset reaches the answer of an available-case fit.

The second of the two verbs of the AbstractCoverageAlgorithm interface. It runs once per asset at read-out, and the assets it refuses are the NaN frame the read-out writes.

Arguments

  • alg: The coverage algorithm.
  • share: The asset's coverage share, its own observation count over the number of observations folded.
  • active: Whether the asset was active at the last observation.
  • stale: The number of observations folded since the asset was last finite and active.
  • min_coverage: The coverage floor of the CoveragePolicy.

Returns

  • admitted::Bool: Whether the asset reaches the answer.

Related

source