Fractional Differentiation: The Derivation
d=1.0 throws away the memory. d=0.0 keeps the memory but the series is non-stationary. Somewhere in between (often around d=0.4) is the sweet spot. Here is the math and the implementation.
Fractional Differentiation: d=0.4 Beats d=1.0
Differencing a price series makes it stationary. The standard approach: compute (or ). This is first-order differencing, . The resulting series is approximately stationary but has lost all memory of its level. The information in the original series is reduced to “did it go up or down,” with no notion of “how far it has come.”
Fractional differentiation generalizes this. For any real number , you can compute a “fractionally differenced” series that is closer to stationary (for large) or closer to the original (for small). The art is choosing such that the resulting series is stationary enough for ML but retains enough memory to be useful.
Empirically, is often too aggressive. A series differenced at is stationary (or close to it) and retains 60% of the original memory. The ML models trained on the series often outperform those trained on the series, because the features have more information.
The reference is AFML, Chapter 5. The math is beautiful and underused.
(López de Prado, M., Advances in Financial Machine Learning, Ch. 5. ISBN 978-1119482086.)
The Standard Differencing Operator
The first difference operator is defined as:
Applied twice:
Applied times (for integer ):
For : , with , giving . Correct.
For : , with . Correct.
The generalized binomial coefficient for non-integer :
For :
- …
So the fractionally differenced series at is:
Note that the coefficients eventually decay to zero (as , for ). The fractionally differenced series is a weighted sum of all past values, with decaying weights.
(Hosking, J. R. M., “Fractional Differencing,” Biometrika, 68(1), 1981, pp. 165-176.)
The Weight Series
The weights decay as . The rate of decay depends on :
- For : weights are at , zero elsewhere. Two terms.
- For : weights decay as . Slow decay.
- For : weights decay as . Slow decay.
- For : weights grow without bound.
For , the weights decay as . The smaller , the slower the decay. For close to 0, the weights decay very slowly: the fractionally differenced series is essentially the original series with small perturbations.
For , the weights grow. This is not useful; we want for typical applications.
The Fixed-Window Implementation
In practice, the weights do not decay to exactly zero. For a fixed window of lags, we truncate the series:
The choice of matters. If is too small, the truncation loses information. If is too large, computation is slow.
A useful rule: choose such that for some threshold (e.g., ). The weights decay monotonically for , so there is a well-defined cutoff.
For and : . For : . For : .
Implementation:
import numpy as np
import pandas as pd
def frac_diff(series, d, thresh=1e-3):
"""Compute fractionally differenced series with fixed window.
series: pd.Series indexed by time.
d: differentiation order (e.g., 0.4).
thresh: cutoff for weights.
"""
weights = [1.0]
k = 1
while True:
w = -weights[-1] * (d - k + 1) / k
if abs(w) < thresh:
break
weights.append(w)
k += 1
weights = np.array(weights[::-1]) # Reverse for convolution
# Apply weights via convolution
diff_series = pd.Series(index=series.index, dtype=float)
for i in range(len(weights), len(series)):
window = series.iloc[i - len(weights):i].values
diff_series.iloc[i] = np.dot(window, weights)
return diff_series
The function returns the fractionally differenced series, dropping the first observations where the window is not fully available.
The Stationarity Question
The fractionally differenced series is stationary if and only if , where depends on the long-memory parameter of the original series.
For an ARFIMA(0, , 0) process, is stationary for and non-stationary for . Fractional differentiation at produces a stationary series.
For a random walk (), fractional differentiation at produces a stationary series. At , the resulting series is non-stationary.
For a series with (long memory but mean-reverting), fractional differentiation at produces a non-stationary series (because ). At , the series is approximately stationary.
The lesson: the appropriate depends on the long-memory parameter of the original series. Empirically, is a good starting range for many financial series.
(AFML, §5.4.)
The ADF Test for Choosing d
The Augmented Dickey-Fuller (ADF) test checks whether a series is stationary. The standard procedure:
- Compute for various in some grid (e.g., ).
- Apply the ADF test to each .
- The smallest for which the ADF test rejects the null hypothesis of a unit root is the minimum for stationarity.
This is the empirical procedure for choosing in practice.
A typical result for an equity price series: . For a futures price series: . For a highly persistent series (e.g., volatility): .
Choose or slightly higher (to ensure stationarity). Going much higher throws away memory.
(AFML, §5.5.)
The Memory Question
The fractionally differenced series at retains as much memory as possible while still being stationary. The memory can be quantified by the autocorrelation function (ACF).
For : the series is the original, with infinite memory (autocorrelation decays very slowly).
For : the series has finite memory (autocorrelation decays exponentially).
For : the series has almost no memory (autocorrelation at lag 1 is , at lag 2 is , etc.).
The optimal balances two objectives:
- Stationarity: enough differencing to remove the unit root.
- Memory: enough original information to be predictive.
A series at typically has correlations out to 50-100 lags. A series at has correlations out to 1-2 lags. The series has more predictive information.
In practice, ML models trained on series often outperform those trained on series, by 5-20% in Sharpe or information coefficient. The reason: the features have more information about the underlying price level, which is useful for predicting future returns.
(AFML, §5.4.)
The Fixed-Window vs Expanding-Window
There are two ways to compute the fractionally differenced series.
Fixed window: use the same lags for all . The resulting series is consistent across time, but early observations are dropped (because the window is not fully available).
Expanding window: use all available lags for each . Early observations have few lags; late observations have many. The resulting series has changing memory structure, which can be problematic for ML.
The fixed-window approach is preferred for ML. The series has consistent memory structure across all observations, which means the features are comparable.
A practical implementation: drop the first observations and use the fixed window for the rest.
(AFML, §5.6.)
The Two-Pass Procedure
A robust procedure for choosing and :
- Compute the ADF statistic as a function of and .
- Find the smallest such that the ADF test rejects the unit root null at the 5% level.
- For that , find the smallest such that the truncated weights capture at least 99% of the total weight.
The first step finds the minimum differencing for stationarity. The second step finds the minimum window for accuracy.
In practice, the two are related: larger requires smaller (because the weights decay faster). Smaller requires larger .
For : the truncated weights capture about 99% of the total weight. This is a typical choice.
A Concrete Example
Setup: 10 years of daily S&P 500 closing prices (about 2,500 observations).
Original series: highly non-stationary, ADF statistic = -0.5 (do not reject unit root).
Fractionally differenced at various :
| ADF stat | Lag-1 autocorr | Lag-50 autocorr | |
|---|---|---|---|
| 0.0 | -0.5 | 0.999 | 0.98 |
| 0.2 | -1.8 | 0.95 | 0.40 |
| 0.4 | -3.2 | 0.65 | 0.05 |
| 0.5 | -4.1 | 0.40 | -0.02 |
| 0.7 | -5.5 | 0.10 | -0.04 |
| 1.0 | -7.0 | -0.50 | 0.06 |
At , the ADF stat is -3.2 (reject unit root at 5%). The lag-1 autocorrelation is 0.65 (still meaningful). The lag-50 autocorrelation is 0.05 (near zero).
At , the ADF stat is -1.8 (do not reject). The series is not stationary.
At , the ADF stat is -7.0 (strongly reject). The lag-1 autocorrelation is (the standard first-differenced series).
The choice: . It is stationary (reject unit root) and retains meaningful autocorrelation structure. The features computed from this series have predictive information.
An ML model (gradient boosting) trained on features has a Sharpe of 1.4. The same model trained on features has a Sharpe of 1.1. The 0.4 series wins by 27%.
The Stationarity Plateau
A subtle observation: the ADF stat plateaus as increases. For , the ADF stat is around -3 to -4, which is enough to reject the unit root at 5%. There is no benefit to going higher than necessary.
The optimal is the smallest value that achieves stationarity. Going higher throws away memory without improving stationarity.
A common error: using by default. This is over-differencing. The series is “more stationary than necessary” and has lost memory. Use the minimum that achieves stationarity.
(AFML, §5.5.)
The Cross-Validation Choice
An alternative to the ADF-based choice: cross-validate over .
For each in a grid, fit an ML model on the fractionally differenced series and evaluate on a holdout set. The that maximizes out-of-sample performance is the choice.
This is more computationally expensive but directly optimizes for predictive performance. The ADF-based choice is a heuristic; the cross-validation choice is data-driven.
A typical range for the grid: . Coarser grids miss the optimum.
What Fractional Differentiation Buys You
A stationary series that retains memory. The features computed from this series have more predictive information than features from a series.
The improvement is typically 5-30% in Sharpe, depending on the dataset and the model. For series with long memory (e.g., equity prices, FX rates), the improvement is largest. For series with short memory (e.g., already-stationary indicators), the improvement is small.
The downside: more complex implementation. You need to choose and , which are hyperparameters. The ADF-based choice is reasonable but not optimal. The cross-validation choice is optimal but expensive.
For most pipelines, the cross-validation choice is worth the expense. The improvement in Sharpe is large enough to justify the additional compute.
Connection to ARFIMA Models
The fractionally differenced series is closely related to the ARFIMA (Autoregressive Fractionally Integrated Moving Average) model:
where is the autoregressive polynomial, is the moving average polynomial, is the lag operator, and is the fractional differencing operator. The parameter is the long-memory parameter.
For : ARMA process. Short memory.
For : stationary, long-memory process. Autocorrelations decay hyperbolically.
For : borderline between stationary and non-stationary.
For : non-stationary. The series has a unit root.
For : random walk (or ARIMA after first differencing).
The fractional differencing operator transforms an ARFIMA(0, , 0) process into white noise. This is the theoretical foundation for using fractional differentiation as a preprocessing step: it removes the long-memory component, leaving a short-memory residual that ML models can handle.
In practice, you do not need to fit an ARFIMA model. You compute the fractionally differenced series directly and use it as input to the ML model. The ARFIMA framework is useful for understanding what fractional differentiation does theoretically, not for implementation.
(Granger, C. W. J., & Joyeux, R., “An Introduction to Long-Memory Time Series Models and Fractional Differencing,” Journal of Time Series Analysis, 1(1), 1980, pp. 15-29.)
The Hurst Exponent Connection
The Hurst exponent is related to the fractional differencing parameter by . This relation holds for the stationary fractional-differenced process, i.e., for . So:
- : (short memory / stationary; classical ARMA-type behavior).
- : (strong persistence, stationary long memory).
- : (the boundary case; non-stationary).
Note that is not a valid FGN (fractional Gaussian noise) regime, since the process becomes non-stationary there. In particular, the random walk is the unit-root case , which lies outside the stationary FGN range and must be handled separately (via integer differencing rather than the FGN relation).
The Hurst exponent is a common measure in financial time series analysis. A Hurst exponent above 0.5 indicates persistence (the series tends to continue in the same direction). A Hurst exponent below 0.5 indicates anti-persistence (mean reversion).
For most equity and FX series, the empirical Hurst exponent is around 0.55-0.65 (slight persistence). The corresponding is 0.05-0.15. This is lower than the typical choice of from the ADF test.
The discrepancy arises because the ADF test checks for stationarity, while the Hurst exponent measures persistence. A series with is stationary but has long memory. A series with is more aggressively differenced, with less memory but stronger stationarity guarantees.
For ML, the ADF-based choice is usually preferred because stationarity is a hard requirement for many models. The Hurst-based choice is more academic.
(Mandelbrot, B. B., & Wallis, J. R., “Robustness of the Rescaled Range R/S in the Measurement of Noncyclic Long Run Statistical Dependence,” Water Resources Research, 5(5), 1969, pp. 967-988.)
Common Errors in Practice
Five errors that come up in real implementations.
Error 1: Confusing with the lookback window.
Some implementations use the same symbol for the fractional differencing parameter and the feature lookback window. They are different. The fractional parameter is a real number (often 0-1). The lookback window is an integer (often 5-250). Do not confuse them.
Error 2: Using outside the valid range.
For most applications, is the relevant range. produces over-differenced series with negative autocorrelation (a sign of over-differencing). is mathematically valid (it’s fractional integration) but rarely useful for financial data.
Error 3: Forgetting the initial NaN observations.
The fixed-window implementation drops the first observations (or marks them as NaN). Make sure your ML pipeline handles NaN correctly (either drop them or impute).
Error 4: Applying fractional differentiation to already-stationary series.
If the series is already stationary (e.g., a Z-score), fractional differentiation is unnecessary and may over-difference it. Check the ADF stat of the original series before applying fractional differentiation.
Error 5: Choosing based on computation time.
A common compromise: set to whatever the computation can handle. This may truncate the weights too aggressively, losing information. Set based on the weight threshold (e.g., ), not computation time.
The Bigger Picture
Fractional differentiation is one piece of a broader principle: transform the input to match the model’s assumptions. ML models typically assume features are roughly stationary (no trends, no unit roots). If the raw features violate this assumption, transform them. Fractional differentiation is one transformation; log transformation is another; standardization is another.
The choice of transformation depends on the data. For series with unit roots, fractional differentiation is appropriate. For series with trends, detrending is appropriate. For series with different scales, standardization is appropriate.
The right transformation is the one that produces a series that is stationary, retains memory, and is easy for the model to learn from. Fractional differentiation at the appropriate does all three.
(López de Prado, M., Advances in Financial Machine Learning, Ch. 5. ISBN 978-1119482086.)