目录
- 一、 引言:为什么要在量化投资中讨论“熵”?
- 二、 熵的本质:从香农信息熵开始
- 三、 结构熵:捕捉市场微观结构信息
- 四、 衡量时间序列复杂性:近似熵(Approximate Entropy, ApEn)
- 五、 近似熵的改良:样本熵(Sample Entropy, SampEn)
- 六、 熵特征的应用:与XGBoost结合
- 七、 总结与展望
一、 引言:为什么要在量化投资中讨论“熵”?
在物理学中,熵是衡量系统混乱程度的度量。在信息论中,熵是衡量信息不确定性的度量。金融市场,本质上是一个充满噪声、不确定性和复杂交互的系统,这使得“熵”这个概念与量化投资结下了不解之缘。
传统的量化特征,如移动平均线(MA)、相对强弱指数(RSI)等,更多地关注价格和成交量的“数值”本身。然而,市场的行为模式、结构和动态复杂性同样蕴含着巨大的信息。一个看似平稳的市场可能内部暗流涌动,一个剧烈波动的市场也可能遵循着某种内在节律。
Marcos Lopez de Prado在其著作《金融机器学习》(Advances in Financial Machine Learning, AFML)中,大力倡导使用基于信息论的特征,其中熵特征就是核心之一。它们能够帮助我们从一个新的维度去刻画市场:
- 不确定性:市场的未来走向有多难预测?
- 复杂性:当前的价格序列是简单的重复,还是复杂的随机游走?
- 结构性:价格波动中是否存在着某种隐藏的、重复出现的模式?
通过量化这些抽象概念,我们可以为机器学习模型(如XGBoost)提供更深层次、更具洞察力的输入,从而提升模型的预测能力。
二、 熵的本质:从香农信息熵开始
要理解所有复杂的熵,我们必须回到源头——克劳德·香农(Claude Shannon)在1948年提出的信息熵。
2.1 什么是信息?——从“意外”说起
在信息论中,信息量的大小取决于它消除的不确定性的多少,或者说,它有多“出人意料”。
- 例子1:“明天太阳会从东边升起”。这句话信息量很低,因为它几乎是必然事件,没有消除任何不确定性。
- 例子2:“明天A股会发生熔断”。这句话信息量极高,因为它是一个极小概率事件,一旦发生,就消除了巨大的不确定性。
因此,一个事件的信息量 I(x) 可以定义为与其发生概率 p(x) 相关的函数。概率越小,信息量越大。香农将其定义为:
I(x) = -\log_b(p(x))
- p(x) 是事件 x 发生的概率。
- \log_b 是对数函数,底数 b 通常取2(单位为比特)、e(单位为奈特)或10。在信息论中,最常用的是2。
- 负号是为了确保信息量为正值,因为概率 p(x) 在 [0, 1] 区间内,其对数小于等于0。
2.2 信息熵的定义与直观理解
信息熵(Information Entropy),通常简称为熵,不是衡量单个事件的信息量,而是衡量一个随机变量(或整个系统)所有可能结果的平均信息量(即信息量的期望值)。
对于一个离散随机变量 X,它有 n 个可能的取值 \{x_1, x_2, ..., x_n\},对应的概率为 \{p(x_1), p(x_2), ..., p(x_n)\}。那么 X 的信息熵 H(X) 定义为:
H(X) = E[I(X)] = \sum_{i=1}^{n} p(x_i) I(x_i) = -\sum_{i=1}^{n} p(x_i) \log_b p(x_i)
直观理解:
- 均匀分布时,熵最大:想象一下抛硬币。
- 如果是一枚公平的硬币,p(正) = 0.5, p(反) = 0.5。每次抛掷的结果都很难预测。其熵为 H = -(0.5 \log_2 0.5 + 0.5 \log_2 0.5) = 1 比特。这是熵最大的情况。
- 如果是一枚作弊的硬币,p(正) = 0.99, p(反) = 0.01。结果几乎总是正面,非常确定。其熵为 H = -(0.99 \log_2 0.99 + 0.01 \log_2 0.01) \approx 0.08 比特。熵非常低。
- 确定事件时,熵最小:如果硬币两面都是正面,p(正) = 1, p(反) = 0。结果完全确定,没有任何不确定性。其熵为 H = -(1 \log_2 1 + 0 \cdot \text{undefined}) = 0。
所以,信息熵衡量的是一个系统的“混乱”或“不可预测”的程度。
2.3 信息熵在金融中的初步应用
我们可以将金融时间序列(如每日收益率)离散化,然后计算其信息熵。
- 离散化:将连续的日收益率序列划分到几个“桶”里。例如:
- 桶1:收益率 < -1% (大跌)
- 桶2:-1% <= 收益率 < 0% (下跌)
- 桶3:0% <= 收益率 < 1% (上涨)
- 桶4:收益率 >= 1% (大涨)
- 计算概率:统计在过去N天里,收益率落在每个桶的频率,作为其概率 p(x_i)。
- 计算熵:套用公式 H(X) = -\sum p(x_i) \log p(x_i)。
- 高信息熵:意味着过去N天里,各种涨跌情况分布得很均匀,市场方向不明朗,不确定性高。
- 低信息熵:意味着过去N天里,市场表现出明显的倾向性,比如连续大涨或连续大跌,市场处于一个相对“确定”的趋势中。
三、 结构熵:捕捉市场微观结构信息
信息熵有一个明显的缺点:它只关心事件的概率分布,而忽略了事件发生的顺序。
3.1 为什么需要结构熵?
考虑两个离散化的收益率序列(+
代表上涨,-
代表下跌):
- 序列A:
+ - + - + - + - + -
- 序列B:
+ + + + + - - - - -
对于这两个序列,+
和 -
的出现概率都是50%。因此,它们的信息熵是完全相同的,都处于最大值。
然而,任何一个交易员都能看出,这两个序列代表的市场状态截然不同:
- 序列A是高度规律的震荡市。
- 序列B是清晰的趋势反转。
信息熵无法区分这两种结构。为此,我们需要一种能捕捉序列模式和结构复杂性的熵——结构熵(Structural Entropy)。
3.2 结构熵的计算步骤
结构熵的核心思想借鉴了Lempel-Ziv (LZ) 无损压缩算法。这个算法的原理是:一个序列越有规律、重复模式越多,它就越容易被压缩。压缩后的长度就反映了其内在的复杂性。
计算步骤如下:
- 序列离散化:同信息熵一样,首先将连续的价格或收益率序列转换成离散的符号序列。例如,
{+1, -1, 0}
。 - 构建词典(Parsing):从左到右遍历序列,构建一个不重复的子序列(词典)集合。
- 从序列的第一个符号开始,将其作为第一个词。
- 继续向后读取,直到遇到一个在当前词典中不存在的新子序列。
- 将这个新的子序列加入词典,并从这个新子序列之后的位置开始,重复上述过程。
- 计算复杂度:词典中最终包含的子序列数量,就是这个序列的复杂度。
举个例子:
对序列 S = 1011010110110
进行解析。
1
-> 在词典里吗?否。加入词典。词典:{1}
。0
-> 否。加入词典。词典:{1, 0}
。11
-> 否。加入词典。词典:{1, 0, 11}
。01
-> 否。加入词典。词典:{1, 0, 11, 01}
。011
-> 否。加入词典。词典:{1, 0, 11, 01, 011}
。0110
-> 否。加入词典。词典:{1, 0, 11, 01, 011, 0110}
。
解析完成,序列 S
被分成了6个独一无二的子序列。其复杂度就是6。
对于我们之前的例子:
- 序列A:
+ - + - + - + - + -
-> 解析后可能是+
,-
,+-
,+--
, ... 这样的形式,由于模式单一,很快就会出现重复,最终词典大小会很小。 - 序列B:
+ + + + + - - - - -
-> 解析后可能是+
,++
,+++
,++++
,+++++
,-
,--
, ... 词典大小也相对较小。 - 一个完全随机的序列
+ - - + + - + - - +
-> 解析后会产生大量不同的子序列,词典会很大。
De Prado提出的结构熵公式是对这个复杂度进行归一化,以便比较不同长度的序列:
H_{struct} = \frac{c(S)}{n} \log_2(n)
其中,c(S) 是通过LZ算法得到的词典大小,n 是序列的总长度。
3.3 结构熵的金融学意义
- 低结构熵:表示市场存在着重复的、可识别的模式。这可能对应着某种交易策略(如高频做市、趋势跟随)正在主导市场,或者市场处于一个稳定的“范式”中(如长期牛市的缓慢上涨)。这种市场的“可压缩性”强。
- 高结构熵:表示市场行为是无序的、难以预测的,缺乏主导模式。这可能发生在市场范式转换、重大新闻冲击或多种力量相互博弈的时期。这种市场的“可压缩性”弱,更接近随机游走。
四、 衡量时间序列复杂性:近似熵(Approximate Entropy, ApEn)
信息熵和结构熵都需要对数据进行离散化,这个过程本身就会损失信息。有没有一种方法可以直接在连续的、原始的时间序列上衡量其复杂性呢?近似熵(ApEn)应运而生。
4.1 为什么需要新的熵?——时间序列的挑战
金融时间序列通常是:
- 连续的:价格是连续变化的。
- 有噪声的:充满了随机波动。
- 非平稳的:统计特性(如均值、方差)随时间变化。
- 数据长度有限:我们往往只能分析一段时期内的数据。
ApEn被设计用来处理这类短而含噪的时间序列,衡量其规律性(regularity)。
4.2 近似熵的计算思想与步骤
ApEn的核心思想是:比较时间序列中相邻“模式”的相似性。一个规律的序列(如正弦波),其模式会不断重复。一个复杂的序列(如白噪声),其模式几乎不重复。
ApEn量化了这样一个问题:“一个长度为 m 的模式,在下一个时间点继续保持相似的概率有多大?”
计算步骤非常精巧:
-
设定参数:
- m:嵌入维度(embedding dimension)。即我们要比较的模式的长度。通常取2或3。
- r:相似度容忍度(tolerance)。即我们认为两个模式“相似”的阈值。通常设为原始数据标准差的0.1到0.25倍。
-
构建 m 维向量:
假设我们的时间序列是 u(1), u(2), ..., u(N)。
我们将其重构成一系列长度为 m 的向量:
X(1) = [u(1), u(2), ..., u(m)]
X(2) = [u(2), u(3), ..., u(m+1)]
...
X(N-m+1) = [u(N-m+1), ..., u(N)] -
计算每个向量的近邻概率:
对于每一个向量 X(i),我们计算它与其他所有向量 X(j) 的距离。距离通常使用切比雪夫距离(即两个向量对应维度上差值的最大值)。
d[X(i), X(j)] = \max_{k=1,..,m} |u(i+k-1) - u(j+k-1)|然后,统计对于每个 X(i),有多少个 X(j) 满足 d[X(i), X(j)] \le r。记这个数量为 N^m(i)。
计算概率 C_i^m(r) = \frac{N^m(i)}{N-m+1}。 -
计算对数概率的均值:
计算所有 C_i^m(r) 的对数的平均值:
\Phi^m(r) = \frac{1}{N-m+1} \sum_{i=1}^{N-m+1} \ln(C_i^m(r)) -
维度增加,重复计算:
将嵌入维度增加到 m+1,重复步骤2、3、4,得到 \Phi^{m+1}(r)。 -
计算近似熵:
最终的近似熵定义为:
ApEn(m, r, N) = \Phi^m(r) - \Phi^{m+1}(r)
直观解释:
\Phi^m(r) 代表了长度为 m 的模式在序列中出现的普遍性。\Phi^{m+1}(r) 代表了长度为 m+1 的模式的普遍性。
如果序列很规律(如正弦波),一个长度为 m 的模式后面大概率会跟着一个特定的值,使得这个模式能延续成一个 m+1 的模式。因此 \Phi^m(r) 和 \Phi^{m+1}(r) 的值会很接近,它们的差值(ApEn)就很小。
如果序列很复杂(如噪声),一个长度为 m 的模式后面跟什么值是完全随机的,很难形成一个固定的 m+1 模式。因此 \Phi^{m+1}(r) 会远小于 \Phi^m(r),它们的差值(ApEn)就很大。
4.3 近似熵的优缺点
- 优点:
- 能直接处理连续数据,无需离散化。
- 对短数据系列(如N=50)依然有效。
- 抗噪声能力较强。
- 缺点:
- 存在偏置:在计算 C_i^m(r) 时,它会把自己和自己进行比较(X(i)与X(i)的距离总是0),这导致它系统性地高估了模式的规律性,尤其是在短序列上。
- 对参数 m 和 r 的选择比较敏感。
五、 近似熵的改良:样本熵(Sample Entropy, SampEn)
为了解决ApEn的偏置问题,Richman和Moorman提出了样本熵(SampEn)。
5.1 样本熵的改进动机
样本熵的核心改进点有两个:
- 消除自匹配(self-matching):在计算模式相似性时,不与自身进行比较。这消除了ApEn的主要偏置来源。
- 计算方法更直接:它不计算每个向量的对数概率再求平均,而是直接计算总的匹配数,这使得结果与数据长度的依赖性更小。
5.2 样本熵的计算步骤
样本熵的计算过程与ApEn类似,但有关键区别:
-
设定参数与构建向量:同ApEn一样,设定 m 和 r,并构建 m 维向量 X(1), ..., X(N-m+1)。
-
计算总匹配数(不含自匹配):
- 定义 B 为在 m 维空间中,所有距离小于 r 的向量对 [X(i), X(j)](其中 i \neq j)的总数量。
- 将维度增加到 m+1,构建 m+1 维向量。
- 定义 A 为在 m+1 维空间中,所有距离小于 r 的向量对的总数量。
-
计算样本熵:
样本熵被定义为:
SampEn(m, r, N) = -\ln \left( \frac{A}{B} \right)
直观解释:
这里的比值 \frac{A}{B} 有一个非常清晰的概率意义:它代表了**“两个序列在 m 个点上匹配的情况下,它们在下一个点也继续匹配”的条件概率**。
- 如果序列规律,这个条件概率会很高(接近1),取负对数后,SampEn就很小(接近0)。
- 如果序列复杂,这个条件概率会很低,取负对数后,SampEn就很大。
5.3 样本熵与近似熵的对比
特性 | 近似熵 (ApEn) | 样本熵 (SampEn) |
---|---|---|
自匹配 | 包含(导致偏置) | 排除(更准确) |
计算方式 | 对每个模板计算log概率再求和 | 计算总的匹配数再求log |
数据长度依赖 | 较强 | 较弱,结果更一致 |
推荐使用场景 | 历史算法,仍有应用 | 现代应用中的首选,尤其在生理信号和金融数据分析中 |
总的来说,在绝大多数应用场景下,样本熵(SampEn)是比近似熵(ApEn)更好的选择。
六、 熵特征的应用:与XGBoost结合
我们已经了解了四种强大的熵特征。现在,如何将它们应用到实际的量化交易模型中,例如与强大的XGBoost结合呢?
6.1 特征工程:如何生成熵特征
熵特征不是对整个历史数据只计算一个值,而是通过**滚动窗口(Rolling Window)**的方式,为每一个时间点生成一个特征值。
流程如下:
- 选择时间序列:可以是价格、对数收益率、波动率等。对数收益率是常用选择。
- 选择窗口长度:例如,选择一个50天(约2个月)的滚动窗口。
- 滚动计算:
- 在时间点 t,我们取 t 时刻之前的50个数据点(从 t-49 到 t)。
- 对这50个数据点组成的小序列,计算其熵值(信息熵、结构熵、ApEn、SampEn)。
- 将计算出的熵值,作为时间点 t 的一个新特征。
- 将窗口向后移动一个时间单位到 t+1,重复此过程。
这样,原始的一维时间序列,就被我们扩展出了多个新的特征列,每一列都代表了不同类型的历史复杂性度量。
下面是一个流程图,展示了如何为时间点 t
生成一个样本熵特征:
你可以为不同的窗口长度(如20天、50天、100天)和不同类型的熵都生成特征,极大地丰富你的特征集。
6.2 将熵特征融入XGBoost模型
XGBoost(eXtreme Gradient Boosting)是一种非常强大的梯度提升决策树模型,擅长处理表格数据,并且对特征的缩放不敏感。
-
构建特征矩阵 X:
将你计算出的所有熵特征(如SampEn_20d
,SampEn_50d
,StructEn_50d
等)与其他传统特征(如RSI, MACD, 动量等)组合在一起,形成一个大的特征矩阵 X。矩阵的每一行对应一个时间点,每一列对应一个特征。 -
定义目标变量 y:
目标变量是你希望模型预测的东西。在金融中,这通常是经过处理的未来收益。例如,使用AFML中推荐的**三重关卡法(Triple-Barrier Method)**来标注样本,即预测未来价格是触及上轨(买入)、下轨(卖出),还是时间止损(持有)。这比直接预测收益率数值更稳健。 -
训练模型:
将特征矩阵 X 和目标变量 y 喂给XGBoost分类器或回归器进行训练。
model.fit(X_train, y_train)
-
特征重要性分析:
训练完成后,XGBoost可以输出所有特征的重要性排序。这时你就可以直观地看到:- 熵特征在模型决策中的权重有多大?
- 是短期复杂性(如
SampEn_20d
)更重要,还是长期复杂性(如SampEn_100d
)更重要? - 结构熵和样本熵,哪一个对你的预测目标更有帮助?
6.3 解释与注意事项
- 金融含义:如果模型发现“样本熵下降”是一个重要的看涨信号,这可能意味着市场从混乱无序状态开始变得规律化、趋势化,这往往是新一轮趋势的开端。反之,熵的急剧增加可能预示着趋势的终结和盘整的开始。
- 参数选择:对于ApEn和SampEn,参数 m 和 r 的选择很重要。通常建议 m=2,而 r 取为窗口数据标准差的0.15或0.2倍。可以进行交叉验证来寻找最优参数。
- 计算成本:ApEn和SampEn的计算复杂度较高(约为 O(N^2)),在处理非常长的时间序列和非常小的窗口时需要注意计算效率。
七、 总结与展望
熵,这个源于物理学和信息论的概念,为我们理解和量化金融市场的复杂性提供了一把锋利的解剖刀。
- 信息熵为我们度量了市场状态分布的不确定性。
- 结构熵让我们能够洞察价格序列中隐藏的模式和结构。
- 近似熵和样本熵则直接在原始时间序列上量化了其动态的规律性和可预测性。
将这些熵特征作为输入,喂给像XGBoost这样强大的机器学习模型,我们就不再仅仅依赖于传统的价量指标,而是让模型学会理解市场的“性格”。
这正是现代量化投资的魅力所在:不断地从其他学科中汲取智慧,创造出更深刻、更有效的市场洞察力,从而在充满不确定性的博弈中,找到属于自己的那一点点确定性优势。