Class FactorRiskModel

java.lang.Object
com.quantfinlib.risk.FactorRiskModel

public final class FactorRiskModel extends Object
Fundamental equity factor risk model in the Barra USE4 style: a market factor, one dummy factor per sector and standardised style factors, estimated by weighted cross-sectional regression each period.

Model. For period t and name i, r_it = f_mkt,t + f_sec(i),t + Σ_k x_ikt f_kt + u_it. The forecast covariance of the names is V = X F Xᵀ + D, with X the exposures at the forecast date, F the factor covariance and D the diagonal of specific variances.

Inputs and timing. returns[t][i] is the simple return of name i over period t. styles[t][k][i] and caps[t][i] are known at the start of period t. A name takes part in period t when its return is finite and its capitalisation is finite and positive. When styles and caps carry one more row than returns, that last row is the forecast date (exposures known today, for the period ahead); otherwise the forecast uses the last estimation row.

Style standardisation (Menchero, Orr and Wang 2011, "The Barra US Equity Model (USE4), Methodology Notes", §3): per period, subtract the capitalisation-weighted mean and divide by the equal-weighted standard deviation, clip at ±winsorLimit, then re-centre and re-scale the clipped values once. A missing raw exposure of a participating name is set to 0, the cap-weighted mean.

Factor returns. Weighted least squares with regression weights √cap_i (heteroskedasticity of specific returns falls with size). The sector dummies sum to the market column, so the system is singular; following Menchero (2010, "The Characteristics of Factor Portfolios", J. Performance Measurement 15(1)) the constraint Σ_s c_s f_s = 0 with c_s the sector's capitalisation share is imposed. It is solved exactly by substituting f_S = −Σ_{s<S} (c_s/c_S) f_s (the restriction matrix R of Menchero's paper) and running unconstrained WLS on X R. The market factor then is the cap-weighted market return net of style contributions. Sectors with no participating names in a period get a return of 0 and drop out of that period's constraint. Periods with fewer names than free parameters plus one are skipped (factor returns NaN).

Factor covariance (USE4 §4): exponentially weighted with half-life factorHalfLife periods and zero mean, then a Newey and West (1987, Econometrica 55(3)) correction for serial correlation, F = C₀ + Σ_{l=1..L} (1 − l/(L+1))(C_l + C_lᵀ), with the lagged cross-covariances C_l = Σ w_t f_t f_{t−l}ᵀ / Σ w_t. A result that is not positive semi-definite to rounding is repaired with PsdMatrices.nearestPsd(double[][]).

Volatility regime adjustment (USE4 §4.3): the cross-sectional bias statistic B_t² = (1/K) Σ_k (f_kt / σ_k,t−1)², with σ_k,t−1 the one-step-ahead EWMA volatility of factor k, is averaged with half-life volatilityRegimeHalfLife; F is multiplied by that average λ_F². The statistic starts after a burn-in of 20 valid periods; 0 switches the adjustment off.

Specific risk. Zero-mean EWMA of the regression residuals with half-life specificHalfLife, then Bayesian shrinkage toward the capitalisation-weighted mean σ̄_n of the name's size bucket (USE4 §5.3): σ_SH = v σ̄_n + (1 − v) σ, v = q|σ − σ̄_n| / (Δ_n + q|σ − σ̄_n|), Δ_n = √(mean_n (σ − σ̄_n)²). Names with fewer than two residuals take the bucket mean.

All variances are per period of the input returns.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static final class 
    Ex-ante risk of one portfolio under the model.
    static final record 
    Estimation settings.
  • Method Summary

    Modifier and Type
    Method
    Description
    double[][]
    The full N × N name covariance X F Xᵀ + D.
    boolean
    covers(int i)
    Whether name i has a forecast (live at the forecast date).
    decompose(double[] weights)
    Risk decomposition of a portfolio (weights as fractions of capital, zero on names that are not covered).
    estimate(double[][] returns, double[][][] styles, List<String> styleNames, int[] sectors, List<String> sectorNames, double[][] caps, FactorRiskModel.Settings settings)
    Estimates the model.
    double
    exposure(int i, int p)
    Exposure of name i to factor p at the forecast date.
    double
    exposureAt(int t, int i, int p)
    Exposure of name i to factor p at the start of period t (the forecast row when t == periods() and a forecast row was supplied).
    int
     
    double
    factorCovariance(int a, int b)
    Element (a, b) of the factor covariance, per period.
    double[][]
    The factor covariance, a copy.
    Factor names: MARKET, then the sectors, then the styles.
    double
    factorReturn(int t, int p)
    Factor return p in period t (NaN when the period was skipped).
    double[]
    Factor returns of period t, a copy.
    int
     
    int
    Number of estimation periods.
    double
    The volatility regime multiplier λ_F applied to factor volatilities (1 when off).
    boolean
    Whether the factor covariance needed a nearest-PSD repair.
    double
    residual(int t, int i)
    Specific return of name i in period t (NaN when it took no part).
    int
    sector(int i)
    Sector index of name i.
    int
     
    double
    Specific variance of name i, per period (NaN when not covered).
    static double[]
    standardize(double[] raw, double[] caps, boolean[] live, double limit)
    Cap-weighted-mean-zero, equal-weighted-unit-sd z-scores over the live names, clipped at ±limit and re-standardised once.
    int
     

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • estimate

      public static FactorRiskModel estimate(double[][] returns, double[][][] styles, List<String> styleNames, int[] sectors, List<String> sectorNames, double[][] caps, FactorRiskModel.Settings settings)
      Estimates the model.
      Parameters:
      returns - [T][N] period returns (NaN = not trading)
      styles - [T or T+1][K][N] raw style exposures
      styleNames - K names
      sectors - sector index of each name, in [0, sectorNames.size())
      sectorNames - S ≥ 1 sector names
      caps - [T or T+1][N] capitalisations (any currency)
      settings - estimation settings
    • standardize

      public static double[] standardize(double[] raw, double[] caps, boolean[] live, double limit)
      Cap-weighted-mean-zero, equal-weighted-unit-sd z-scores over the live names, clipped at ±limit and re-standardised once. Live names with a non-finite raw value get 0; names not live get NaN. All-zero when the live values have no dispersion.
    • factorNames

      public List<String> factorNames()
      Factor names: MARKET, then the sectors, then the styles.
    • factorCount

      public int factorCount()
    • sectorCount

      public int sectorCount()
    • styleCount

      public int styleCount()
    • nameCount

      public int nameCount()
    • periods

      public int periods()
      Number of estimation periods.
    • sector

      public int sector(int i)
      Sector index of name i.
    • factorReturn

      public double factorReturn(int t, int p)
      Factor return p in period t (NaN when the period was skipped).
    • factorReturnsCopy

      public double[] factorReturnsCopy(int t)
      Factor returns of period t, a copy.
    • residual

      public double residual(int t, int i)
      Specific return of name i in period t (NaN when it took no part).
    • exposureAt

      public double exposureAt(int t, int i, int p)
      Exposure of name i to factor p at the start of period t (the forecast row when t == periods() and a forecast row was supplied). NaN for a name that did not take part.
    • exposure

      public double exposure(int i, int p)
      Exposure of name i to factor p at the forecast date.
    • covers

      public boolean covers(int i)
      Whether name i has a forecast (live at the forecast date).
    • factorCovariance

      public double factorCovariance(int a, int b)
      Element (a, b) of the factor covariance, per period.
    • factorCovarianceCopy

      public double[][] factorCovarianceCopy()
      The factor covariance, a copy.
    • specificVariance

      public double specificVariance(int i)
      Specific variance of name i, per period (NaN when not covered).
    • regimeMultiplier

      public double regimeMultiplier()
      The volatility regime multiplier λ_F applied to factor volatilities (1 when off).
    • repaired

      public boolean repaired()
      Whether the factor covariance needed a nearest-PSD repair.
    • covariance

      public double[][] covariance()
      The full N × N name covariance X F Xᵀ + D. Rows and columns of names that are not covered are zero.
    • decompose

      public FactorRiskModel.Decomposition decompose(double[] weights)
      Risk decomposition of a portfolio (weights as fractions of capital, zero on names that are not covered).