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} <: AbstractSpannedShrinkageCalibrationAlgorithmShrinks 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
errchooses. UnderCurrentForecastErrorthere is one row, the latest. - $n$: Number of rows that
errchooses. - $\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_momentsstates 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
err: The rows of the spanned part of the Return Forecast whose distance from the factor mean measures the error of the forecast, a member ofAbstractForecastErrorAlgorithm.CurrentForecastErrorreads the latest row, andForecastHistoryErrorreads the Return Forecast history.
Constructors
PrecisionBlend(; err::AbstractForecastErrorAlgorithm = CurrentForecastError()) -> PrecisionBlendKeywords correspond to the struct's fields.
Examples
julia> PrecisionBlend().err isa CurrentForecastErrortrueRelated
AbstractSpannedShrinkageCalibrationAlgorithmSteinShrinkage: the shrinkage intensity of an expected-returns estimator, towardsg.AbstractForecastErrorAlgorithmCrossSectionalFactorPriorcross_sectional_forecast_mu
References
- [44] P. Jorion. Bayes-Stein estimation for portfolio analysis. The Journal of Financial and Quantitative Analysis 21, 279–292 (1986).
PortfolioOptimisers.SteinShrinkage — Type
struct SteinShrinkage{__T_alg} <: AbstractSpannedShrinkageCalibrationAlgorithmShrinks 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_momentsstates 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,JamesSteinandBodnarOkhrinParolya. - $\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 ofAbstractShrunkExpectedReturnsAlgorithm. Its targettgtis not read: the target is the spanned part of the Return Forecast.
Constructors
SteinShrinkage(; alg::AbstractShrunkExpectedReturnsAlgorithm = BayesStein()) -> SteinShrinkageKeywords correspond to the struct's fields.
Examples
julia> SteinShrinkage().alg isa BayesSteintrueRelated
AbstractSpannedShrinkageCalibrationAlgorithmPrecisionBlend: the default rule of the slot.ShrunkExpectedReturnsstein_spanned_shrinkageCrossSectionalFactorPrior
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).
PortfolioOptimisers.ForecastCalibrationSlope — Type
struct ForecastCalibrationSlope{__T_wu, __T_target} <: AbstractOrthogonalForecastScaleCalibrationAlgorithmComputes 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
wutakes 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_pairsstates. - $q_{k}$: Regression weight of the same asset at the row of the forecast, zero where that weight is not finite.
Fields
wu: The warm-up form, a member ofAbstractForecastScaleWarmUpAlgorithm. It decides how much of the slope the rule takes on a short history.
target: The number that the rule falls back to underThresholdWarmUp, 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) -> ForecastCalibrationSlopeKeywords correspond to the struct's fields.
Validation
targetis finite and>= 0.
Examples
julia> ForecastCalibrationSlope().target1Related
AbstractOrthogonalForecastScaleCalibrationAlgorithmAbstractForecastScaleWarmUpAlgorithmforecast_calibration_slopeorthogonal_forecast_pairsCrossSectionalFactorPrior
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).
PortfolioOptimisers.AbstractForecastErrorAlgorithm — Type
abstract type AbstractForecastErrorAlgorithm <: AbstractAlgorithmChooses 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 aCrossSectionalFactorPrioras(; g, ap, csfm, hist, cre), ornothingwhen the site names none.gholds the spanned coefficients of the Return Forecast, one per estimated factor, andapits unscaled orthogonal part, one per asset; both arenothingwhen the prior states no Return Forecast Estimator.csfmis theCrossSectionalFactorModelblock, with a zeroband no Return Forecast, which carries the idiosyncratic variance historyvsand the regression weightsrw.histis the Return Forecast history fromforecast_history, ornothingunless a slot answerstruetoreads_forecast_history.creis 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
PortfolioOptimisers.CurrentForecastError — Type
struct CurrentForecastError <: AbstractForecastErrorAlgorithmMeasures 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())falseRelated
PortfolioOptimisers.ForecastHistoryError — Type
struct ForecastHistoryError <: AbstractForecastErrorAlgorithmMeasures 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())trueRelated
PortfolioOptimisers.spanned_forecast_sample — Function
spanned_forecast_sample(err::CurrentForecastError, cs::NamedTuple) -> MatNum
spanned_forecast_sample(err::ForecastHistoryError, cs::NamedTuple) -> MatNumReturn the spanned coefficients of a Return Forecast that PrecisionBlend reads, one column per row.
Algorithm
CurrentForecastError: takecs.gas the one column, or a zero column when the prior states no Return Forecast Estimator.ForecastHistoryError: split the Return Forecast history withcross_sectional_split_history, and keep the columns before the latest row whose coefficients are all finite. When no column is left, take the column ofCurrentForecastError.
Arguments
err: The member ofAbstractForecastErrorAlgorithm.cs: The fit of aCrossSectionalFactorPrioras(; g, ap, csfm, hist, cre), ornothingwhen the site names none.gholds the spanned coefficients of the Return Forecast, one per estimated factor, andapits unscaled orthogonal part, one per asset; both arenothingwhen the prior states no Return Forecast Estimator.csfmis theCrossSectionalFactorModelblock, with a zeroband no Return Forecast, which carries the idiosyncratic variance historyvsand the regression weightsrw.histis the Return Forecast history fromforecast_history, ornothingunless a slot answerstruetoreads_forecast_history.creis the Cross-Sectional Regression Estimator of the prior, which splits a row of the history as the prior splits the latest forecast.
Validation
- The rules of
cross_sectional_split_history, forForecastHistoryError.
Returns
G::MatNum: The spanned coefficients,estimated factors × rows.
Related
PortfolioOptimisers.AbstractForecastScaleWarmUpAlgorithm — Type
abstract type AbstractForecastScaleWarmUpAlgorithm <: AbstractAlgorithmChooses 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 isNaNwhen 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
PortfolioOptimisers.ThresholdWarmUp — Type
struct ThresholdWarmUp{__T_min_obs} <: AbstractForecastScaleWarmUpAlgorithmTakes 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) -> ThresholdWarmUpKeywords correspond to the struct's fields. The default is one year of daily rows.
Validation
min_obs > 0.
Examples
julia> ThresholdWarmUp().min_obs252Related
PortfolioOptimisers.PlugInWarmUp — Type
struct PlugInWarmUp <: AbstractForecastScaleWarmUpAlgorithmShrinks 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.5Related
PortfolioOptimisers.PositivePartWarmUp — Type
struct PositivePartWarmUp <: AbstractForecastScaleWarmUpAlgorithmShrinks 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.5Related
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) -> NumberReturn 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 ofAbstractForecastScaleWarmUpAlgorithm.c: The calibration slope.se: The standard error of the slope.n: Number of rows of the history that give at least one pair. OnlyThresholdWarmUpreads it.target: The number that the rule falls back to.
Returns
c::Number: The Orthogonal Forecast Scale.
Related
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 <: AbstractSystematicRepairRepairs 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 ofmp.order. - $\operatorname{pdm}$: The repair under the estimator that
matrix_processing_posdefgives formp, fromposdef!. - $\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() -> SystematicRepairExamples
julia> SystematicRepair()SystematicRepair()Related
PortfolioOptimisers.NoSystematicRepair — Type
struct NoSystematicRepair <: AbstractSystematicRepairDoes 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
mpexcept the:pdmstep, in the order ofmp.order, then the symmetric part of the block. - $\operatorname{pdm}$: The repair under
mp.pdm, fromposdef!. - $\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() -> NoSystematicRepairExamples
julia> NoSystematicRepair()NoSystematicRepair()Related
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...) -> MatNumProcesses 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.
SystematicRepair: runmatrix_processing!ofmponsigma, every step included.NoSystematicRepair: runmatrix_processing_step!for each step ofmp.orderexcept:pdm, in that order. Then replacesigmaby its symmetric part $(\boldsymbol{\Sigma} + \boldsymbol{\Sigma}^{\intercal}) / 2$. The product of the loadings and the factor covariance is symmetric only to rounding, andposdef!accepts the sum without a repair only when it is exactly symmetric.
Arguments
srep: Systematic Repair rule of the lift, a member ofAbstractSystematicRepair.NoSystematicRepairruns every step ofmpon the systematic block except the:pdmstep, andSystematicRepairruns every step. Under each rule the lift then adds the idiosyncratic block and repairs the sum under the estimator thatmatrix_processing_posdefgives formp.mp: Matrix processing estimator.NoSystematicRepairreads its steps one by one, so it takes aMatrixProcessingalone.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 ofmp.
Returns
sigma::MatNum: The systematic block, modified in place.
Related
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 <: AbstractCarryRuleFolds 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
vethat does not fold fits every idiosyncratic return again at each step. - A factor prior
pethat does not fold fits every factor return again at each call with no data. - A
BatchChoicewith 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 > 0with acethat does not fold is estimated again over every standardised idiosyncratic return at each call with no data. Acethat folds, as the defaultExpWeightedCovariancedoes, folds the rows of each step.
FoldOnly refuses such a prior in its constructor instead.
Constructors
FoldOrRefit() -> FoldOrRefitExamples
julia> FoldOrRefit()FoldOrRefit()Related
PortfolioOptimisers.FoldOnly — Type
struct FoldOnly <: AbstractCarryRuleAccepts 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() -> FoldOnlyExamples
julia> FoldOnly()FoldOnly()Related
PortfolioOptimisers.assert_carry_rule — Function
assert_carry_rule(carry::FoldOrRefit, cfg) -> nothing
assert_carry_rule(carry::FoldOnly, cfg) -> nothingApplies the Carry Rule of a CrossSectionalFactorPrior to its configuration.
Algorithm
The method that Julia selects is the algorithm.
FoldOrRefitaccepts every configuration.FoldOnlyrefuses a configuration for whichcarry_growing_partslists a part.
Arguments
carry: The Carry Rule of the prior.cfg: The prior, or aNamedTupleof its fieldsfactors,pe,ve,rfe,th,ce,choiceandfamilies.
Validation
- Under
FoldOnly, no part grows. Raises oneArgumentErrorthat names every part that grows and the method that each part lacks.
Returns
nothing.
Related
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).