← ClaudeAtlas

fractional-differentiationlisted

Make a price series stationary without throwing away the memory a model needs - the weight recursion, the fixed-width window, and the scan for the smallest d that passes ADF. TRIGGER - fractional differentiation, fractional differencing, fracdiff, frac_diff, frac_diff_ffd, get_weights_ffd, plotMinFFD, plot_min_ffd, "minimum d", ARFIMA, long memory, (1-B)^d, binomial weights, fixed-width window fracdiff; "my model only sees returns", "prices are non-stationary so I differenced them", "ADF says my feature is non-stationary", "should I feed prices or returns to the model", Lopez de Prado chapter 5, AFML fracdiff. SKIP for the cointegration ADF table and the fitted-residual null (stat-arb-cointegration), for unit-root and ARIMA model selection generally (time-series-forecasting-models), for making a feature causal and its warm-up (signal-construction), and for labels rather than features (triple-barrier-labeling).
howard-lynn-ye/fin-skills · ★ 1 · AI & Automation · score 77
Install: claude install-skill howard-lynn-ye/fin-skills
# Fractional differentiation **Returns are stationary and memoryless; prices remember and fail every stationarity test. `d` is the dial between them, and almost nobody turns it.** Advances in Financial Machine Learning (Lopez de Prado 2018), chapter 5. The default pipeline sets `d = 1` by reflex — `df.pct_change()` — and that is the maximum possible amount of differencing, not the minimum needed. Every number below is printed by `scripts/frac_diff.py` (numpy + scipy, seed 0, **3.7 s**, `statsmodels` optional). The test series is a mildly non-stationary log price: an AR(1) with `phi = 0.999`, T = 3,000, so `E[r_{t+1} | p_t] = (phi - 1) p_t` **exactly** — the level is the entire edge and a single return contains almost none of it. That is the DGP on which "differencing destroys memory" is a measurable statement rather than a slogan. ⚠️ Section and page numbers below are as cited in **mlfinpy 0.1.2's own docstrings**; what is verified here is the *code*, not the book. ## 1. The weight recursion, and why it is not a moving average `(1 - B)^d` expanded as a binomial series gives weights on the **levels**, newest first: ``` w[0] = 1 w[k] = -w[k-1] * (d - k + 1) / k ``` ✅ Measured: the recursion equals the closed form `w_k = (-1)^k C(d, k)` (`scipy.special.binom`, an independent route) to **1.1e-16** over the first 500 terms at d = 0.15, 0.40 and 0.75. ✅ `d = 1` returns exactly `[1, -1, 0, 0, ...]` — the first difference — and `d = 0` the identity. | d | first six wei