Class RegimeDetector

java.lang.Object
com.quantfinlib.ml.RegimeDetector

public final class RegimeDetector extends Object
Two-state Gaussian Markov-switching model (hidden Markov model) fitted by Baum-Welch EM with scaled forward-backward recursions (Rabiner 1989, Proc. IEEE 77, 257-286; Hamilton 1989, Econometrica 57, 357-384). Detects calm/turbulent regimes in a return series. State 1 is always the high-volatility regime.

Filtered versus smoothed. The model reports two probability paths. filteredHighVolProbability[t] = P(high vol at t | r_0..r_t) uses only data up to t and is the one a strategy may act on at t (after observing r_t). smoothedHighVolProbability[t] = P(high vol at t | r_0..r_{n−1}) uses the whole sample, including data after t; it is for labelling regimes after the fact. De-levering on the smoothed path in a backtest is look-ahead. Note that the parameters themselves are fitted on the whole sample, so even the filtered path is only out-of-sample when the model was fitted on an earlier window.

EM is local: fit(double[], int) runs from the median-split start plus four seeded random starts and keeps the highest likelihood. Emission densities are handled in log space with a per-period shift, so an extreme return cannot underflow both densities to zero. Inputs must be finite.

  • Method Details

    • fit

      public static RegimeDetector.RegimeModel fit(double[] returns, int maxIterations)
      Fits with five starts (median split plus four seeded random starts).
    • fit

      public static RegimeDetector.RegimeModel fit(double[] returns, int maxIterations, int starts, long seed)
      Fits the regime model by EM from several starts.
      Parameters:
      maxIterations - EM iterations per start (0 evaluates the start)
      starts - number of starting points, ≥ 1; the first is always the median split, the rest are random
      seed - seed for the random starts
    • viterbi

      public static int[] viterbi(double[] returns, RegimeDetector.RegimeModel model)
      Most likely state sequence (Viterbi, in log space) under a fitted model; uses the whole sample, so it is an ex-post labelling.