Cross-Sectional Calibration Rules

The rules that compute the two calibration slots of a CrossSectionalFactorPrior from its fit. A rule of the spanned shrinkage stands in lambda, and a rule of the orthogonal forecast scale stands in c. PrecisionBlend is the default of lambda, and c stays one unless the caller states ForecastCalibrationSlope.

PortfolioOptimisers.PrecisionBlend — Type
struct PrecisionBlend{__T_err} <: AbstractSpannedShrinkageCalibrationAlgorithm

Shrinks the factor mean towards the spanned part of a Return Forecast by the precision of each.

The fitted factor mean $\hat{\boldsymbol{\mu}}_{f}$ and the spanned part $\boldsymbol{g}$ are two estimates of the expected factor returns. The rule gives the factor mean a weight equal to the error of $\boldsymbol{g}$ over the sum of the two errors, so the estimate with the smaller error gets the larger weight. The sampling error of the factor mean, in the metric of the pseudo-inverse of the factor covariance, is $K / T_{e}$. The rule measures the error of $\boldsymbol{g}$ by its distance from the factor mean less that sampling error. That distance holds both errors, so the difference estimates the error of $\boldsymbol{g}$ alone, and the rule clips it at zero.

It is the default of the lambda slot of CrossSectionalFactorPrior. A prior that states no Return Forecast Estimator has $\boldsymbol{g} = \boldsymbol{0}$, and the rule then shrinks the factor mean towards zero, with a weight that falls as the mean becomes less distinct from zero. The rule takes no warm-up: on a short history the factor mean has its largest error, so a pull towards a weight of one is the wrong direction.

The form is that of the shrinkage of a sample mean towards a target in [44]: the weight of the target is the sampling error of the mean over the squared distance of the mean from the target. The rule estimates that ratio from the fit and takes its positive part.

Mathematical definition

\[\begin{align} B &= \frac{1}{n} \sum_{j=1}^{n} \left( \boldsymbol{g}_{j} - \hat{\boldsymbol{\mu}}_{f} \right)^{\intercal} \hat{\mathbf{\Sigma}}_{f}^{+} \left( \boldsymbol{g}_{j} - \hat{\boldsymbol{\mu}}_{f} \right)\,, \\ \lambda &= \frac{\max\left(B - K / T_{e},\, 0\right)}{K / T_{e} + \max\left(B - K / T_{e},\, 0\right)} = \max\left(0,\, 1 - \frac{K}{T_{e} B}\right)\,. \end{align}\]

Where:

  • $B$: Mean squared distance of the spanned coefficients from the factor mean, in the metric of the pseudo-inverse of the factor covariance.
  • $\boldsymbol{g}_{j}$: Spanned coefficients of row $j$ of the Return Forecast, which err chooses. Under CurrentForecastError there is one row, the latest.
  • $n$: Number of rows that err chooses.
  • $\hat{\boldsymbol{\mu}}_{f}$: Factor mean of the nested factor prior, over the estimated factors.
  • $\hat{\mathbf{\Sigma}}_{f}^{+}$: Pseudo-inverse of the factor covariance of the nested factor prior, over the estimated factors, as spanned_shrinkage_moments states it.
  • $\lambda$: Spanned Shrinkage, the weight of the factor mean.
  • $K$: Rank of the factor covariance over the estimated factors.
  • $T_{e}$: Effective sample size, which is Kish's when the observation weights are stated.

Fields

Constructors

PrecisionBlend(;    err::AbstractForecastErrorAlgorithm = CurrentForecastError()) -> PrecisionBlend

Keywords correspond to the struct's fields.

Examples

julia> PrecisionBlend().err isa CurrentForecastErrortrue

Related

References

  • [44] P. Jorion. Bayes-Stein estimation for portfolio analysis. The Journal of Financial and Quantitative Analysis 21, 279–292 (1986).
source
PortfolioOptimisers.SteinShrinkage — Type
struct SteinShrinkage{__T_alg} <: AbstractSpannedShrinkageCalibrationAlgorithm

Shrinks the factor mean towards the spanned part of a Return Forecast by the intensity of a shrunk expected-returns estimator.

The rule computes the shrinkage intensity of the algorithm in alg, with the spanned coefficients $\boldsymbol{g}$ as the target, and returns the weight of the factor mean. ShrunkExpectedReturns shrinks a sample mean towards a target that its own field tgt computes. This rule reads the same intensity with $\boldsymbol{g}$ in place of that target, so it ignores the tgt of the algorithm. With no Return Forecast Estimator, $\boldsymbol{g}$ is zero.

Each intensity is read off the factor mean and the factor covariance of the nested factor prior, over the estimated factors, and off the effective sample size. The factor covariance enters through its pseudo-inverse and its rank, as spanned_shrinkage_moments states. BayesStein gives a weight in [0, 1) with no clip, as in [44]. JamesStein can give an intensity outside [0, 1], and the rule clips it, which is the positive-part form of [42]. At two factors or fewer its intensity is not positive, so the rule keeps the factor mean. BodnarOkhrinParolya gives the weight of the sample mean and a separate scale of the target, as in [45]. The blend of the prior gives the target the weight that the sample mean leaves, so the rule returns the clipped weight of the sample mean and reads no scale of the target.

Mathematical definition

\[\begin{align} \boldsymbol{d} &= \hat{\boldsymbol{\mu}}_{f} - \boldsymbol{g}\,, \\ \lambda_{\mathrm{BS}} &= 1 - \frac{K + 2}{K + 2 + T_{e} \, \boldsymbol{d}^{\intercal} \hat{\mathbf{\Sigma}}_{f}^{+} \boldsymbol{d}}\,, \\ \lambda_{\mathrm{JS}} &= 1 - \min\left(\max\left(\frac{\sum_{i} \ell_{i} - 2 \, \ell_{\max}}{T_{e} \, \boldsymbol{d}^{\intercal} \boldsymbol{d}},\, 0\right),\, 1\right)\,, \\ \lambda_{\mathrm{BOP}} &= \min\left(\max\left(\frac{\left(u - K / (T_{e} - K)\right) v - s^{2}}{u v - s^{2}},\, 0\right),\, 1\right)\,. \end{align}\]

Where:

  • $\boldsymbol{d}$: Difference of the factor mean and the spanned coefficients.
  • $\hat{\boldsymbol{\mu}}_{f}$: Factor mean of the nested factor prior, over the estimated factors.
  • $\hat{\mathbf{\Sigma}}_{f}^{+}$: Pseudo-inverse of the factor covariance of the nested factor prior, over the estimated factors, as spanned_shrinkage_moments states it.
  • $\boldsymbol{g}$: Spanned coefficients of a Return Forecast, $K \times 1$, the coefficients of its regression on the latest Factor Exposures.
  • $\lambda_{\mathrm{BS}}$, $\lambda_{\mathrm{JS}}$, $\lambda_{\mathrm{BOP}}$: Spanned Shrinkage under BayesStein, JamesStein and BodnarOkhrinParolya.
  • $\ell_{i}$, $\ell_{\max}$: Kept eigenvalues of the factor covariance over the estimated factors, and the largest of them.
  • $u$, $v$, $s$: The quadratic forms $\hat{\boldsymbol{\mu}}_{f}^{\intercal} \hat{\mathbf{\Sigma}}_{f}^{+} \hat{\boldsymbol{\mu}}_{f}$, $\boldsymbol{g}^{\intercal} \hat{\mathbf{\Sigma}}_{f}^{+} \boldsymbol{g}$ and $\hat{\boldsymbol{\mu}}_{f}^{\intercal} \hat{\mathbf{\Sigma}}_{f}^{+} \boldsymbol{g}$.
  • $K$: Rank of the factor covariance over the estimated factors.
  • $T_{e}$: Effective sample size, which is Kish's when the observation weights are stated.

Fields

  • alg: The algorithm whose shrinkage intensity the rule reads, a member of AbstractShrunkExpectedReturnsAlgorithm. Its target tgt is not read: the target is the spanned part of the Return Forecast.

Constructors

SteinShrinkage(;    alg::AbstractShrunkExpectedReturnsAlgorithm = BayesStein()) -> SteinShrinkage

Keywords correspond to the struct's fields.

Examples

julia> SteinShrinkage().alg isa BayesSteintrue

Related

References

  • [44] P. Jorion. Bayes-Stein estimation for portfolio analysis. The Journal of Financial and Quantitative Analysis 21, 279–292 (1986).
  • [42] A. Meucci. Risk and Asset Allocation (Springer Berlin Heidelberg, 2005).
  • [45] T. Bodnar, O. Okhrin and N. Parolya. Optimal shrinkage estimator for high-dimensional mean vector. Journal of Multivariate Analysis 170, 63–79 (2019).
source
PortfolioOptimisers.ForecastCalibrationSlope — Type
struct ForecastCalibrationSlope{__T_wu, __T_target} <: AbstractOrthogonalForecastScaleCalibrationAlgorithm

Computes the Orthogonal Forecast Scale as the calibration slope of the orthogonal forecast on the forward idiosyncratic return.

The rule splits each row of the Return Forecast history against the Factor Exposures of that row, and pairs the orthogonal part of each asset with the idiosyncratic return of the asset at the next row. The slope of a weighted regression of the returns on the forecasts, through the origin, is the scale that maps the forecast onto the return it predicts. A scale of the orthogonal part with the least squared error is that slope, as the forecast refinement of [63] states. The rule clips the slope at zero and puts no upper bound on it, so a forecast whose magnitude is too small is scaled up.

The rule reads the history, so the prior makes it, and a prior whose rfe has no history refuses the rule at construction. The default c of CrossSectionalFactorPrior stays one, because a history of a fitted forecast is expensive, so a caller states this rule to take it.

Mathematical definition

\[\begin{align} \hat{c} &= \frac{\sum_{k} q_{k} a_{k} b_{k}}{\sum_{k} q_{k} a_{k}^{2}}\,, \\ \mathrm{se} &= \frac{\sqrt{\sum_{k} \left( q_{k} a_{k} \left( b_{k} - \hat{c} a_{k} \right) \right)^{2}}}{\sum_{k} q_{k} a_{k}^{2}}\,. \end{align}\]

Where:

  • $\hat{c}$: The calibration slope, before the warm-up form wu takes it.
  • $\mathrm{se}$: The heteroskedasticity-consistent standard error of the slope, the HC0 sandwich.
  • $a_{k}$: Orthogonal part of the forecast of the $k$-th pair, an asset at a row of the history before the latest.
  • $b_{k}$: Idiosyncratic return of the same asset at the next row. The rule pools no pair whose target is a Leverage-One Pair, as orthogonal_forecast_pairs states.
  • $q_{k}$: Regression weight of the same asset at the row of the forecast, zero where that weight is not finite.

Fields

  • target: The number that the rule falls back to under ThresholdWarmUp, and that it shrinks the slope towards under the two standard-error forms. It is finite and >= 0.

Constructors

ForecastCalibrationSlope(;    wu::AbstractForecastScaleWarmUpAlgorithm = ThresholdWarmUp(),    target::Number = 1) -> ForecastCalibrationSlope

Keywords correspond to the struct's fields.

Validation

  • target is finite and >= 0.

Examples

julia> ForecastCalibrationSlope().target1

Related

References

  • [63] R. C. Grinold and R. N. Kahn. Active Portfolio Management: A Quantitative Approach for Producing Superior Returns and Controlling Risk. 2 Edition (McGraw-Hill, New York, 1999).
source
PortfolioOptimisers.AbstractForecastErrorAlgorithm — Type
abstract type AbstractForecastErrorAlgorithm <: AbstractAlgorithm

Chooses the spanned coefficients whose distance from the factor mean measures the error of a Return Forecast.

PrecisionBlend holds a member of this family in its field err. The blend divides the sampling error of the factor mean by the sum of that error and the error of the spanned part g of the forecast. It measures the second error by the distance of g from the factor mean, and this family chooses the rows of g that it reads: the latest row alone, or the rows of the Return Forecast history.

Interfaces

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

spanned_forecast_sample

  • spanned_forecast_sample(err::MyForecastError, cs::NamedTuple) -> AbstractMatrix: Returns the spanned coefficients that the blend reads, one column per row of the forecast and one row per estimated factor.

Arguments

  • err: The member of the family.
  • cs: The fit of a CrossSectionalFactorPrior as (; g, ap, csfm, hist, cre), or nothing when the site names none. g holds the spanned coefficients of the Return Forecast, one per estimated factor, and ap its unscaled orthogonal part, one per asset; both are nothing when the prior states no Return Forecast Estimator. csfm is the CrossSectionalFactorModel block, with a zero b and no Return Forecast, which carries the idiosyncratic variance history vs and the regression weights rw. hist is the Return Forecast history from forecast_history, or nothing unless a slot answers true to reads_forecast_history. cre is the Cross-Sectional Regression Estimator of the prior, which splits a row of the history as the prior splits the latest forecast.

Returns

  • G::AbstractMatrix: The spanned coefficients, estimated factors × rows. Each column is finite.

A member whose method reads cs.hist also adds a method of reads_forecast_history that answers true, so the prior makes the history.

Related

source
PortfolioOptimisers.CurrentForecastError — Type
struct CurrentForecastError <: AbstractForecastErrorAlgorithm

Measures the error of the spanned part of a Return Forecast from its latest row alone.

PrecisionBlend with this member reads the spanned coefficients g that the prior blends, and nothing more, so it needs no Return Forecast history. With no Return Forecast Estimator, g is zero.

Examples

julia> PortfolioOptimisers.reads_forecast_history(CurrentForecastError())false

Related

source
PortfolioOptimisers.ForecastHistoryError — Type
struct ForecastHistoryError <: AbstractForecastErrorAlgorithm

Measures the error of the spanned part of a Return Forecast from the rows of its history.

PrecisionBlend with this member splits each row of the Return Forecast history against the Factor Exposures of that row, and averages the distance of each spanned part from the factor mean. The history ends at the latest observation, and the member reads the rows before it. A forecast that has no row before the latest gives the latest row alone, which is the reading of CurrentForecastError.

The member reads the history, so the prior makes it, and a prior whose rfe has no history refuses the member at construction.

Examples

julia> PortfolioOptimisers.reads_forecast_history(ForecastHistoryError())true

Related

source
PortfolioOptimisers.spanned_forecast_sample — Function
spanned_forecast_sample(err::CurrentForecastError, cs::NamedTuple) -> MatNum
spanned_forecast_sample(err::ForecastHistoryError, cs::NamedTuple) -> MatNum

Return the spanned coefficients of a Return Forecast that PrecisionBlend reads, one column per row.

Algorithm

  1. CurrentForecastError: take cs.g as the one column, or a zero column when the prior states no Return Forecast Estimator.
  2. ForecastHistoryError: split the Return Forecast history with cross_sectional_split_history, and keep the columns before the latest row whose coefficients are all finite. When no column is left, take the column of CurrentForecastError.

Arguments

  • err: The member of AbstractForecastErrorAlgorithm.
  • cs: The fit of a CrossSectionalFactorPrior as (; g, ap, csfm, hist, cre), or nothing when the site names none. g holds the spanned coefficients of the Return Forecast, one per estimated factor, and ap its unscaled orthogonal part, one per asset; both are nothing when the prior states no Return Forecast Estimator. csfm is the CrossSectionalFactorModel block, with a zero b and no Return Forecast, which carries the idiosyncratic variance history vs and the regression weights rw. hist is the Return Forecast history from forecast_history, or nothing unless a slot answers true to reads_forecast_history. cre is the Cross-Sectional Regression Estimator of the prior, which splits a row of the history as the prior splits the latest forecast.

Validation

Returns

  • G::MatNum: The spanned coefficients, estimated factors × rows.

Related

source
PortfolioOptimisers.AbstractForecastScaleWarmUpAlgorithm — Type
abstract type AbstractForecastScaleWarmUpAlgorithm <: AbstractAlgorithm

Chooses how the calibration slope of an orthogonal forecast reaches its target on a short history.

ForecastCalibrationSlope holds a member of this family in its field wu. The slope is noisy on a short history, so the member decides how much of it the rule takes, and how much of the number target that the rule falls back to. ThresholdWarmUp takes the target below a count of rows and the slope above it. PlugInWarmUp and PositivePartWarmUp shrink the slope towards the target by its standard error.

Interfaces

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

forecast_scale_warm_up

  • forecast_scale_warm_up(wu::MyForecastScaleWarmUp, c::Number, se::Number, n::Integer, target::Number) -> Number: Returns the Orthogonal Forecast Scale.

Arguments

  • wu: The member of the family.
  • c: The calibration slope. It is NaN when no pair has a positive weighted square.
  • se: The standard error of the slope.
  • n: Number of rows of the history that give at least one pair.
  • target: The number that the rule falls back to.

Returns

  • c::Number: The Orthogonal Forecast Scale, finite and >= 0.

Related

source
PortfolioOptimisers.ThresholdWarmUp — Type
struct ThresholdWarmUp{__T_min_obs} <: AbstractForecastScaleWarmUpAlgorithm

Takes the target below a count of history rows, and the calibration slope at or above it.

The slope is clipped at zero, and a slope that is not finite gives the target.

Fields

  • min_obs: Number of history rows, each with at least one pair, below which the rule takes the target.

Constructors

ThresholdWarmUp(;    min_obs::Integer = 252) -> ThresholdWarmUp

Keywords correspond to the struct's fields. The default is one year of daily rows.

Validation

  • min_obs > 0.

Examples

julia> ThresholdWarmUp().min_obs252

Related

source
PortfolioOptimisers.PlugInWarmUp — Type
struct PlugInWarmUp <: AbstractForecastScaleWarmUpAlgorithm

Shrinks the calibration slope towards the target by the plug-in weight of its standard error.

The weight of the slope is the squared distance of the slope from the target over the sum of that distance and the squared standard error. So a slope far from the target, measured in standard errors, keeps most of its value.

Mathematical definition

\[\begin{align} \delta &= \max\left(\hat{c},\, 0\right) - c_{0}\,, \\ c &= c_{0} + \frac{\delta^{2}}{\delta^{2} + \mathrm{se}^{2}} \, \delta\,. \end{align}\]

Where:

  • $\hat{c}$: The calibration slope.
  • $c_{0}$: The target of the rule.
  • $\mathrm{se}$: The standard error of the slope.
  • $c$: The Orthogonal Forecast Scale.

Examples

julia> PortfolioOptimisers.forecast_scale_warm_up(PlugInWarmUp(), 2.0, 1.0, 10, 1)1.5

Related

source
PortfolioOptimisers.PositivePartWarmUp — Type
struct PositivePartWarmUp <: AbstractForecastScaleWarmUpAlgorithm

Shrinks the calibration slope towards the target by the positive-part weight of its standard error.

The weight of the slope is one less the squared standard error over the squared distance of the slope from the target, clipped at zero. So a slope within one standard error of the target gives the target.

Mathematical definition

\[\begin{align} \delta &= \max\left(\hat{c},\, 0\right) - c_{0}\,, \\ c &= c_{0} + \max\left(0,\, 1 - \frac{\mathrm{se}^{2}}{\delta^{2}}\right) \delta\,. \end{align}\]

Where:

  • $\hat{c}$: The calibration slope.
  • $c_{0}$: The target of the rule.
  • $\mathrm{se}$: The standard error of the slope.
  • $c$: The Orthogonal Forecast Scale.

Examples

julia> PortfolioOptimisers.forecast_scale_warm_up(PositivePartWarmUp(), 3.0, 1.0, 10, 1)2.5

Related

source
PortfolioOptimisers.forecast_scale_warm_up — Function
forecast_scale_warm_up(wu::ThresholdWarmUp, c::Number, se::Number, n::Integer,
                       target::Number) -> Number
forecast_scale_warm_up(wu::PlugInWarmUp, c::Number, se::Number, n::Integer,
                       target::Number) -> Number
forecast_scale_warm_up(wu::PositivePartWarmUp, c::Number, se::Number, n::Integer,
                       target::Number) -> Number

Return the Orthogonal Forecast Scale that a warm-up form takes from a calibration slope and its target.

Each form clips the slope at zero first. A slope that is not finite gives the target in each form, and so does a standard error that is not finite in the two shrinkage forms. PlugInWarmUp and PositivePartWarmUp state their formulas.

Arguments

  • wu: The member of AbstractForecastScaleWarmUpAlgorithm.
  • c: The calibration slope.
  • se: The standard error of the slope.
  • n: Number of rows of the history that give at least one pair. Only ThresholdWarmUp reads it.
  • target: The number that the rule falls back to.

Returns

  • c::Number: The Orthogonal Forecast Scale.

Related

source

The two members of the systematic repair rule of a CrossSectionalFactorPrior, and the method that each one implements, are on this page too. The rule stands in srep.

PortfolioOptimisers.SystematicRepair — Type
struct SystematicRepair <: AbstractSystematicRepair

Repairs the systematic block before the lift of a CrossSectionalFactorPrior adds the idiosyncratic block.

The lift runs every step of mp on the systematic block in the order of mp.order, the :pdm step included, as factor_lift does. Then it adds the idiosyncratic block and repairs the sum under the estimator that matrix_processing_posdef gives for mp. The systematic block has rank at most $K$, so the :pdm step runs its full repair at each fit, and it moves the block by round-off alone.

Mathematical definition

\[\begin{align} \mathbf{\Sigma}_{\mathcal{I}\mathcal{I}} &= \operatorname{pdm}\left(\operatorname{mp}\left(\mathbf{B}_{T,\,\mathcal{I}} \odot \mathbf{F} \odot \mathbf{B}_{T,\,\mathcal{I}}^{\intercal}\right) + \mathbf{D}_{\mathcal{I}\mathcal{I}}\right)\,. \end{align}\]

Where:

  • $\mathbf{\Sigma}$: Asset covariance.
  • $\operatorname{mp}$: Every step of mp, in the order of mp.order.
  • $\operatorname{pdm}$: The repair under the estimator that matrix_processing_posdef gives for mp, from posdef!.
  • $\odot$: The product over the support of each row of loadings, from support_product.
  • $\mathbf{B}_{T,\,\mathcal{I}}$: The rows of $\mathbf{B}_{T}$ at the assets of $\mathcal{I}$.
  • $\mathbf{B}_{T}$: Latest Factor Exposures, $N \times K$, with entry $B_{Tik}$ for asset $i$ and factor $k$.
  • $\mathbf{F}$: Factor covariance, $K \times K$, the covariance of the factor distribution that the prior result carries.
  • $\mathbf{D}$: Covariance of the idiosyncratic returns that the loadings block carries, $N \times N$. It is diagonal when the block stores a variance vector.
  • $\mathcal{I}$: Investable set, the assets the prior states a finite moment for.

Constructors

SystematicRepair() -> SystematicRepair

Examples

julia> SystematicRepair()SystematicRepair()

Related

source
PortfolioOptimisers.NoSystematicRepair — Type
struct NoSystematicRepair <: AbstractSystematicRepair

Does not repair the systematic block before the lift of a CrossSectionalFactorPrior adds the idiosyncratic block. This is the default rule.

The lift runs every step of mp on the systematic block in the order of mp.order, except the :pdm step, and takes the symmetric part of the block. Then it adds the idiosyncratic block and repairs the sum under mp.pdm. That repair is the one repair of the asset covariance. A sum that is positive definite passes it unchanged, so the lift does no repair of a block that is positive semidefinite to round-off.

Mathematical definition

\[\begin{align} \mathbf{\Sigma}_{\mathcal{I}\mathcal{I}} &= \operatorname{pdm}\left(\operatorname{mp}_{\setminus\mathrm{pdm}}\left(\mathbf{B}_{T,\,\mathcal{I}} \odot \mathbf{F} \odot \mathbf{B}_{T,\,\mathcal{I}}^{\intercal}\right) + \mathbf{D}_{\mathcal{I}\mathcal{I}}\right)\,. \end{align}\]

Where:

  • $\mathbf{\Sigma}$: Asset covariance.
  • $\operatorname{mp}_{\setminus\mathrm{pdm}}$: Every step of mp except the :pdm step, in the order of mp.order, then the symmetric part of the block.
  • $\operatorname{pdm}$: The repair under mp.pdm, from posdef!.
  • $\odot$: The product over the support of each row of loadings, from support_product.
  • $\mathbf{B}_{T,\,\mathcal{I}}$: The rows of $\mathbf{B}_{T}$ at the assets of $\mathcal{I}$.
  • $\mathbf{B}_{T}$: Latest Factor Exposures, $N \times K$, with entry $B_{Tik}$ for asset $i$ and factor $k$.
  • $\mathbf{F}$: Factor covariance, $K \times K$, the covariance of the factor distribution that the prior result carries.
  • $\mathbf{D}$: Covariance of the idiosyncratic returns that the loadings block carries, $N \times N$. It is diagonal when the block stores a variance vector.
  • $\mathcal{I}$: Investable set, the assets the prior states a finite moment for.

Constructors

NoSystematicRepair() -> NoSystematicRepair

Examples

julia> NoSystematicRepair()NoSystematicRepair()

Related

source
PortfolioOptimisers.systematic_processing! — Function
systematic_processing!(srep::SystematicRepair, mp::AbstractMatrixProcessingEstimator,
                       sigma::MatNum, X::MatNum; kwargs...) -> MatNum
systematic_processing!(srep::NoSystematicRepair, mp::MatrixProcessing, sigma::MatNum,
                       X::MatNum; kwargs...) -> MatNum

Processes the systematic block of the lift of a CrossSectionalFactorPrior in place, under the Systematic Repair rule srep.

Algorithm

The method that Julia selects is the algorithm.

  1. SystematicRepair: run matrix_processing! of mp on sigma, every step included.
  2. NoSystematicRepair: run matrix_processing_step! for each step of mp.order except :pdm, in that order. Then replace sigma by its symmetric part $(\boldsymbol{\Sigma} + \boldsymbol{\Sigma}^{\intercal}) / 2$. The product of the loadings and the factor covariance is symmetric only to rounding, and posdef! accepts the sum without a repair only when it is exactly symmetric.

Arguments

  • srep: Systematic Repair rule of the lift, a member of AbstractSystematicRepair. NoSystematicRepair runs every step of mp on the systematic block except the :pdm step, and SystematicRepair runs every step. Under each rule the lift then adds the idiosyncratic block and repairs the sum under the estimator that matrix_processing_posdef gives for mp.
  • mp: Matrix processing estimator. NoSystematicRepair reads its steps one by one, so it takes a MatrixProcessing alone.
  • sigma: The systematic block, investable assets × investable assets.
  • X: The asset return scenarios of the investable assets, scenarios × investable assets.
  • kwargs...: Additional keyword arguments passed to the steps of mp.

Returns

  • sigma::MatNum: The systematic block, modified in place.

Related

source

The two members of the carry rule of a CrossSectionalFactorPrior are on this page too. The rule stands in carry.

PortfolioOptimisers.FoldOrRefit — Type
struct FoldOrRefit <: AbstractCarryRule

Folds each part of a CrossSectionalFactorPrior that has a fold, and fits every other part again at each step of the carry fold. This is the default Carry Rule.

The rule accepts every configuration. A part that does not fold, as carry_growing_parts lists it, is fitted again over every row that it reads, so the call with no data equals the batch fit over the folded observations. The cost of that refit grows with the stream:

  • A factor or a Return Forecast with no finite look-back makes the carry keep every panel row, so each step computes its Factor Exposures over every row.
  • A Return Forecast with no fold of its rows fits again over every row at each call with no data.
  • A ve that does not fold fits every idiosyncratic return again at each step.
  • A factor prior pe that does not fold fits every factor return again at each call with no data.
  • A BatchChoice with an automatic dropped member folds the factor prior again over every carried factor return at each step that moves the member.
  • The idiosyncratic correlation under th > 0 with a ce that does not fold is estimated again over every standardised idiosyncratic return at each call with no data. A ce that folds, as the default ExpWeightedCovariance does, folds the rows of each step.

FoldOnly refuses such a prior in its constructor instead.

Constructors

FoldOrRefit() -> FoldOrRefit

Examples

julia> FoldOrRefit()FoldOrRefit()

Related

source
PortfolioOptimisers.FoldOnly — Type
struct FoldOnly <: AbstractCarryRule

Accepts only a CrossSectionalFactorPrior whose every step of the carry fold has a cost that does not grow with the stream.

The constructor of the prior refuses a configuration that holds a part from carry_growing_parts, and names each such part and the method that it lacks. A bounded window passes: a factor whose Descriptors state a finite lookback makes the carry keep that many rows alone. On the configurations that the rule accepts, the carry fold runs the same step as under FoldOrRefit, so the call with no data equals the batch fit. A step where an Empty Factor comes alive folds the factor prior again over every carried factor return, at most once for each factor, as cross_sectional_step_factors states. The data decide that step and the configuration does not, so the rule does not refuse it.

Constructors

FoldOnly() -> FoldOnly

Examples

julia> FoldOnly()FoldOnly()

Related

source
PortfolioOptimisers.assert_carry_rule — Function
assert_carry_rule(carry::FoldOrRefit, cfg) -> nothing
assert_carry_rule(carry::FoldOnly, cfg) -> nothing

Applies the Carry Rule of a CrossSectionalFactorPrior to its configuration.

Algorithm

The method that Julia selects is the algorithm.

  1. FoldOrRefit accepts every configuration.
  2. FoldOnly refuses a configuration for which carry_growing_parts lists a part.

Arguments

  • carry: The Carry Rule of the prior.
  • cfg: The prior, or a NamedTuple of its fields factors, pe, ve, rfe, th, ce, choice and families.

Validation

  • Under FoldOnly, no part grows. Raises one ArgumentError that names every part that grows and the method that each part lacks.

Returns

  • nothing.

Related

source

References

[42]
A. Meucci. Risk and Asset Allocation (Springer Berlin Heidelberg, 2005).
[44]
P. Jorion. Bayes-Stein estimation for portfolio analysis. The Journal of Financial and Quantitative Analysis 21, 279–292 (1986).
[45]
T. Bodnar, O. Okhrin and N. Parolya. Optimal shrinkage estimator for high-dimensional mean vector. Journal of Multivariate Analysis 170, 63–79 (2019).
[63]
R. C. Grinold and R. N. Kahn. Active Portfolio Management: A Quantitative Approach for Producing Superior Returns and Controlling Risk. 2 Edition (McGraw-Hill, New York, 1999).