halo 的技术博客

返回

做量化的人几乎都踩过同一个坑:特征用错了差分阶数

  • 直接用价格 PtP_t 喂给模型?价格是 I(1)I(1)(单位根),均值、方差都随时间漂移,模型会学到一堆「伪相关」——比如价格和自己的滞后项高度相关只是因为它俩都在往上爬。
  • 那用收益率 Rt=PtPt1R_t = P_t - P_{t-1}(一阶差分,d=1d=1)?平稳了,可你把记忆也一起差分没了。收益率几乎不携带「价格现在处在历史什么位置」这种长周期信息,很多慢变量信号就这样被洗掉。

有没有中间地带?有——分数阶差分(fractional differentiation),记作 (1L)d(1-L)^d,其中 dd 不必是整数。Marcos López de Prado 在 Advances in Financial Machine Learning 里把它作为特征工程的核心工具:0<d<10<d<1 的阶数,把序列从 I(1)I(1) 降到 I(1d)I(1-d),在「足够平稳」和「保留记忆」之间找平衡点。

本文用一段合成的「类资产价格」随机游走(3000 点),亲手走完 fracdiff 的全部流程:权重公式 → ADF 平稳性扫描 → 记忆保留曲线 → 自相关对比,所有图表与数字由文末代码真实生成。

一、分数阶差分的权重公式#

一阶差分是 xt=xtxt1\nabla x_t = x_t - x_{t-1},权重为 [1,1][1,-1]。分数阶差分把「减去一阶」推广成「减去一个分数阶的导数」,其无限阶 MA 权重递归定义为:

w0=1,wk=wk1k1dk,k=1,2,w_0 = 1,\qquad w_k = w_{k-1}\cdot\frac{k-1-d}{k},\qquad k=1,2,\dots

对序列做 (1L)d(1-L)^d 就是 yt=k0wkxtky_t = \sum_{k\ge 0} w_k\,x_{t-k}。注意两点:

  1. d=0d=0 时所有权重退化成 w0=1w_0=1,即原序列;
  2. dd 越大,权重衰减越快——也就是说,更大的 dd 把越久远的历史「稀释」得越狠,记忆越短

分数阶差分权重:d 越小衰减越慢,融进越久的历史

看图就很直观:d=0.2d=0.2 的权重长长地拖一条尾巴(长记忆),d=0.8d=0.8 几乎两步就归零(短记忆)。这尾巴的长度,就是 fracdiff 区别于「直接取收益率」的本质。

二、核心权衡:越平稳,越丢记忆#

我们拿一段随机游走(典型的价格形态:强记忆、非平稳)做实验,对网格 d[0,1]d\in[0,1] 计算两个量:

  • 平稳性:对差分后的序列跑 ADF 单位根检验,取 pp 值。值越小越平稳(惯例以 0.05 为阈值)。
  • 记忆保留:差分后序列与原序列的线性相关 corr(yd,x)\text{corr}(y_d, x)。值越接近 1,说明越没丢掉原序列的信息。

分数阶差分的权衡:越往 d=1 越平稳却越丢记忆;取最小平稳 d 兼顾两者

曲线说得很清楚:

  • d=0d=0(原价格):记忆满分(相关 1.000),但 ADF p=0.10p=0.10非平稳——直接进模型就是坑。
  • d=1d=1(收益率):ADF p0p\approx0,彻底平稳,可记忆相关只剩 0.036——几乎把价格信息丢光。
  • 中间地带:取 d0.4d\approx0.4,序列已经显著平稳(ADF p<0.01p<0.01),记忆相关仍有 0.815。也就是说,你用 40% 的差分,既治好了非平稳,又保住了八成以上的「与原价格的同步性」。

真实数字(本文合成序列,3000 点):原序列 ADF p=0.1027p=0.1027;收益率 ADF p0p\approx0、与原序列相关 0.030-0.030d=0.4d=0.4 时 ADF p0p\approx0、记忆相关 0.8150.815;记忆相关随 dd 从 1.000 平滑跌到 0.036。

实践启示:别无脑用收益率。先扫一遍 dd,挑一个「ADF 通过 + 记忆保留尽量高」的折中区间(本文大致是 d[0.1,0.5]d\in[0.1,0.5],记忆从 0.995 退到 0.647),你的特征既平稳又有信息量。

三、自相关对比:fracdiff 把「慢衰减压」成「快衰减」#

平稳性在自相关函数(ACF)上看得更明白。序列越「有记忆」,ACF 衰减越慢。

自相关对比:fracdiff 把慢衰减压成快衰减,同时比收益率保留更多结构

  • 原随机游走:ACF 几乎不衰减(强记忆、非平稳的典型长尾巴)。
  • 收益率(d=1d=1):ACF 在滞后 1 就几乎归零——确实平稳,但太干净了,什么结构都没留
  • d=0.4d=0.4 的分数差分:ACF 比原序列衰减快得多(更接近平稳),却又明显比收益率「厚」——它保留了收益率丢掉的那部分中长周期结构。

这正是 fracdiff 的甜区:比原序列平稳,比收益率有记忆

四、保记忆的直观证据:叠加图#

光看数字不够,把 d=0.4d=0.4 的分数差分序列和原价格叠在一起(为同图可视做了缩放):

y_{d=0.4} 与原序列高度同步:既平稳,又保留了对原序列形态的追踪

两条线高度同步——分数差分序列忠实地「追踪」着原价格的形态,却已经脱去了单位根的非平稳外壳。把它作为特征喂给模型,模型拿到的是既平稳、又携带价格位置信息的输入。

五、完整 Python 实现#

下面这段代码自包含(不依赖 statsmodels,ADF 自己实现),可直接复现本文全部图表与数字。

跑出来的关键读数(与正文一致):d=0d=0 记忆 1.000、ADF p=0.10p=0.10d=0.4d=0.4 记忆 0.815、ADF p0p\approx0d=1d=1 记忆 0.036。

六、五个必须知道的坑#

  1. ADF 对分数根功率很低。当真实积分阶数接近 0.5 时,ADF 常常「分不清」I(0.6)I(0.6)I(1)I(1)。所以本文用 ADF 作为指示性信号,而非金标准——真正该问的是「我的下游模型/检验的平稳性假设是否被满足」,fracdiff 给你的是一根连续可调的旋钮,而不是一个魔法数字。
  2. 权重要截断。理论上 wkw_k 无限长,实践里取 L=50100L=50\sim100 足够,前 LL 个点会因边界效应设为 NaN(预热),别拿去训练。
  3. 别迷信 d* 唯一解。本文「最小平稳 dd」约 0.10,但真正好用的是 d[0.1,0.5]d\in[0.1,0.5] 这段安全带——在这个区间里你既通过平稳性检验,又保留了六成以上的记忆。
  4. 真实价格不是纯随机游走。真实资产价格常带趋势、均值回复、结构断点,fracdiff 找到的 dd 可能比本文的合成值更靠近 0.4–0.6,务必对你的数据重新扫描
  5. fracdiff 不改尺度量纲的解释。差分后序列单位是「原单位的 dd 阶差分」,做特征时通常还要标准化;它解决的是平稳性记忆,不解决异常值、幸存者偏差等其它问题。

七、小结#

分数阶差分的精髓就一句话:差分不是只有 0 和 1 两个档位dd 从 0 到 1 是一条连续光谱——0 端是「有记忆但不平稳」,1 端是「平稳但失忆」,中间 d0.4d\approx0.4 附近才同时拿到两者的好处。把它当成特征工程里的标准动作:先扫 dd、看 ADF 与记忆权衡、选安全带里的折中值,再进模型。这比直接丢收益率进去,往往多留住一大截有用的长周期信息。

所有图表均由本文代码在合成数据上真实生成,数字可复现;换成你的真实价量数据,只需替换「第三步」的数据源即可。

分数阶差分 fracdiff:在平稳与记忆之间找平衡点
https://blog.halo26812.eu.org/blog/fractional-differentiation-fracdiff
Author halo
Published at 2026年7月12日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨