Class SignalEvaluator

java.lang.Object
com.quantfinlib.alpha.SignalEvaluator

public final class SignalEvaluator extends Object
Signal evaluation: the metrics that decide whether a factor is worth building a portfolio from, computed before any backtest so weak signals die cheaply.
  • IC (information coefficient): Spearman rank correlation between scores at t and forward returns over (t, t+h]. Rank rather than Pearson because scores have arbitrary units and fat tails; rank IC is invariant to any monotone transform of the signal. Computed at every bar from startIndex, so the forward windows overlap.
  • t-stat: mean(IC) / SE_HAC, with the Newey-West (1987) standard error at lag max(h − 1, Andrews(1991) AR(1) plug-in). Overlapping windows make the IC series MA(h−1) mechanically, and persistent signals add positive autocorrelation on top; the iid std/√n t-stat ignores both and is reported only as naiveTStat for comparison.
  • IR: mean(IC) / std(IC), Grinold and Kahn's signal quality per unit of inconsistency.
  • IC autocorrelation: the lag-h autocorrelation of the IC series, the correlation between consecutive non-overlapping ICs. Near 1 means the sample holds far fewer independent observations than dates.
  • Hit rate: fraction of (symbol, date) pairs where the sign of the cross-sectionally demeaned score matches the sign of the demeaned forward return. Demeaning matters: a one-signed raw score (−σ for low volatility, a yield for value) would otherwise turn the hit rate into the fraction of up-moves in the panel.
  • Turnover: half the L1 change in gross-1 z-score weights between t − h and t, the trading the signal demands if rebalanced every h bars.
  • Factor exposure: mean cross-sectional rank correlation against another factor.

Forward returns come from AlphaContext.returnOver(int, int, int), which is terminal-event aware when a point-in-time universe is attached: a name that delists inside the window contributes its delisting return, not the flat forward-filled ghost bars that follow.

  • Method Details

    • evaluate

      public static SignalEvaluator.Report evaluate(AlphaContext ctx, AlphaFactor factor, int startIndex, int horizon)
      Evaluates a factor at every bar in [startIndex, ctx.bars() − horizon) against overlapping horizon-bar forward returns (see the class doc for each metric).
      Parameters:
      horizon - forward-return horizon in bars
      Throws:
      IllegalArgumentException - with fewer than horizon + 2 scored dates
    • quantileReturns

      public static SignalEvaluator.QuantileReport quantileReturns(AlphaContext ctx, AlphaFactor factor, int startIndex, int horizon, int quantiles)
      Buckets each evaluation date's cross-section into quantiles score-ranked groups and averages forward returns per group. Dates step by horizon from startIndex (non-overlapping); a NaN score or forward return drops that pair; a date with fewer complete pairs than quantiles contributes to no bucket. Bucketing is by ascending score rank (rank * quantiles / n); ties are split by input order at a boundary, so membership is not fully tie-invariant.
      Parameters:
      quantiles - number of buckets, at least 2 (5 = quintiles)
    • factorExposure

      public static double factorExposure(AlphaContext ctx, AlphaFactor a, AlphaFactor b, int startIndex, int step)
      Mean cross-sectional rank correlation between two factors' scores — how much of factor B is already inside factor A. Above ~0.7 the "new" factor adds little beyond the old one.