Class BenchmarkComparison

java.lang.Object
com.quantfinlib.backtest.BenchmarkComparison

public final class BenchmarkComparison extends Object
BENCHMARK-RELATIVE performance — the numbers an allocator actually asks for. A standalone Sharpe answers "was this good?"; these answer "was this good compared to just buying the index?", which is the question every active strategy must survive.
  • beta — Cov(r_s, r_b)/Var(r_b): how much of the strategy is just the benchmark in disguise;
  • alpha — annualized Jensen intercept (mean(r_s) − β·mean(r_b))·P at zero risk-free rate: the return left over after the benchmark exposure is paid for;
  • tracking error — annualized stdev of active returns a_t = r_s,t − r_b,t: how far the strategy strays;
  • information ratio — annualized mean(a)/TE: alpha per unit of straying. The active-management analogue of Sharpe; sustained IR > 0.5 is good, > 1 is elite;
  • up/down capture — mean strategy return over periods when the benchmark rose (fell), divided by the benchmark's own mean in those periods. The dream profile is up > 1, down < 1. Arithmetic means of per-period returns, not compounded — stated, and the right choice at daily granularity where cross-terms are negligible. NaN when the benchmark had no up (down) periods: no evidence, not zero.

Both series must be the same length and aligned period-by-period — this class cannot detect a one-day offset, and an offset silently destroys beta (it becomes a lead-lag estimate). Align first, then compare. Requires the benchmark to actually vary; comparing against a constant series is refused rather than returning a 0/0 beta.

  • Method Details

    • compare

      public static BenchmarkComparison.Result compare(double[] strategy, double[] benchmark, int periodsPerYear)
      Parameters:
      strategy - per-period strategy returns, aligned with benchmark, ≥ 3 periods, finite
      benchmark - per-period benchmark returns, must vary
      periodsPerYear - annualization factor (252 daily, 12 monthly)