fracdiff¶
Defined in fynance.features.engineering
- fracdiff(X, d=0.4, tol=1e-5)[source]
Fixed-width-window fractional differentiation of a price series.
Stationarizes a (typically non-stationary, e.g. price or log-price) series while retaining as much memory as possible, unlike integer differencing (
d=1) which is stationary but wipes out most of the long-run dependence. Applies the fractional difference operator \((1-L)^d\) — where \(L\) is the lag operator — truncated to a fixed-width window, so that it is usable causally (online) rather than needing the full history at every step as the “expanding window” variant does.The weights follow the binomial-series recursion
\[w_0 = 1, \qquad w_k = -w_{k-1} \frac{d - k + 1}{k},\]truncated to the first \(K\) terms such that \(|w_K| < tol\) (\(K\) is fixed for the whole series — “fixed-width window”). The output is the causal convolution
\[y_t = \sum_{k=0}^{K-1} w_k X_{t-k}, \qquad t \ge K - 1,\]with the first \(K - 1\) entries set to NaN (insufficient history). Only past and current values of
Xare used, sofracdiffis strictly causal and safe to use in a walk-forward / online setting.- Parameters:
- Xnp.ndarray[float64, ndim=1 or 2]
Input series (e.g. price level). If two-dimensional, shape
(T, N), each column is treated independently. Must be finite (no NaN / inf).- dfloat, optional
Order of differentiation, must lie in
[0, 2].d=0leaves the series unchanged (post-warmup);d=1reduces, with the default tol, to the ordinary first difference; non-integerdin between trades off memory (smalld) against stationarity (larged). Default is 0.4.- tolfloat, optional
Weight-magnitude cutoff used to fix the window width \(K\) (see
_fracdiff_weights). Smaller tol keeps more weights (longer memory, larger warmup) at the cost of more computation. Default is 1e-5.
- Returns:
- np.ndarray[float64, ndim=1 or 2]
Fractionally differentiated series, same shape as X. The first
K - 1rows are NaN. IfXhas fewer thanKobservations, the output is entirely NaN.
- Raises:
- ValueError
If d is not in
[0, 2], if X contains non-finite values, or if X is not 1-D or 2-D.
See also
multi_resolution,adaptive_roll
Notes
There is an inherent memory-vs-stationarity trade-off (Lopez de Prado, 2018, ch. 5): larger
ddifferentiates more aggressively, making the series more likely to be stationary (e.g. pass an ADF test) but erasing more of the long-run memory that predictive models rely on; smallerdpreserves memory but may leave the series non-stationary. The common recipe is to search for the minimaldfor which the fractionally differentiated series is stationary.References
M. Lopez de Prado, “Advances in Financial Machine Learning”, Wiley, 2018, ch. 5.
Examples
>>> import numpy as np >>> X = np.array([1.0, 2.0, 4.0, 7.0, 11.0]) >>> fracdiff(X, d=1.0) array([nan, 1., 2., 3., 4.]) >>> np.array_equal(fracdiff(X, d=1.0)[1:], np.diff(X)) True >>> fracdiff(X, d=0.0) array([ 1., 2., 4., 7., 11.])