金融事件采样中的 CUSUM 滤波器详解
从对数收益累积和阈值重置入手,理解 CUSUM 如何选择事件时点,以及阈值、收盘时间和回测成本会怎样影响结果。
本指南内容CUSUM 选择事件时点,而不是预测方向
简短摘要
CUSUM 滤波器把连续对数收益分别累积到正向和负向路径;任一路径越过阈值时,便记录一个事件并重置该侧累积值。它回答的是“何时抽取样本”,不是“下一步涨跌如何”,也不会自行生成预测标签或交易信号。
CUSUM 选择事件时点,而不是预测方向
按固定时间间隔抽样时,安静时段和剧烈变动时段可能得到同样多的样本。事件采样改为只保留预先定义的价格变动触发时点,让研究者关注发生了足够累积移动之后的数据。它改变样本时间轴,不能因此被解释为已经识别出机会。
Page 在 1954 年讨论了持续检查过程的累积和方案;金融机器学习中的 CUSUM 滤波器把这类“持续累积偏差、到阈值便发出事件”的思路应用到价格变化上。Page 的论文与 《Advances in Financial Machine Learning》第 2 章提供了方法背景。mlfinpy 的过滤文档把过滤器用于选出后续标注或建模的事件时点。
这一步应与后续任务分开:过滤器决定在哪里开始观察;特征工程和模型决定使用哪些信息;标签规则再决定怎样描述事件之后的结果。每根 K 线都做一个预测和仅在事件触发时建立样本,代表不同的抽样问题。
正向与负向累积如何更新
令 (P_t) 为时点 (t) 的收盘价,并计算相邻收盘价的对数收益:
\[ r_t=\ln(P_t/P_{t-1}). \]
令 (S^+_t) 和 (S^-_t) 分别表示非负的正向累积值与非正的负向累积值:
\[ S^+_t=\max(0,S^+_{t-1}+r_t),\qquad S^-_t=\min(0,S^-_{t-1}+r_t). \]
对于对称阈值 (h>0),本文采用严格触发条件:当 (S^+_t>h) 或 (S^-_t<-h) 时记录事件,并把触发侧重置为零。另一侧依照自身递推继续更新;不要把“记录一个事件”误写成不加区分地清空所有状态。
滤波器的输出通常是事件时间戳或事件对应的收盘行。它不是每个事件的方向标签,也不是价格目标。实现还可能支持随时间变化的 (h_t),但无论阈值固定还是动态,累积量和阈值都必须使用相同的收益单位。
逐步计算一个对称阈值示例
假设收盘价依次为 100.00、100.20、100.40、100.60、100.40、100.20、100.00,且 (h=0.005) 个对数收益单位。以下是为说明规则而设的假想数字,不是实际市场行情或成交记录。
前三段正向对数收益分别约为 0.001998、0.001994、0.001992。因为三段都朝同一方向累积,至 100.60 时的正向总量为
\[ \ln(100.60/100.00)=0.005982\text{(约 }0.598\%\text{)}. \]
该值高于 0.005,因此在 100.60 这一收盘时点触发正向事件,之后将 (S^+) 归零。价格随后回落时,向下累积从重置后的状态开始;从 100.60 到 100.00 的总对数变化为
\[ \ln(100.00/100.60)=-0.005982. \]
因此,在 100.00 这一收盘时点触发负向事件,并重置 (S^-)。路径先前出现过上行,并不阻止回落之后另一次事件发生。每次触发之间究竟有多少根 K 线,取决于实际路径,不应假设为固定间隔。
阈值单位、边界和动态调整
这里的 (r_t) 与 (h) 都以无量纲的对数收益表示。若用百分比显示阈值 0.005,它约等于 0.5% 的连续复利收益尺度;不能把 0.005 直接当作价格金额,也不能不经转换便与波动率百分数以外的指标比较。对较小变动,对数收益接近简单收益,但两者并不完全相同。
教程对触发条件有时写作达到或超过阈值((\geq h)),而 mlfinpy 当前对称过滤代码在比较时使用严格的大于和小于((S^+>h)、(S^-<-h))。文档与实现代码应一并查看。连续价格数据恰好落在边界上的机会或许不多,但量化数据可能经过舍入,恰等于阈值时是否触发就会影响可复现性;研究中应明确选定并固定比较规则。
固定阈值简单、容易复现,却会在不同波动状态下形成不同的事件密度。一种动态方案可按历史波动尺度调整 (h_t),例如将历史估计的收益波动乘以预先选好的常数。估计必须因果:在处理时点 (t) 的收益时,只能使用当时已经可得的数据,并记录估计窗口、更新频率以及阈值对应的时点。用完整样本计算波动率再回填历史阈值会泄漏未来信息。动态阈值让事件间隔随尺度变化,但不是对未来波动或最佳阈值的保证。
对数收益要求价格为正
(\ln(P_t/P_{t-1})) 要求两期价格都为正。遇到零价、负价或不适合对数收益的序列,公式无定义或不再有原有解释。不要为了让代码运行而默默取对数绝对值或任意平移价格;这会改变测量对象。应选用适合该数据的收益或价格变动定义,并相应重设阈值、说明单位、检查数据清理规则。
用于事件采样的价格序列也要定义清楚:是交易价、买卖中价、结算价还是调整后的收盘价?不同序列可能产生不同的触发时点。拆股等导致的机械价格跳变、缺失报价和时间戳错位,都可能制造并非市场变动信号的累积量。
时间 K 线、事件时间与收盘可见性
在时间 K 线上,输入可以是每分钟、每小时或每日收盘价;CUSUM 会在触发阈值的那些 K 线留下事件,因此相邻事件的时间间隔通常不规则。事件时间序列不是匀速的时钟:一段时间内可能没有事件,也可能在较短时段内连续产生事件。下游模型若依赖时间间隔、波动或持有期,应把间隔本身作为明确的变量处理,不能默认每两个样本等于一个固定交易日。
若 (r_t) 使用收盘价,只有在收盘价已经形成并可见后才能计算该根 K 线的收益和触发结果。因此,用该收盘价同时检测信号又假设能无延迟地在同一价格成交,会引入不现实的时序假设。回测应按可获得数据的时间安排决策,并在下一可执行报价或成交价模拟下单;若使用盘中数据,也要说明当时实际可见的价格以及数据和订单延迟。
阈值决定事件密度,也改变噪声取舍
阈值较低时,累积路径更容易触发,事件数量通常增加;这会留下较多较小波动,同时增加噪声样本、手续费和执行负担。阈值较高时,事件较少且移动较大才被记录,但小幅或较快反转的变化可能被遗漏。改变阈值不仅改变样本数,还会改变事件分布、重叠程度和模型接收到的数据,因此不能只挑选回测表现最好的阈值,再把它当成事先已知的设计。
先在训练期或研究设计中确定候选阈值,再用时间顺序的样本外区间评估事件率、事件间隔和后续任务。若尝试很多阈值、资产和日期区间,报告这种选择过程;只展示最佳结果会夸大证据。阈值没有脱离预测目标、市场和数据频率而普遍最佳的取值。
验证、费用与三个不同的 CUSUM 用途
验证应保留时间顺序,并在每个训练折中仅用当时可得数据估计动态阈值。若后续标签使用了多个未来时点,训练与测试事件的结果区间可能重叠,须采用与标签区间相符的清除或隔离规则。评估模型时也应计入点差、手续费、滑点、资金费率、借券费用和成交可行性;事件越频繁,成本越可能改变净结果。
价格事件滤波器要与回归稳定性检验区分。回归 CUSUM 通常累积递归残差,用统计边界检验回归系数是否稳定;它检验的是模型残差及其假设,并非这里对价格对数收益设置双侧阈值的事件过滤器。可参阅回归 CUSUM 结构稳定性检验指南。
同样,事件滤波器不会替三重障碍法生成结果标签。先由 CUSUM 选择事件开始时点,再由研究者规定的止盈、止损和时间期限规则,为之后的路径计算 (y)。参见三重障碍法金融事件标注指南。触发只表示指定累积变化达到阈值;它不预测方向,不保证平稳性、流动性或盈利,也不证明扣除交易成本后存在优势。
常见问题
Q1CUSUM 事件触发是否代表看涨或看跌信号?
不代表。正向或负向触发描述的是哪一侧累计变化越过了阈值,用于标记观察时点。是否预测下一段方向,需要另行定义特征、预测目标和验证方法。
Q2阈值等于累积值时是否触发?
取决于约定。过滤教程的文字有时用“大于或等于”表达,而 mlfinpy 当前实现使用严格的大于或小于。应在研究和代码中选择同一规则,并固定边界处理。
Q3CUSUM 滤波器能否保证样本平稳或策略盈利?
不能。它按累积价格变化选择事件,不会证明收益平稳、成交有流动性或策略扣费后盈利。必须单独检查模型假设、样本外结果和交易成本。
资料来源与延伸阅读
报告问题
我们会准备一封包含本文链接的邮件。发送后,Mark 才会收到你的反馈
快速检查
读完指南后,用 3 道题检查一下
问题 01
当正向累积值首次严格大于阈值 h 时,按本文规则应如何处理?
选择答案即可查看解释