Stationary Bootstrap (平稳自助法)

Politis & Romano (1994) resampling scheme that preserves the weak dependence structure of a time series (e.g., autocorrelations). The standard tool for computing standard errors of Sharpe-ratio differences in strategy backtests.

Why not the iid bootstrap?

The naive bootstrap resamples return observations with replacement, treating them as iid. This destroys autocorrelation — which is exactly the structure you care about in a momentum / mean-reversion strategy. Under iid bootstrap, you overestimate precision because the effective sample size is wrong.

The stationary bootstrap resamples blocks of random length instead of single observations, preserving local dependence.

Algorithm (Politis & Romano, 1994)

For a time series \{r_t\}_{t=1}^T and block-size distribution parameter p \in (0, 1]:

  1. Draw i_1 uniformly from \{1, \dots, T\}. The first resampled observation is r_{i_1}.
  2. Draw U \sim \text{Uniform}(0,1). If U < p, draw the next index i_2 uniformly from \{1, \dots, T\}. Otherwise, set i_2 = i_1 + 1 \pmod T (continue the block).
  3. Repeat until you have a resampled series of length T.

The expected block length is 1/p. Choice of p:

  • Larger p → longer blocks → preserves more dependence but more variance in the resampled series.
  • Smaller p → closer to iid bootstrap.

Choosing p

Politis & Romano recommend an automatic bandwidth selection rule based on the autocorrelation structure of the series:

  1. Compute the sample autocorrelation function \hat\rho(k) for lags k = 1, 2, \dots.
  2. Find the smallest k such that |\hat\rho(k)| < 2 / \sqrt{T} (approximately white-noise threshold).
  3. Use p = 1/k.

For daily strategy returns over ~20 years (~5000 obs), p \approx 0.05 to 0.10 is typical.

Application: Sharpe ratio difference test

The standard test in Moskowitz et al. (2025) is:

H_0: SR_A \geq SR_B \quad \text{vs.} \quad H_1: SR_A < SR_B

Compute \Delta SR = SR_A - SR_B on the original returns. Then resample block-wise with the SAME index draws for both strategies A and B (preserves correlation between A and B). Compute \Delta SR^*_b for b = 1, \dots, B (typically B = 1000). The bootstrap p-value is:

p = \frac{1}{B} \sum_{b=1}^{B} \mathbf{1}\!\left[\Delta SR^*_b \geq \Delta SR\right]

Why synchronized resampling matters: if you draw different block indices for A and B, you destroy the cross-correlation between them and lose power. Always use the same index draws across strategies for paired tests.

Implementation

Most quant libraries have it. In Python:

import numpy as np

def stationary_bootstrap_indices(T, p, rng):
    """Generate one set of resampled indices for a stationary bootstrap."""
    idx = np.empty(T, dtype=int)
    i = rng.integers(0, T)
    for t in range(T):
        idx[t] = i
        if rng.random() < p:
            i = rng.integers(0, T)
        else:
            i = (i + 1) % T
    return idx

For vectorized resampling of two correlated return series, draw one index array and apply to both.

When to use alternatives

  • Circular bootstrap: fixed block length L, simpler. Loses the smoothness of the stationary version but is unbiased for sample statistics. Use when dependence has a clean cutoff at a known lag.
  • Block bootstrap with optimal block length (Lahiri): similar to stationary but with deterministic block length chosen via subsampling.
  • Iid bootstrap: only valid when the statistic is invariant to ordering (e.g., mean of uncorrelated returns).
  • Moving-block bootstrap: fixed length L, similar caveats to circular.

Common pitfalls

  • Wrong p: too large → too much serial correlation injected → too few independent samples → conservative tests (false negatives).
  • Desynchronized resampling for paired tests → destroys cross-correlation.
  • Ignoring time variation in vol: bootstrap on raw returns can mislead if vol is highly clustered; consider bootstrap on standardized returns or block-bootstrap on squared returns separately.
  • Look-ahead: resampling test data with information from the training period contaminates inference.

References

  • Politis, D.N. & Romano, J.P. (1994). "The Stationary Bootstrap." Journal of the American Statistical Association, 89(428).
  • Moskowitz, T.J., Sabbatucci, R., Tamoni, A., & Uhl, B. (2025). "Nonlinear Time Series Momentum." Working paper, §4 (uses n_b = 1000 bootstrap samples).