Cross-Sectional Exposure IC

Types

PortfolioOptimisers.ExposureICSummaryResult — Type
struct ExposureICSummaryResult{__T_mean_ic, __T_std_ic, __T_ic_ir, __T_t_stat, __T_p_value, __T_mean_ci_lower, __T_mean_ci_upper, __T_hit_rate, __T_nf, __T_fam} <: AbstractResult

Holds the summary of an information coefficient series per factor, with the names and the families of the factors.

exposure_ic_summary returns it when it reads a FactorDiagnosticResult or a block. The method over a bare matrix returns a NamedTuple of the same eight vectors, and a caller reads a field of either by the same name. port_opt_view selects the factors of the summary by position, by name, or by family with a LabelGroup.

Fields

  • mean_ic: Mean of the information coefficient over the observations at which it is finite, one entry per factor.
  • std_ic: Standard deviation of the information coefficient over the same observations, one entry per factor.
  • ic_ir: Information ratio, the mean over the standard deviation, one entry per factor.
  • t_stat: T-statistic of the mean, with a long-run standard error, one entry per factor.
  • p_value: Two-sided p-value of the null hypothesis that the mean is zero, one entry per factor.
  • mean_ci_lower: Lower bound of the confidence interval of the mean at the level of the Mean Test, one entry per factor.
  • mean_ci_upper: Upper bound of the confidence interval of the mean at the level of the Mean Test, one entry per factor.
  • hit_rate: Fraction of the same observations at which the information coefficient is positive, one entry per factor.
  • nf: Name of each factor on the factor axis of the answer, or nothing when the block names no factor. The axis is the one that the verb answers on, raw or reduced.
  • fam: Family label of each factor on the factor axis of the answer, or nothing when the block labels no family. A view selects the factors of one family with a LabelGroup.

Constructors

ExposureICSummaryResult(    mean_ic, std_ic, ic_ir, t_stat, p_value, mean_ci_lower, mean_ci_upper,    hit_rate, nf, fam) -> ExposureICSummaryResult

The arguments are the fields, in the order of their declaration. The type is a Result, so exposure_ic_summary builds it and a caller reads it. It has no keyword constructor, and it checks none of its values.

Related

source

Functions

PortfolioOptimisers.exposure_ic — Function
exposure_ic(B::Arr3Num, R::MatNum, w::Option{<:MatNum} = nothing;
            horizon::Integer = 1, rank::Bool = true,
            ties::Symbol = :average) -> Matrix{<:Real}
exposure_ic(csfm::CrossSectionalFactorModel, rd::Option{<:ReturnsResult} = nothing;
            horizon::Integer = 1, rank::Bool = true, reduced::Bool = false,
            ties::Symbol = :average) -> FactorDiagnosticResult

Return the information coefficient of every factor exposure, one row per pair of observations.

The information coefficient is the cross-sectional correlation between the exposure known at an observation and the mean asset return over the observations that follow it. It scores the exposure as a forecast of the return.

A risk factor with an information coefficient near zero is not a bad risk factor. The purpose of a risk factor is to explain the covariance and not to predict the mean, so read exposure_stability and the variance the factor contributes before you judge one, and never the information coefficient alone.

The block method reads rw for the weights of the Pearson form, and answers on the raw factor axis. reduced maps the exposures through the family re-basis of the block first, and then the answer is on the reduced axis. Without rd, it reconstructs the asset returns as $\mathbf{B}_{t-\ell} \boldsymbol{f}_{t} + \boldsymbol{\varepsilon}_{t}$. The reconstruction reads every factor of an asset, so an exposure that is not finite on one factor makes the return of that asset NaN, and the asset leaves the score of every factor. One sparse factor can thus blank the coefficient of every other factor. With rd, the method scores each factor against the asset returns rd.X on the rows of the block, so each factor reads every asset whose own exposure and forward return are finite. The form with rd reads no fit, and it scores the first $\ell - 1$ rows of the block too, which the reconstruction trims. On every cell that the fit regressed, the reconstruction gives back rd.X, the part the observed factors carry included, unless the CrossSectionalFactorPrior read named net returns under its lx. So the two forms read the same return wherever the reconstruction is finite, and they differ only by the assets that the reconstruction loses.

Mathematical definition

\[\begin{align} \mathrm{IC}_{tk} &= \rho \left( \mathbf{B}_{t \cdot k}, \boldsymbol{y}_{t}, \boldsymbol{u}_{t} \right)\,. \end{align}\]

Where:

  • $\mathrm{IC}_{tk}$: Information coefficient of factor $k$ at observation $t$.
  • $\mathbf{B}_{t \cdot k}$: Exposure cross-section of factor $k$ at observation $t$.
  • $\boldsymbol{y}_{t}$: Forward mean asset return of observation $t$, over the finite returns of the $H$ observations that follow it. exposure_forward_mean_return defines it.
  • $\boldsymbol{u}_{t}$: Cross-sectional weights of observation $t$.
  • $\rho$: The rank correlation of cs_spearman_correlation when rank, which reads no weight, and the weighted correlation of cs_weighted_correlation otherwise.
  • $H$: Forward window, in observations.

A one-hot exposure, such as an industry, is a block of 0 and a block of 1, so every asset of it is in a tie. Under the default ties = :average, its rank coefficient compares the forward returns of the two blocks. Under ties = :ordinal, the order of the assets inside each block sets most of it.

Algorithm

  1. Resolve the weight history with exposure_weights.
  2. Build the forward mean return with exposure_forward_mean_return.
  3. Correlate each exposure against it, one observation at a time, with cs_spearman_correlation when rank and cs_weighted_correlation otherwise.

Arguments

  • B: Exposure history observations × assets × factors, unlagged.
  • R: Asset return history observations × assets, on the observation axis of B.
  • w: Cross-sectional weight history observations × assets, or nothing for equal weights. The rank form reads no weights.
  • horizon: Forward window, in observations.
  • rank: Take the rank correlation when true, and the weighted correlation otherwise.
  • csfm: A cross-sectional factor model block.
  • rd: The returns data that the prior read, or nothing to reconstruct the asset returns from the fit of the block. exposure_ic_returns takes the rows of the block from it.
  • reduced: Map the exposures through the family re-basis of the block before the correlation.
  • ties: Rule that ranks the equal values of a cross-section. :average gives each value of a tie the mean of the positions the tie takes, so a rank correlation does not read the order of the assets, and a constant cross-section has no rank correlation. :ordinal gives the values of a tie consecutive positions, in the order of the asset axis. The two rules give the same ranks to a cross-section with no tie. The weighted correlation reads no rank, so it ignores ties.

Validation

  • !isempty(B).
  • size(R) == (size(B, 1), size(B, 2)).
  • horizon >= 1 and size(B, 1) > horizon.
  • csfm.Ms is not nothing, and without rd neither is csfm.csr. Otherwise the verb raises an IsNothingError that names the field.
  • With rd, the rules of exposure_ic_returns.
  • The rules of cs_ranks, when rank.

Returns

  • ic::Matrix{<:Real}: (observations - horizon) × factors, on the method over histories. Row t scores the exposures of observation t against the returns that follow it.
  • r::FactorDiagnosticResult: On the block method, the same matrix in X, with the names and the family labels of its factor axis: the raw axis, or under reduced the whole reduced axis that cs_diagnostic_factor_names maps with two arguments. With rd, its rows are the rows of the block. Without it, they start at row $\max(1, \ell)$ of the block, as exposure_ic_data states. The block method returned the bare matrix in earlier releases, so a caller that indexed it now reads r.X.

Related

source
PortfolioOptimisers.exposure_ic_summary — Function
exposure_ic_summary(ic::MatNum; lags::Integer = 0, window::Real = lags + 1,
                    mt::AbstractMeanTestEstimator = WildBootstrapMeanTest()) -> NamedTuple
exposure_ic_summary(ic::FactorDiagnosticResult; lags::Integer = 0,
                    window::Real = lags + 1,
                    mt::AbstractMeanTestEstimator = WildBootstrapMeanTest()) -> ExposureICSummaryResult
exposure_ic_summary(csfm::CrossSectionalFactorModel,
                    rd::Option{<:ReturnsResult} = nothing; horizon::Integer = 1,
                    rank::Bool = true, reduced::Bool = false,
                    ties::Symbol = :average,
                    mt::AbstractMeanTestEstimator = WildBootstrapMeanTest()) -> ExposureICSummaryResult

Return the summary of an information coefficient series, one entry per factor.

The mean states the average score, the standard deviation states how much the score moves, and their ratio states the score per unit of movement. The t-statistic, the p-value and the confidence interval of the mean state whether the mean is far enough from zero to believe over the observations that carried a score, and the hit rate states how often the score was positive. All eight read the observations that carried a score. An observation whose score is NaN is one at which nothing was measured, not a miss, so it is in no denominator here, as it is in none of the library's other summaries. The coverage of the series answers the separate question of how often the series had no score.

The Mean Test mt gives the t-statistic, the p-value and the interval, as exposure_ic_factor_summary states. The function resolves the generator of the test once, so a seeded test is reproducible and the factors take different draws. exposure_ic scores every observation against a window of horizon observations, so each row shares returns with the horizon - 1 rows on each side of it, and the block method derives lags as horizon - 1. The bare method takes lags from the caller. Its default of 0 is the independent case, which is the case of a series scored at a stride of its window. Only OverlapMeanTest reads lags.

Mathematical definition

\[\begin{align} \overline{\mathrm{IC}}_{k} &= \frac{1}{|\mathcal{T}_{k}|} \sum_{t \in \mathcal{T}_{k}} \mathrm{IC}_{tk}\,, \\ s_{k}^{2} &= \frac{1}{|\mathcal{T}_{k}| - 1} \sum_{t \in \mathcal{T}_{k}} \left( \mathrm{IC}_{tk} - \overline{\mathrm{IC}}_{k} \right)^{2}\,, \\ \mathrm{IR}_{k} &= \frac{\overline{\mathrm{IC}}_{k}}{s_{k}}\,, \\ t_{k} &= \frac{\overline{\mathrm{IC}}_{k}}{\sigma_{k}} \sqrt{\left| \mathcal{T}_{k} \right|}\,, \\ \mathrm{hit}_{k} &= \frac{1}{|\mathcal{T}_{k}|} \sum_{t \in \mathcal{T}_{k}} \mathbb{1}\left[\mathrm{IC}_{tk} > 0\right]\,. \end{align}\]

Where:

  • $\mathrm{IC}_{tk}$: Information coefficient of factor $k$ at observation $t$.
  • $\mathcal{T}_{k}$: The observations at which it is finite.
  • $\overline{\mathrm{IC}}_{k}$: Its mean over $\mathcal{T}_{k}$.
  • $s_{k}$: Its standard deviation over $\mathcal{T}_{k}$.
  • $\mathrm{IR}_{k}$: Its information ratio.
  • $\sigma_{k}$: Its long-run standard deviation over $\mathcal{T}_{k}$, which the Mean Test mt defines.
  • $t_{k}$: Its t-statistic. The p-value of mt reads it.
  • $\mathrm{hit}_{k}$: Its hit rate.

Arguments

  • ic: Information coefficient series pairs × factors, or the FactorDiagnosticResult of exposure_ic, whose labels the answer keeps.
  • lags: Number of rows on each side of a given row whose windows overlap it. It is one less than the number of rows a forward window spans, horizon - 1 for a series scored at every observation.
  • window: Number of rows that one forward window spans, lags + 1 by default.
  • mt: The Mean Test of the t-statistic, the p-value and the interval.
  • csfm: A cross-sectional factor model block.
  • rd: The returns data that the prior read, or nothing to reconstruct the asset returns from the fit of the block. exposure_ic states how each form reads the returns.
  • horizon: Forward window, in observations.
  • rank: Take the rank correlation when true, and the weighted correlation otherwise.
  • reduced: Map the exposures through the family re-basis of the block before the correlation.
  • ties: Rule that ranks the equal values of a cross-section. :average gives each value of a tie the mean of the positions the tie takes, so a rank correlation does not read the order of the assets, and a constant cross-section has no rank correlation. :ordinal gives the values of a tie consecutive positions, in the order of the asset axis. The two rules give the same ranks to a cross-section with no tie. The weighted correlation reads no rank, so it ignores ties.

Validation

Returns

  • summary::NamedTuple: (; mean_ic, std_ic, ic_ir, t_stat, p_value, mean_ci_lower, mean_ci_upper, hit_rate), each one entry per factor, on the method over a matrix.
  • s::ExposureICSummaryResult: On the other two methods, the same eight vectors, with the names and the family labels of the factor axis of the series. The block method returned the NamedTuple in earlier releases, and a field of the Result has the name of the field of the NamedTuple.

Related

source
PortfolioOptimisers.port_opt_view — Method
port_opt_view(s::ExposureICSummaryResult, i, args...)

Return a view of an ExposureICSummaryResult that keeps only the factors that i selects.

Algorithm

  1. Cut every field to the selected factors with factor_table_fields.
  2. Build a new ExposureICSummaryResult from the views.

Arguments

  • s: A summary of an information coefficient series.
  • i: The factor index: positions, a range, a Colon, a vector of names, or a LabelGroup.
  • args...: Additional positional arguments (ignored).

Validation

Returns

  • s::ExposureICSummaryResult: The summary of the selected factors.

Related

source