Realised factor attribution: private API

PortfolioOptimisers.ATTRIBUTION_CURRENCY_FAMILYConstant
const ATTRIBUTION_CURRENCY_FAMILY = "currency"

Family label whose rows carry no regression-estimation uncertainty.

A currency factor is a direct return rather than a coefficient the cross-sectional fit estimates, so the sandwich covariance says nothing about it. factor_attribution keeps such a row out of the Gram matrix and reports NaN for its standard error and for the standard error of its family.

Related

source
PortfolioOptimisers.attribution_sliceFunction
attribution_slice(B::MatNum, t::Integer)
attribution_slice(B::Arr3Num, t::Integer)

Return the exposure slice of one observation.

A block whose exposures do not move carries one matrix and answers it at every observation, and a block that keeps a history answers the slice. The shape is the dispatch, so the arithmetic above reads one name.

Arguments

  • B: The static loadings, or the exposure history.
  • t: The observation.

Returns

  • Bt::MatNum: The exposures of observation t, assets × factors.

Related

source
PortfolioOptimisers.attribution_weightsFunction
attribution_weights(w::VecNum, t::Integer)
attribution_weights(W::MatNum, t::Integer)

Return the portfolio weights of one observation.

A constant weight answers the same vector at every observation, and a weight history answers the row. The shape is the dispatch, so the arithmetic above reads one name.

Arguments

  • w: The constant weights, or the weight history.
  • t: The observation.

Returns

  • wt::VecNum: The weights of observation t.

Related

source
PortfolioOptimisers.attribution_covFunction
attribution_cov(x::VecNum, yc::VecNum)

Return the covariance of a series with a pre-centred series.

The portfolio series is centred once and reused by every covariance a realised attribution takes, which is what makes the components additive: the covariances of the parts with the whole sum to the variance of the whole.

Arguments

  • x: The series.
  • yc: The pre-centred series.

Returns

  • cv::Real: The covariance, with the corrected denominator.

Related

source
PortfolioOptimisers.attribution_alignFunction
attribution_align(rr::AbstractLoadingsRegressionResult, pr::AbstractPriorResult,
                  T::Integer)

Return the lag-aligned history a realised factor attribution reads off a factor model block.

The fit of observation t regresses the returns of t on the exposures of t - lag, so the exposures are trimmed at the tail and every return-like history at the head. A block whose exposures do not move keeps its one matrix, because a static slice needs no alignment.

A fit that warmed up on the first observations keeps fewer than the caller's series carries, so the two axes are lined up at their tail: the aligned history describes the last observations of the caller's series, and rows names them.

Arguments

  • rr: The factor model block.
  • pr: The prior result the block travels on, which carries the two return series of a block that stores none.
  • T: The number of observations the caller's return series carries.

Validation

  • The caller's series carries at least as many observations as the block, else a DimensionMismatch is raised.
  • The block carries more observations than the exposure lag, else a DimensionMismatch is raised.

Returns

  • B: The exposures, static or lag-aligned.
  • f::MatNum: The lag-aligned factor returns.
  • eps::MatNum: The lag-aligned idiosyncratic returns.
  • rw::Option{<:MatNum}: The lag-aligned regression weights, or nothing.
  • vs::Option{<:MatNum}: The lag-aligned idiosyncratic variances, or nothing.
  • fcb::Option{<:AbstractFactorFamilyBasis}: The family re-basis over the aligned axis, or nothing.
  • rows::UnitRange{Int}: The rows of the caller's series the aligned history describes.

Related

source
PortfolioOptimisers.attribution_trim_exposuresFunction
attribution_trim_exposures(B::MatNum, lag::Integer)
attribution_trim_exposures(B::Arr3Num, lag::Integer)

Return the exposure history trimmed at the tail by the lag.

A static loadings matrix describes every observation, so it is returned unchanged. A history is trimmed at the tail, which is the half of the alignment the exposures carry.

Arguments

  • B: The static loadings, or the exposure history.
  • lag: The exposure lag.

Returns

  • B: The static loadings, or the trimmed exposure history.

Related

source
PortfolioOptimisers.attribution_trim_rowsFunction
attribution_trim_rows(A::Nothing, rows)
attribution_trim_rows(A::MatNum, rows)

Return the rows of an optional per-observation history, or nothing.

The regression weights and the idiosyncratic variances are optional, so the absent case is a method rather than a test at the call site.

Arguments

  • A: The history, or nothing.
  • rows: The rows to keep.

Returns

  • A::Option{<:MatNum}: The kept rows, or nothing.

Related

source
PortfolioOptimisers.attribution_trim_basisFunction
attribution_trim_basis(fcb::Nothing, n::Integer)
attribution_trim_basis(fcb::FactorFamilyBasis, n::Integer)

Return the family re-basis over the aligned observation axis, or nothing.

The coefficients of observation t are coordinates in the basis of t - lag, so the basis follows the exposures and is sliced at the head of its own axis.

Arguments

  • fcb: The family re-basis, or nothing.
  • n: The number of aligned observations.

Returns

  • fcb::Option{<:FactorFamilyBasis}: The sliced basis, or nothing.

Related

source
PortfolioOptimisers.attribution_finite_rowsFunction
attribution_finite_rows(A::Nothing)
attribution_finite_rows(A::MatNum)

Return an optional per-observation history with every non-finite entry replaced by zero.

The pairing of attribution_finite with the absent case, so the regression weights and the idiosyncratic variances take the same treatment as the histories beside them without a test at the call site.

Arguments

  • A: The history, or nothing.

Returns

  • A::Option{<:MatNum}: The history with its non-finite entries replaced by zero, or nothing.

Related

source
PortfolioOptimisers.attribution_windowFunction
attribution_window(al::NamedTuple, rows)

Return the aligned history restricted to one rolling window.

The alignment runs once over the whole history, and a window is a slice of the aligned axis. Windowing before the alignment would spend the lag again inside every window.

Arguments

  • al: The aligned history.
  • rows: The rows of the aligned axis the window covers.

Returns

  • al::NamedTuple: The aligned history over the window.

Related

source
PortfolioOptimisers.attribution_window_exposuresFunction
attribution_window_exposures(B::MatNum, rows)
attribution_window_exposures(B::Arr3Num, rows)

Return the exposures of one rolling window.

A static loadings matrix describes every window, so it is returned unchanged.

Arguments

  • B: The static loadings, or the aligned exposure history.
  • rows: The rows the window covers.

Returns

  • B: The static loadings, or the exposures of the window.

Related

source
PortfolioOptimisers.attribution_window_weightsFunction
attribution_window_weights(w::VecNum, rows)
attribution_window_weights(W::MatNum, rows)

Return the portfolio weights of one rolling window.

A constant weight describes every window, so it is returned unchanged.

Arguments

  • w: The constant weights, or the weight history.
  • rows: The rows the window covers.

Returns

  • w: The constant weights, or the weights of the window.

Related

source
PortfolioOptimisers.attribution_weight_momentsFunction
attribution_weight_moments(w::VecNum, ::Integer)
attribution_weight_moments(W::MatNum, n::Integer)

Return the mean weight of each asset and the spread of its history.

A constant weight has no spread, so the spread is nothing and a reader dispatches on it rather than reading a vector of zeros.

Arguments

  • w: The constant weights, or the weight history.
  • n: The number of assets.

Returns

  • weight::VecNum: The mean weight of each asset.
  • weight_std::Option{<:VecNum}: The spread of each asset's weight, or nothing.

Related

source
PortfolioOptimisers.realised_attributionFunction
realised_attribution(W::VecNum_MatNum, ret::VecNum, al::NamedTuple,
                     fam::Option{<:VecStr}, assets::Bool, se::Bool, ppy::Number)
    -> FactorAttributionResult

Decompose one realised return series over the factors of an aligned factor model history.

The core of every realised method of factor_attribution and of every window of every rolling method. It assumes the alignment is done, so it reads the exposures, the factor returns and the idiosyncratic returns as they stand.

Algorithm

  1. Centre the portfolio series once, and take every covariance against it.
  2. Form the per-observation portfolio exposure g and the per-observation systematic and idiosyncratic series.
  3. Take each component's mean, volatility and covariance with the portfolio.
  4. Put the difference between the portfolio series and the model's reconstruction into the remainder.
  5. Sum the factor rows by family, and over the assets when assets = true.
  6. Scale by ppy.

Arguments

  • W: The constant weights, or the weight history.
  • ret: The net portfolio return series.
  • al: The aligned factor model history.
  • fam: The family label of each raw factor, or nothing.
  • assets: Whether to fill the asset axis and the asset-by-factor matrices.
  • se: Whether to fill the standard errors of the mean return contributions.
  • ppy: Periods per year the numbers are scaled to.

Validation

  • The portfolio volatility is positive, else a DomainError is raised.
  • ppy > 0, else a DomainError is raised.

Returns

  • fa::FactorAttributionResult: The attribution of the series.

Related

source
PortfolioOptimisers.attribution_series_componentFunction
attribution_series_component(pnl::VecNum, retc::VecNum, total_vol::Number,
                             sc::NamedTuple, mu_se) -> AttributionComponent

Return one component of a realised attribution from its own return series.

The systematic, the idiosyncratic and the unattributed series are decomposed alike, so one verb builds all three. The volatility contribution is the covariance with the portfolio over the portfolio volatility, which is what makes the three sum to the portfolio volatility exactly.

Arguments

  • pnl: The component's own return series.
  • retc: The centred portfolio return series.
  • total_vol: The portfolio volatility.
  • sc: The two annualisation factors.
  • mu_se: The standard error of the mean return contribution, or nothing.

Returns

  • c::AttributionComponent: The component.

Related

source
PortfolioOptimisers.attribution_family_spreadFunction
attribution_family_spread(fam::Nothing, g::MatNum)
attribution_family_spread(fam::VecStr, g::MatNum)

Return the spread of each family's portfolio exposure over the observations.

A family's exposure is the sum of the exposures of its factors, so its spread is the spread of that sum and not the sum of the spreads.

Arguments

  • fam: The family label of each raw factor, or nothing.
  • g: The per-observation portfolio exposure, observations × factors.

Returns

  • exposure_std::Option{<:VecNum}: The spread of each family's exposure, or nothing.

Related

source
PortfolioOptimisers.attribution_no_errorsFunction
attribution_no_errors()

Return the empty standard errors of an attribution that was not asked for them.

The three answers are nothing together, so a Result built without se = true carries nothing in every place a standard error would sit.

Returns

  • sys::Nothing: The systematic standard error.
  • factor::Nothing: The per-factor standard errors.
  • family::Nothing: The per-family standard errors.

Related

source
PortfolioOptimisers.attribution_standard_errorsFunction
attribution_standard_errors(g::MatNum, al::NamedTuple, fam::Option{<:VecStr},
                            s1::Number, T::Integer) -> NamedTuple

Return the standard errors of the mean return contributions of a realised attribution.

The cross-sectional fit estimates the factor returns of every observation, and that estimation error propagates into every mean return contribution. The error is the sandwich covariance of the fit, summed over the observations through the portfolio's own exposure.

Under a family re-basis the raw Gram matrix is singular by construction, so the sandwich is taken in the reduced full-rank basis and mapped back onto the raw axis for the per-factor and per-family answers. The systematic answer is invariant under the change of basis, so it is read in the reduced basis directly.

The systematic and the idiosyncratic errors are equal: the portfolio return is observed, so the two estimation errors sum to zero.

Mathematical definition

\[\begin{align} \operatorname{Var}(\hat{\boldsymbol{f}}_{t}) &= \mathbf{G}_{t}^{-1} \mathbf{B}_{t}^{\intercal} \mathbf{W}_{t} \boldsymbol{\Omega}_{t} \mathbf{W}_{t} \mathbf{B}_{t} \mathbf{G}_{t}^{-1}\,, \\ \mathbf{G}_{t} &= \mathbf{B}_{t}^{\intercal} \mathbf{W}_{t} \mathbf{B}_{t}\,, \\ \mathrm{SE} &= \frac{a}{T} \sqrt{\sum_{t=1}^{T} \boldsymbol{g}_{t}^{\intercal} \operatorname{Var}(\hat{\boldsymbol{f}}_{t}) \boldsymbol{g}_{t}}\,. \end{align}\]

Where:

  • $\mathbf{B}_{t}$: Exposure slice of observation $t$.
  • $\mathbf{W}_{t}$: Diagonal matrix of the regression weights of observation $t$.
  • $\boldsymbol{\Omega}_{t}$: Diagonal matrix of the idiosyncratic variances of observation $t$.
  • $\boldsymbol{g}_{t}$: Portfolio exposure of observation $t$.
  • $a$: Periods per year the numbers are scaled to.
  • $T$: Number of observations.

Arguments

  • g: The per-observation portfolio exposure on the raw axis, observations × factors.
  • al: The aligned factor model history.
  • fam: The family label of each raw factor, or nothing.
  • s1: The factor a mean takes under the annualisation.
  • T: The number of aligned observations.

Validation

  • al.rw and al.vs are not nothing, else an IsNothingError names the field.

Returns

  • sys::Real: The standard error of the systematic mean return contribution.
  • factor::VecNum: The standard error of each factor's mean return contribution.
  • family::Option{<:VecNum}: The standard error of each family's, or nothing.

Related

source
PortfolioOptimisers.attribution_reduce_for_errorsFunction
attribution_reduce_for_errors(fcb::Nothing, B, g::MatNum, fam, T::Integer)
attribution_reduce_for_errors(fcb::FactorFamilyBasis, B, g::MatNum, fam, T::Integer)

Return the exposures and the portfolio exposure the sandwich covariance is taken in.

A block that constrains no family is regressed on its raw axis, and the two answers pass through. A block that constrains a family has a singular raw Gram matrix, so the sandwich is taken in the reduced full-rank basis.

Arguments

  • fcb: The family re-basis, or nothing.
  • B: The static loadings, or the aligned exposure history.
  • g: The per-observation portfolio exposure on the raw axis.
  • fam: The family label of each raw factor, or nothing.
  • T: The number of aligned observations.

Returns

  • B::Arr3Num: The exposures of the regression basis, one slice per observation.
  • g::MatNum: The portfolio exposure in the regression basis.
  • currency::Vector{Bool}: Whether each column of the regression basis is a currency factor.
  • nr::Int: The number of columns of the regression basis.

Related

source
PortfolioOptimisers.attribution_broadcast_exposuresFunction
attribution_broadcast_exposures(B::MatNum, T::Integer)
attribution_broadcast_exposures(B::Arr3Num, T::Integer)

Return an exposure history of T slices, repeating a static loadings matrix.

The sandwich covariance runs per observation, and the basis transforms it reads take a history, so a static block is repeated once here rather than branched at every use.

Arguments

  • B: The static loadings, or the aligned exposure history.
  • T: The number of aligned observations.

Returns

  • Ms::Arr3Num: The exposure history, observations × assets × factors.

Related

source
PortfolioOptimisers.attribution_sandwichFunction
attribution_sandwich(Bt::MatNum, q::VecNum, s2::VecNum, keep::AbstractVector{<:Integer})

Return the sandwich covariance of the factor returns of one observation.

The fit of one observation is a weighted least squares across the assets, so the covariance of its coefficients is the sandwich of the Gram matrix around the weighted idiosyncratic variances. A rank-deficient Gram matrix falls back to the pseudo-inverse, which is the policy PseudoInverseFallback states and the rank test cross_sectional_rank applies, so the standard errors of a collinear cross-section are the minimum-norm answer rather than an arbitrarily large one.

Arguments

  • Bt: The exposures of the observation, assets × factors.
  • q: The regression weight of each asset at the observation.
  • s2: The idiosyncratic variance of each asset at the observation.
  • keep: The factors the regression estimates.

Returns

  • V::MatNum: The covariance of the estimated factor returns.

Related

source
PortfolioOptimisers.attribution_expand_errorsFunction
attribution_expand_errors(fcb::Nothing, V::MatNum, keep, nr::Integer, t::Integer)
attribution_expand_errors(fcb::FactorFamilyBasis, V::MatNum, keep, nr::Integer,
                          t::Integer)

Return the sandwich covariance of one observation on the raw factor axis.

The sandwich runs over the factors the regression estimates, so the answer is first scattered back into the full regression axis, and then, under a family re-basis, mapped from the reduced axis onto the raw one.

Arguments

  • fcb: The family re-basis, or nothing.
  • V: The covariance over the estimated factors.
  • keep: The factors the regression estimates.
  • nr: The number of columns of the regression basis.
  • t: The observation.

Returns

  • Vf::MatNum: The covariance on the raw factor axis.

Related

source
PortfolioOptimisers.attribution_scatterFunction
attribution_scatter(V::MatNum, keep, nr::Integer)

Return a covariance over a subset of factors, placed into a zero matrix of the full axis.

A factor the regression does not estimate carries no estimation uncertainty, so its row and its column are zero rather than absent.

Arguments

  • V: The covariance over the estimated factors.
  • keep: The factors the regression estimates.
  • nr: The number of factors of the full axis.

Returns

  • S::MatNum: The covariance on the full axis.

Related

source
PortfolioOptimisers.attribution_family_errorsFunction
attribution_family_errors(fam::Nothing, g::MatNum, Vf::AbstractVector{<:MatNum},
                          scale::Number, T::Integer)
attribution_family_errors(fam::VecStr, g::MatNum, Vf::AbstractVector{<:MatNum},
                          scale::Number, T::Integer)

Return the standard error of each family's mean return contribution.

A family's contribution sums the contributions of its factors, so its error reads the full covariance block of the family rather than the diagonal alone. The currency family reports NaN, because its rows carry no regression-estimation uncertainty.

Arguments

  • fam: The family label of each raw factor, or nothing.
  • g: The per-observation portfolio exposure on the raw axis.
  • Vf: The sandwich covariance of each observation, on the raw axis.
  • scale: The annualisation factor over the number of observations.
  • T: The number of aligned observations.

Returns

  • family::Option{<:VecNum}: The standard error of each family, or nothing.

Related

source
PortfolioOptimisers.realised_attribution_assetsFunction
realised_attribution_assets(assets::Bool, W::VecNum_MatNum, al::NamedTuple,
                            sysr::MatNum, retc::VecNum, total_vol::Number,
                            sc::NamedTuple)

Return the asset axis and the asset-by-factor matrices of a realised attribution.

Each asset's systematic and idiosyncratic contributions are the covariances of its own weighted series with the portfolio, so the rows sum to their components exactly. The axis decomposes the model, so vol_contrib is the two parts together and the rows sum to the systematic and idiosyncratic components together, not to the total: the remainder is a property of the portfolio and has no per-asset split. The asset-by-factor matrices split the systematic row of each asset over the factors.

Arguments

  • assets: Whether to compute the two answers at all.
  • W: The constant weights, or the weight history.
  • al: The aligned factor model history.
  • sysr: The per-observation systematic return of each asset.
  • retc: The centred portfolio return series.
  • total_vol: The portfolio volatility.
  • sc: The two annualisation factors.

Returns

  • abd::Option{<:AssetAttributionBreakdown}: The asset axis, or nothing.
  • afc::Option{<:AssetFactorContribution}: The asset-by-factor matrices, or nothing.

Related

source
PortfolioOptimisers.realised_attribution_asset_factorFunction
realised_attribution_asset_factor(W::VecNum_MatNum, al::NamedTuple, retc::VecNum,
                                  total_vol::Number, sc::NamedTuple, T::Integer,
                                  N::Integer, K::Integer) -> AssetFactorContribution

Return the asset-by-factor contributions of a realised attribution.

The series of the pair (i, k) is w_{t,i} B_{t,i,k} f_{t,k}, so its mean is the pair's mean return contribution and its covariance with the portfolio over the portfolio volatility is the pair's volatility contribution.

Arguments

  • W: The constant weights, or the weight history.
  • al: The aligned factor model history.
  • retc: The centred portfolio return series.
  • total_vol: The portfolio volatility.
  • sc: The two annualisation factors.
  • T: The number of aligned observations.
  • N: The number of assets.
  • K: The number of raw factors.

Returns

  • afc::AssetFactorContribution: The two asset-by-factor matrices.

Related

source
PortfolioOptimisers.attribution_rollingFunction
attribution_rolling(W::VecNum_MatNum, ret::VecNum, al::NamedTuple, fam, assets::Bool,
                    se::Bool, ppy::Number, window::Integer, step::Integer)
    -> Vector{<:FactorAttributionResult}

Roll a realised attribution over the windows of an aligned history.

The alignment runs once over the whole history, and each window is a slice of the aligned axis, so a window carries window effective observations and spends the exposure lag once rather than once per window. The windows end at window:step:T.

Arguments

  • W: The constant weights, or the weight history.
  • ret: The net portfolio return series, already aligned.
  • al: The aligned factor model history.
  • fam: The family label of each raw factor, or nothing.
  • assets: Whether to fill the asset axis and the asset-by-factor matrices.
  • se: Whether to fill the standard errors of the mean return contributions.
  • ppy: Periods per year the numbers are scaled to.
  • window: Size of the rolling window, in observations.
  • step: Stride between two consecutive windows.

Validation

  • 1 <= window <= T, else a DomainError is raised.
  • step >= 1, else a DomainError is raised.

Returns

  • fas::Vector{<:FactorAttributionResult}: One attribution per window.

Related

source
PortfolioOptimisers.attribution_net_returnsFunction
attribution_net_returns(w::VecNum, X::MatNum, fees::Option{<:Fees}, strict::Bool)

Return the net portfolio return series over the finite entries of the asset returns.

A point-in-time panel carries a NaN at every (observation, asset) pair where the asset is inactive: before it lists, after it delists, and at a non-investable asset's whole column. 0 * NaN is NaN, so a zero weight does not save the product X * w, and the series is formed over the finite entries instead.

A pair with a zero weight contributes nothing whatever it holds, and is never reported. A pair with a non-zero weight and a non-finite return is a holding with no return to earn, and it takes the library's strictness policy through strict_diagnostic: a warning names the observations and the assets and the pair contributes zero, or an ArgumentError names them under strict. Under a walk-forward the held pairs after a delisting carry a zero weight already, so the default is silent there.

Arguments

  • w: Portfolio weights.
  • X: Asset returns, observations × assets.
  • fees: Fees the net series is formed against, or nothing.
  • strict: Whether a non-finite return at a held pair raises rather than warns.

Validation

  • Every held pair of X is finite, else a warning naming the pairs is emitted, or an ArgumentError naming them is raised under strict.

Returns

  • ret::VecNum: The net portfolio return series, one entry per observation.

Related

source
PortfolioOptimisers.attribution_finite_seriesFunction
attribution_finite_series(ret::VecNum)

Refuse a portfolio return series that carries a non-finite value, naming the observations.

The methods that form the series themselves route a non-finite return through attribution_net_returns, so a NaN that reaches here came in the caller's own series or in a fold's. It is refused before the alignment, so the observations named are the caller's and not the aligned window's, and the refusal names the cause rather than the volatility it would poison.

Arguments

  • ret: The net portfolio return series.

Validation

  • ret is finite throughout, else an IsNonFiniteError naming the observations is raised.

Returns

  • Nothing is returned.

Related

source
PortfolioOptimisers.attribution_realised_entryFunction
attribution_realised_entry(W::VecNum_MatNum, pr::AbstractPriorResult, ret::VecNum;
                           assets::Bool = false, se::Bool = false, ppy::Number = 1,
                           strict::Bool = false)
    -> FactorAttributionResult

Align a factor model block against a realised return series and decompose it.

Every realised method of factor_attribution that is not rolling arrives here, having formed its net return series and its weights.

Arguments

  • W: The constant weights, or the weight history.
  • pr: Prior result carrying the factor model block.
  • ret: The net portfolio return series.
  • assets: Whether to fill the asset axis and the asset-by-factor matrices.
  • se: Whether to fill the standard errors of the mean return contributions.
  • ppy: Periods per year the numbers are scaled to.
  • strict: Whether a holding in a non-investable asset raises rather than warns.

Returns

  • fa::FactorAttributionResult: The attribution of the series.

Related

source
PortfolioOptimisers.attribution_rolling_entryFunction
attribution_rolling_entry(W::VecNum_MatNum, pr::AbstractPriorResult, ret::VecNum,
                          window::Integer; step::Integer = 1, assets::Bool = false,
                          se::Bool = false, ppy::Number = 1, strict::Bool = false)
    -> Vector{<:FactorAttributionResult}

Align a factor model block against a realised return series and roll the decomposition.

Every rolling method of factor_attribution arrives here, having formed its net return series and its weights.

Arguments

  • W: The constant weights, or the weight history.
  • pr: Prior result carrying the factor model block.
  • ret: The net portfolio return series.
  • window: Size of the rolling window, in observations.
  • step: Stride between two consecutive windows.
  • assets: Whether to fill the asset axis and the asset-by-factor matrices.
  • se: Whether to fill the standard errors of the mean return contributions.
  • ppy: Periods per year the numbers are scaled to.
  • strict: Whether a holding in a non-investable asset raises rather than warns.

Returns

  • fas::Vector{<:FactorAttributionResult}: One attribution per window.

Related

source
PortfolioOptimisers.attribution_prediction_historyFunction
attribution_prediction_history(pred::MultiPeriodPredictionResult)

Return the weight history and the net return series a cross-validation produced.

Each fold holds its own weights and its own net series, so the history is the folds stacked in order. A fold that recorded a Held Weights result carries its drifted path, and a fold that recorded none held its target weights for the whole fold.

Arguments

  • pred: A multi-period prediction result.

Returns

  • W::MatNum: The weight history, observations × assets.
  • ret::VecNum: The net portfolio return series.

Related

source