← Back to archive

1. Introduction

Mean reversion is among the oldest ideas in trading: prices that deviate from some equilibrium tend to return to it. In equities, this is complicated by the presence of a positive drift (the equity risk premium) and corporate events that create permanent price changes. In foreign exchange markets, the case for mean reversion is stronger on theoretical grounds. Purchasing power parity, uncovered interest rate parity, and central bank policy all create forces that pull exchange rates toward equilibrium values over various horizons.

The practical challenge is not whether FX rates mean-revert — over sufficiently long horizons, most G10 pairs do — but whether the mean reversion occurs on a timescale that permits profitable trading after transaction costs. A pair with a half-life of 300 trading days is statistically mean-reverting but practically useless for a strategy that needs to generate monthly returns. We need mean reversion that operates on a timescale of days to weeks, with sufficient amplitude to cover the bid-ask spread and slippage.

This article develops a systematic framework for identifying and trading mean reversion in G10 FX, using the Ornstein-Uhlenbeck (OU) process as the core statistical model. The key innovation is the addition of a regime filter that suppresses signals during trending periods, where mean reversion signals produce systematic losses.

2. The Ornstein-Uhlenbeck Model

The OU process is the canonical continuous-time model for mean reversion. For an exchange rate deviation x(t) from some equilibrium level, the OU process is described by the stochastic differential equation:

dx(t) = θ(μ − x(t))dt + σdW(t)

where θ is the speed of mean reversion, μ is the long-term mean, σ is the volatility of the process, and W(t) is a standard Brownian motion. The key parameter for our purposes is θ: it determines how quickly the process reverts to the mean. The half-life of mean reversion — the expected time for a deviation to decay by 50% — is:

t½ = ln(2) / θ

To estimate the OU parameters from discrete data, We use the equivalence between the OU process and the continuous-time limit of an AR(1) process. Given a time series of log exchange rate deviations from a rolling mean, We estimate the discrete AR(1) coefficient and then recover the OU parameters:

import numpy as np
from scipy import stats

def estimate_ou_params(series, dt=1.0):
    """
    Estimate Ornstein-Uhlenbeck parameters from a time series
    using the AR(1) regression method (Chan, 2013).

    Args:
        series: array of log-price deviations from mean
        dt: time step (1.0 for daily data)
    Returns:
        dict with theta, mu, sigma, half_life, adf_pvalue
    """
    y = np.diff(series)
    x = series[:-1]

    # AR(1) regression: dy = lambda * y_{t-1} + mu_hat + eps
    slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)

    # Recover OU parameters
    theta = -slope / dt
    mu = intercept / (theta * dt) if theta > 0 else np.nan

    residuals = y - (slope * x + intercept)
    sigma = np.std(residuals) / np.sqrt(dt)

    half_life = np.log(2) / theta if theta > 0 else np.inf

    # ADF test for stationarity (the slope should be negative)
    adf_stat = slope / std_err

    return {
        'theta': theta,
        'mu': mu,
        'sigma': sigma,
        'half_life': half_life,
        'adf_stat': adf_stat,
        'adf_pvalue': p_value,
        'mean_reverting': slope < 0 and p_value < 0.05
    }

The critical diagnostic is the Augmented Dickey-Fuller (ADF) test statistic. A statistically significant negative slope coefficient indicates that the series is mean-reverting rather than a random walk. We require a p-value below 0.05 and a half-life between 5 and 50 trading days to classify a pair as exhibiting tradeable mean reversion.

3. Screening G10 Cross Pairs

The G10 currencies (USD, EUR, GBP, JPY, CHF, AUD, NZD, CAD, NOK, SEK) produce 45 unique cross pairs. We compute deviations from a rolling 60-day mean of the log exchange rate and estimate OU parameters on a rolling 252-day window, updating daily. The analysis covers the period January 2015 to December 2024.

Pair Median Half-Life % Windows Significant Median θ
AUDNZD 11.2 days 78% 0.062
EURCHF 14.8 days 71% 0.047
EURGBP 18.3 days 64% 0.038
NOKSEK 8.4 days 82% 0.083
AUDCAD 16.7 days 58% 0.042
NZDCAD 22.6 days 53% 0.031

Table 1: G10 cross pairs with statistically significant mean reversion in more than 50% of rolling 252-day windows. "% Windows Significant" indicates the proportion of windows where the ADF test rejects the random walk null at the 5% level.

The pairs that show the strongest and most persistent mean reversion share a common feature: they are economically linked economies with similar monetary policy regimes. AUDNZD (Australia and New Zealand), NOKSEK (Norway and Sweden), and EURCHF (Eurozone and Switzerland) all represent pairs where the two economies are closely integrated and central banks operate within similar frameworks. This economic intuition reinforces the statistical findings and suggests that the mean reversion is driven by a genuine economic mechanism rather than a statistical artefact.

The remaining 39 pairs either fail the ADF test in a majority of windows or exhibit half-lives exceeding 50 days, making them impractical for a short-to-medium-term trading strategy.

4. Signal Generation

For each qualifying pair, We generate trading signals based on the z-score of the current deviation from the estimated mean:

z(t) = (x(t) − μ̂) / σ̂

We enter a mean-reversion position when |z| exceeds an entry threshold z_entry and exit when z crosses zero (the estimated mean) or when |z| exceeds a stop-loss threshold z_stop. The optimal thresholds are a function of the estimated OU parameters: higher θ (faster reversion) permits more aggressive entry thresholds, while higher σ (more noise) requires wider stops.

The theoretical optimal entry level for an OU process, derived from the solution to the optimal stopping problem (Leung and Li, 2015), depends on the ratio σ²/(2θ) and the discount rate applied to future returns. In practice, We find that z_entry between 1.5 and 2.0 standard deviations and z_stop between 3.0 and 3.5 standard deviations produces the best risk-adjusted results across our six pairs.

5. The Regime Filter

Unconditional mean reversion signals suffer from a well-known problem: during trending regimes, the strategy takes positions against the trend and is systematically stopped out. The resulting losses can be large enough to offset the profits accumulated during range-bound periods.

We address this with a simple but effective regime filter based on the Hurst exponent. The Hurst exponent H is estimated using the rescaled range (R/S) method over a trailing 120-day window. Values of H near 0.5 indicate a random walk; values below 0.5 indicate mean reversion; values above 0.5 indicate persistence (trending). We suppress mean reversion signals when H exceeds 0.55, indicating a trending regime.

def hurst_exponent(series, max_lag=60):
    """
    Estimate the Hurst exponent using the rescaled range method.
    H < 0.5: mean-reverting; H = 0.5: random walk; H > 0.5: trending
    """
    lags = range(2, max_lag)
    rs_values = []

    for lag in lags:
        subseries = [series[i:i+lag] for i in range(0, len(series)-lag, lag)]
        rs = []
        for s in subseries:
            mean_s = np.mean(s)
            devs = np.cumsum(s - mean_s)
            r = np.max(devs) - np.min(devs)
            std_s = np.std(s, ddof=1)
            if std_s > 0:
                rs.append(r / std_s)
        if rs:
            rs_values.append((np.log(lag), np.log(np.mean(rs))))

    if len(rs_values) < 2:
        return 0.5

    x, y = zip(*rs_values)
    slope, _, _, _, _ = stats.linregress(x, y)
    return slope

def regime_filter(series, window=120, threshold=0.55):
    """Returns True when regime is mean-reverting (H < threshold)."""
    h = hurst_exponent(series[-window:])
    return h < threshold

6. Results

We evaluate the framework over the out-of-sample period January 2020 to December 2024, using parameters estimated on the preceding five-year training period and re-estimated monthly. Transaction costs are set at 1.5 pips per round trip for major pairs and 2.5 pips for Scandinavian crosses.

Pair Sharpe (No Filter) Sharpe (Regime Filter) Max DD (No Filter) Max DD (Filter)
AUDNZD 0.41 0.72 −8.3% −5.1%
EURCHF 0.28 0.54 −11.6% −7.2%
EURGBP 0.15 0.43 −9.7% −6.8%
NOKSEK 0.52 0.81 −6.9% −4.4%
AUDCAD 0.09 0.37 −12.4% −8.9%
NZDCAD −0.12 0.21 −14.1% −9.5%
Portfolio 0.58 0.94 −7.8% −4.6%

Table 2: Out-of-sample performance with and without the Hurst regime filter. The "Portfolio" row is an equal-weighted combination of all six pairs.

The regime filter improves performance across every pair. The improvement is largest for pairs that experienced extended trending episodes during the evaluation period — AUDCAD and NZDCAD during the commodity price fluctuations of 2020-2022, and EURGBP during Brexit-related trends. The equal-weighted portfolio achieves a Sharpe ratio of 0.94 with the filter, compared to 0.58 without, with maximum drawdown reduced from 7.8% to 4.6%.

7. Caveats and Limitations

Several limitations should be noted. First, the OU model assumes constant parameters, which is clearly violated in practice. Our rolling estimation addresses this partially, but parameter estimation itself introduces noise, particularly when the true half-life is close to the estimation window length.

Second, the Hurst exponent is itself an estimate with significant uncertainty at the window lengths We use. Misclassifying a range-bound regime as trending causes missed trades; the reverse causes trend-fighting losses. We have chosen the threshold (H = 0.55) conservatively to minimise the latter, which is more costly.

Third, our transaction cost assumptions may be optimistic for Scandinavian crosses during periods of low liquidity. The NOKSEK and NZDCAD results in particular should be viewed as upper bounds on achievable performance.

Finally, the economic rationale for mean reversion in closely linked economies — similar monetary policy, integrated trade, correlated economic cycles — is itself subject to structural change. Policy divergence between previously aligned central banks can permanently shift the equilibrium, rendering the historical calibration invalid.

8. Conclusion

Mean reversion in FX is real but selective. Of 45 G10 cross pairs, only 6 exhibit statistically robust mean reversion on tradeable timescales. These pairs share the common feature of representing closely linked economies. A simple framework based on OU parameter estimation with a Hurst exponent regime filter produces a diversified portfolio with an out-of-sample Sharpe ratio of 0.94 and a maximum drawdown below 5%. While these results are encouraging, they require ongoing monitoring for structural breaks in the economic relationships that drive mean reversion.

References

  1. Chan, E.P. (2013). Algorithmic Trading: Winning Strategies and Their Rationale. John Wiley & Sons.
  2. Leung, T. and Li, X. (2015). Optimal Mean Reversion Trading: Mathematical Analysis and Practical Applications. World Scientific.
  3. Bao, Y., Ullah, A. and Wang, Y. (2017). "Distribution of the Mean Reversion Estimator in the Ornstein–Uhlenbeck Process." Econometric Reviews, 36(6-9), 1039–1056.
  4. Cantarutti, N. et al. (2025). "Considerations on the Mean-Reversion Time." SSRN Working Paper.
  5. Holý, V. and Tomanová, P. (2018). "Estimation of Ornstein-Uhlenbeck Process Using Ultra-High-Frequency Data." arXiv:1811.09312.
  6. Stübinger, J. and Endres, S. (2018). "Pairs Trading with a Mean-Reverting Jump-Diffusion Model." Quantitative Finance, 18(10), 1735–1751.