Skip to content

Mean Reversion Half-Life

Intuição

A Mean Reversion Half-Life estima o tempo (em períodos) para um desvio decair pela metade, a partir de uma regressão simples que aproxima um processo tipo OU.

Definição

Em uma janela n, ajuste:

Δp_t = λ * p_{t-1} + ε_t

Se λ < 0, a meia-vida é:

HL = -ln(2) / λ

Uso

from quantmaster.features.statistical import mean_reversion_half_life

df["hl_60"] = mean_reversion_half_life(df, window=60)

API

Source code in src/quantmaster/features/statistical.py
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
def mean_reversion_half_life(
    data: pd.DataFrame | pd.Series,
    *,
    window: int = 60,
    price_col: str = "close",
) -> pd.Series:
    window = validate_positive_int(window, name="window")

    price = get_price_series(data, price_col=price_col).astype(float)
    price = price.where(price > 0)

    out = pd.Series(np.nan, index=price.index, dtype=float)
    out.name = f"mean_reversion_half_life_{window}"

    if len(price) < window:
        return out

    p = np.log(price).to_numpy(dtype=float)
    pw = np.lib.stride_tricks.sliding_window_view(p, window_shape=window)

    hl = np.full(pw.shape[0], np.nan, dtype=float)
    for i in range(pw.shape[0]):
        w = pw[i]
        x = w[:-1]
        y = np.diff(w)
        lam = _ols_slope(x, y)
        if not np.isfinite(lam) or lam >= 0.0:
            continue
        hl[i] = float(-np.log(2.0) / lam)

    out.iloc[window - 1 :] = hl
    return out