这类错误最麻烦的地方,不是程序报错,而是程序运行得很顺。缺失值被填上,因子矩阵变得规整,模型能够正常训练,回测曲线也不会主动告诉你其中混入了未来信息。等到策略接入实时数据,历史样本里被人为制造出来的平滑性消失,信号强度、换手节奏和风险暴露都会发生变化。
复盘一套策略时,真正需要追问的不是“缺失值有没有被处理”,而是三个更具体的问题:
- 当时能不能看到这条数据?
- 插补过程使用了哪些信息?
- 缺失本身是否已经携带了风险信号?
如果这三个问题没有被区分,所谓“数据清洗”很容易变成对历史数据的二次加工。回测阶段得到的不是策略在当时能看到的市场,而是经过事后信息修补后的市场。
典型实现往往看起来没有问题:价格字段使用前向填充,财务因子使用双向线性插值。单看语法,它们都属于常见的数据处理操作;放到量化回测中,问题却完全不同。前者可能把停牌、断流和真实无成交混在一起,后者则可能在计算某个时点的因子时,访问该时点之后才出现的观测值。
插补不是修补数据,而是在修补关于数据生成过程的假设。假设错了,数据越整齐,回测越危险。
缺失值插补的隐形陷阱:为何回测表现与实盘背离
金融时间序列中的缺失值,通常来自几种不同过程。交易日之外的日期并不一定是缺失,它可能只是市场没有开市;接口传输中断造成的空值,和停牌期间没有成交造成的空值,也不能按照同一规则处理。
在实际数据中,至少要区分以下几种情况:
- 交易所休市或标的尚未上市,时间轴上本来就不应该存在观测值;
- 数据供应商传输中断,理论上应该存在的字段没有到达;
- 标的停牌,价格和成交量在一段时间内没有新的市场成交信息;
- 低流动性资产在某些时段没有成交,成交量可能为零,也可能被数据源记录为空;
- 财务数据尚未披露,或者披露后还没有进入数据接口;
- 后续修订覆盖了原始版本,导致今天下载的数据与当时可见的数据不一致。
这些情况在表格里都可能表现为 NaN,但它们对应的经济含义并不相同。把它们都交给同一个 fillna 函数,相当于默认它们来自同一种随机机制。这个默认通常没有经过验证。
机器学习模型不能直接处理缺失值,或者至少不能在所有实现中稳定地处理缺失值,因此训练前往往需要插补、删除样本,或者将缺失状态编码为特征。问题不在于“必须插补”这件事,而在于插补是否改变了原始数据的时间关系和横截面关系。
价格、成交量和财务因子不能用同一套规则
对日线收盘价做前向填充,有时可以表达“在没有新成交之前,沿用上一条已知价格”的工程假设。但这个假设只在特定场景下成立。停牌期间没有新的成交价,不代表市场价值保持不变;复牌后的跳空、涨跌停和流动性冲击,都可能在缺失区间结束后集中体现。
对成交量直接填零也有类似问题。真正的零成交,表示数据源确认该时段没有成交;字段缺失,则只表示这条记录没有被观测到。二者混用,会让量价因子把数据故障当成市场行为。
财务因子的缺失通常更加复杂。企业披露有明确的报告期、公告时间和数据可见时间。某个报告期的财务指标,不能因为数据库后来补齐了,就被当成当时已经可用于交易的因子。对于回测来说,财务数据的公开时间和版本时间往往比报告期本身更重要。
| 数据类型 | 常见缺失场景 | 容易造成偏差的做法 | 更稳妥的处理方向 |
|---|---|---|---|
| 日线收盘价 | 停牌、接口中断、行情缺口 | 对所有空值双向线性插值 | 区分停牌与断流,必要时前向填充并保留状态标志 |
| 成交量 | 低流动性、接口缺字段、无成交 | 将所有空值直接填零 | 先确认数据语义,再决定保留空值、填零或剔除 |
| 财务因子 | 尚未披露、披露延迟、历史修订 | 使用全样本均值或未来版本 | 按公开可见时间截断,保留公告版本和缺失标志 |
| 分钟级价量 | 接口断流、局部数据丢失 | 用整段均值补齐 | 对连续断流区间做质量标记,必要时放弃该区间 |
| 复权字段 | 除权除息、复权因子更新 | 将价格缺口当作普通缺失 | 明确复权口径,单独处理公司行为 |
判断插补是否合理,可以先问一句:填进去的值,是否在当时真的能够被交易系统观察到?
如果答案是否定的,那么即使插补值在统计意义上很接近真实值,也不适合直接用于历史策略回测。回测需要重建的是信息集,而不是事后最接近真实价格的完整数据集。
被平滑的因子会制造虚假的稳定性
双向插值最直观的效果是让曲线变得连续。对于展示图表,这种连续性可能很舒服;对于交易信号,它可能改变波动率、拐点和排序结果。
假设一个财务字段在两个已知观测之间存在较长缺口。线性插值会把缺口内部的变化强行设定为平滑过渡。可是在真实市场中,财务指标可能因为公告、重述、会计口径变化或数据补录而出现跳变。中间那些点并不是市场曾经观测到的值,而是算法根据两端信息构造出来的路径。
当该字段被用来计算趋势、变化率、分位数或标准化因子时,问题会继续放大:
1. 缺口内部的波动被压低;
2. 因子变化时间被提前或推迟;
3. 截面排名变得过于稳定;
4. 与其他字段的相关关系被重新塑造;
5. 下游模型把人工生成的平滑性当成可重复信号。
回测曲线因此可能表现得更“干净”,但这种干净不一定来自策略能力。它可能只是缺失值处理过程消除了真实数据中的不确定性。
数据缺失机制的深度拆解:MCAR、MAR 与 MNAR
缺失值机制通常用 MCAR、MAR 和 MNAR 三个概念描述。它们不是给数据贴上的固定标签,而是对“为什么缺失”的不同假设。插补方法是否有效,首先取决于这个假设是否接近真实的数据生成过程。
MCAR:缺失与已知信息和未知信息都无关
MCAR,即完全随机缺失,指缺失事件与已经观测到的变量、尚未观测到的变量都没有系统关系。
例如,某次传输异常随机丢失了部分记录,而且丢失概率不依赖于标的规模、行业、价格水平、波动率或当天的市场状态。这个前提在现实中并不容易完全成立,但在局部的数据链路故障中可以作为近似。
MCAR 场景下,删除缺失样本通常不会系统性改变总体分布,简单插补也可能不会造成明显方向性偏差。不过,“不会明显偏差”不等于“可以不审计”。随机丢失仍可能改变样本量、时间连续性和成交时点,尤其是高频数据。
诊断时,可以比较缺失标志与已观测变量之间的关系。例如,将“该字段是否缺失”作为一个二元变量,观察它是否与波动率、成交额、行业、交易时段或其他已知字段存在稳定联系。如果存在明显联系,就不能再轻易把它归为 MCAR。
MAR:缺失由已观测变量解释
MAR,即随机缺失,指缺失概率与已经观测到的变量有关,但在控制这些变量后,与缺失值本身没有额外关系。
财务数据披露延迟可以作为一种近似场景:不同规模、行业或地区的公司,数据进入系统的时间可能不同。此时,缺失状态与公司特征有关,不能用一个不区分标的的全局均值简单填充。
MAR 场景可以使用条件模型,根据已观测变量估计缺失值。多重插补链式方程,正是常被用于这类多变量缺失问题的方法之一。它为不同字段建立条件模型,使用其他变量反复更新缺失值。
但多重插补并不会自动解决时间问题。若条件模型使用了未来日期的财务字段、未来截面的统计量,或者包含回测时点尚不可见的修订值,那么复杂的插补模型只是在更复杂地引入泄漏。
MNAR:缺失本身与未观测值或风险状态有关
MNAR,即非随机缺失,指缺失概率与缺失值本身或其背后的未观测状态有关。
停牌、连续无成交、重大事件期间数据中断,都可能接近 MNAR。这里的缺失不是普通的数据故障,而可能与公司经营状况、市场风险、交易限制或投资者预期直接相关。缺失发生本身就是信息。
在 MNAR 场景中,简单填充很容易产生方向性偏差。把停牌期间价格保持不变,等于假设市场价值没有变化;把连续无成交视为普通零成交,等于假设市场参与者已经充分表达了价格意见。这些假设都可能不成立。
| 缺失机制 | 典型特征 | 处理难度 | 简单插补的主要风险 | 更适合的分析方式 |
|---|---|---|---|---|
| MCAR | 缺失与数据内容及市场状态都无明显关系 | 较低 | 样本量下降、时间断裂 | 删除、简单插补,并检查随机性 |
| MAR | 缺失与规模、行业、流动性等已观测变量有关 | 中等 | 忽略条件差异,造成横截面偏差 | 条件插补、多重插补、分组建模 |
| MNAR | 缺失与风险状态、停牌原因或真实值有关 | 较高 | 缺失信号被抹平,方向性偏差 | 单独建模、敏感性分析、显式剔除 |
现实数据很少能仅靠一个统计检验就确定缺失机制。MCAR、MAR 和 MNAR 更像是建模时需要不断验证的工作假设。尤其是 MNAR,往往要结合市场制度、公司行为和数据供应商的记录来判断。
一个实用做法是保留缺失标志,而不是在插补后把原始状态彻底覆盖。模型可以同时看到“填补后的数值”和“这个值曾经缺失过”两个信息。对于停牌、披露延迟和流动性异常,缺失状态本身可能就是风险因子。
前视偏差的触发逻辑与规避策略
前视偏差的核心不在于某个数值是否准确,而在于该数值在交易时点是否可获得。
回测在时间点 t 计算信号时,只能使用当时信息集中的数据。某条数据在后来被修订得更准确,不代表它在 t 时点已经可以被策略使用。任何把未来观测、未来统计量或未来修订版本带回过去的处理,都可能构成前视偏差。
插补引入前视偏差,常见有以下几条路径。
双向插值读取了缺口之后的信息
双向插值的问题,不是线性插值这个数学形式本身,而是它可能同时使用缺口前后的观测值。如果回测在较早时间点计算因子,缺口后面的值当时并不存在,却被算法拿来确定当前值。
这在整段数据预处理时尤其隐蔽。程序先对全历史数据完成插补,再把结果交给回测引擎。回测引擎看到的是一张已经被未来信息修补过的表,并不会知道某些值在当时尚不可见。
正确做法不是简单地把双向参数改成单向参数,而是明确插补的时间边界。每次计算时,插补函数都应接收当前时间,只能访问不晚于该时间已经公开并可用的信息。对在线数据而言,未来区间甚至不应进入当前函数的可用数据集。
全样本统计量污染了历史样本
全样本均值、标准差、分位数和归一化边界,都可能把未来分布带回过去。
例如,用整段历史数据计算标准化参数,再将早期样本转换为标准分数,早期样本实际上已经使用了后续阶段的均值和波动率。市场结构发生变化时,这种污染会更加明显,因为后期市场状态可能与早期完全不同。
滚动统计和扩展窗口可以降低这种风险,但前提是窗口边界设计正确。扩展窗口只使用当前时点之前的数据,滚动窗口则还需要明确窗口长度、最小观测数和缺失值处理规则。对于信号在开盘前生成还是收盘后生成,也要区分数据的实际公开时刻和策略的实际执行时刻。
截面操作也可能产生时间泄漏
前视偏差不只发生在纵向时间序列中。全市场截面排序、分位数转换和行业中性化,同样依赖一个隐含前提:参与计算的所有标的在当时都已经有可用数据。
如果一个回测时点使用了后来补齐的财务值,或者使用了当前完整成分股名单来重构过去的截面,就算没有直接引用未来价格,也可能把未来信息带回历史。截面统计必须基于当时实际可见的股票池和字段版本。
如何做代码层面的约束
前视偏差不能只靠人工阅读代码发现。数据接口应当从设计上限制未来访问。
可以在数据加载层引入 current_time 参数,所有读取操作都先按该时间截断。插补函数、标准化函数和特征工程函数都必须接收这个边界,不允许在内部默认使用完整数据表的最大日期。
审计时可以重点检查以下内容:
- 是否存在对完整数据表直接调用
mean、std、rank或quantile的操作; - 插值是否使用了当前时点之后的观测;
- 滚动窗口是否发生了居中计算;
- 缺失值填充是否在切分训练集和测试集之前完成;
- 训练阶段保存的模型参数是否只来自当时可见样本;
- 财务指标是否按公开时间,而不是报告期结束时间进入数据集;
- 股票池、行业分类和指数成分是否使用了历史版本;
- 交易信号生成时,收盘价、成交量和公司行为信息是否已经公开并可用。
统计层面也需要做反向验证。可以把同一套因子分别用严格时间截断和全样本预处理运行,比较两者的差异。如果结果异常接近,说明该字段可能对未来信息不敏感;如果差异很大,则应进一步定位是哪一个清洗步骤造成了变化。
不要把因子短期表现异常强、不同市场阶段都过于稳定,直接当作策略优势。它也可能是时间泄漏的表现。尤其是经过插补和全样本标准化后,因子曲线变得过于平滑,应该优先检查数据处理链路,而不是继续调参。
从均值填充到多重插补:复杂插补算法中的过拟合风险
插补方法越复杂,不代表结果越接近真实市场。复杂模型能够拟合更多变量关系,也就可能把更多不属于当时信息集的关系带入历史。
均值和中位数插补:简单,但会改变分布
均值或中位数插补的优势是透明、稳定、计算成本低。它们适合用作敏感性分析的基线,也适合处理那些对精确值不敏感、缺失比例较低的字段。
问题在于,所有缺失值被压到同一个位置,导致:
- 方差被压低;
- 尾部被削弱;
- 变量与其他字段的相关关系发生变化;
- 横截面排序出现大量并列;
- 波动率、变化率和极值类因子失真。
如果使用均值填充财务因子,再根据该因子进行分组,缺失样本可能被集中到一个人为的中间位置。结果看起来不像异常值,却也不代表真实的公司状态。
前向填充:适合延续性字段,但不能代替状态建模
前向填充通常适用于某些在短时间内可以视为不变的状态字段,或者用于表达“在新观测到来之前沿用最近已知值”的数据口径。
但它不应被当成通用方案。价格、财务指标和估值字段的经济含义不同。停牌价格沿用上一交易日价格,并不意味着该价格仍然可交易;财务指标沿用上一版本,也不意味着市场在整个期间都把它当作最新信息。
更稳妥的做法是将填充后的值与以下字段同时保留:
- 距离上次真实观测的时间;
- 是否处于停牌或无成交状态;
- 是否属于供应商补录;
- 是否使用了历史版本延续;
- 当前值是原始值还是插补值。
这些字段能帮助模型区分“真实观测”和“算法延续”。
K近邻插补:相似样本不一定处于相似市场状态
K近邻插补通过特征空间寻找相似样本,再使用邻近样本的值进行填补。它比单一均值更有条件性,但对距离定义非常敏感。
在金融数据中,两个标的可能具有相似的收益变化,却处在不同价格水平;两个公司可能行业相同,却处在不同的披露阶段;两个时间段的波动率可能接近,但市场流动性和交易制度不同。直接使用欧氏距离,容易把不具备可比性的样本放在一起。
使用 K近邻前,至少需要明确:
- 距离计算使用价格、收益率还是标准化后的特征;
- 相似样本是否必须来自当前时点之前;
- 是否允许不同市场阶段的样本互相填充;
- 邻居数量是否会导致过度平滑;
- 缺失标志是否参与距离计算;
- 计算规模是否满足生产环境要求。
如果相似样本搜索使用了完整数据集,K近邻同样会发生前视偏差。算法名称本身不能提供时间上的豁免。
多重插补:能处理条件关系,也能放大错误假设
多重插补通过多轮条件模型处理多个字段之间的关系,理论上适合复杂的多变量缺失场景。但在金融数据中,它有三个额外风险。
第一是时间边界。每个条件模型都必须只使用当时已经公开且可用的协变量。只要其中一个协变量包含未来值,最终插补结果就会受到污染。
第二是模型过拟合。财务面板中的行业、规模、盈利能力和估值字段本身高度相关。多重插补可能在历史样本中拟合出很强的关系,但这些关系未必在不同市场阶段稳定存在。
第三是计算与审计成本。多轮迭代、多个字段和大规模面板会显著增加运算量。越复杂的插补链路,越需要保存每轮使用的数据版本、参数和时间边界,否则出问题后很难追溯。
| 方法 | 主要优点 | 主要风险 | 更适合的场景 |
|---|---|---|---|
| 前向填充 | 简单、可在线执行、时间边界清楚 | 可能掩盖状态变化 | 有明确延续逻辑的日线字段 |
| 单向线性插值 | 比固定值平滑,容易实现 | 仍可能制造不存在的中间路径 | 短缺口、变化较平稳且不含事件的数据 |
| 均值或中位数 | 成本低、便于做基线 | 压低波动和横截面离散度 | 低敏感字段或敏感性分析 |
| K近邻 | 能利用横截面相似性 | 距离定义敏感,计算量较大 | 低维、样本边界清晰的截面数据 |
| 多重插补 | 能处理多变量条件关系 | 过拟合、迭代成本和泄漏风险较高 | 有充分审计条件的基本面面板 |
| 保留缺失 | 不制造数值路径 | 下游模型需要原生缺失处理能力 | 缺失本身可能带有信号的场景 |
在工程中,插补方法应该按字段和缺失机制分别选择,而不是全表统一处理。价格、成交量、财务因子和技术指标可以拥有不同的缺失策略。策略代码如果只有一个总开关,例如 fill_method='ffill',通常意味着数据语义还没有被充分拆开。
构建稳健的数据清洗流水线:点时间数据的应用实践
点时间数据,也就是 PIT 数据,解决的不是“如何把空值填满”,而是“在过去某个时间点,系统究竟应该看到什么”。
这里需要特别纠正一个容易写反的时间关系:一条数据不是到了 as-of date 之后才可以被回测使用,也不是只要报告期已经结束就能被当作已知信息。对于带有可见时间戳的数据,正确的判断是:
- 回测当前时点为
t时,只能使用公开时间不晚于t的数据; - 数据的公开时间或可用时间早于、等于当前回测时点,才可能进入当时的信息集;
- 数据的公开时间晚于当前回测时点,即使报告期更早,也不能被带回过去使用;
- 如果公告发生在收盘后,还要根据策略的执行时点判断它最早影响下一个交易时段,不能简单按自然日归类;
- 数据进入本地系统的时间可以用于描述数据链路,但不能自动等同于市场公开时间。
换句话说,as-of date 是重建信息集时的截止边界:在这个时点上,所有公开时间不晚于该边界、并且符合数据源可用规则的记录,才有资格被回测读取。不是排除该日期之前的数据,而是排除在该日期之后才公开的数据。
这也是点时间数据最容易被误解的地方。报告期、可见时间和入库时间描述的是三件不同的事情。报告期回答“指标反映的是哪一段经营期间”;可见时间回答“市场最早什么时候可能看到这条信息”;入库时间回答“这条信息什么时候进入某个数据库或研究系统”。三者不能互相替代。
报告期、可见时间和入库时间必须分开
一条财务数据记录,最好同时保留报告期、公告时间、数据进入系统的时间和版本信息。对于经过修订的数据,还要能够区分初始披露版本与后续修订版本。
常见的时间字段包括:
period_end_date:指标对应的报告期结束时间;filing_date:企业或监管系统公布数据的时间;available_date:策略数据源允许使用该字段的时间;as_of_date:回测重建信息集时采用的可见时间边界;revision_id:同一指标不同版本的修订标识;ingest_time:数据进入本地系统的时间。
这些字段不是越多越好,而是要定义清楚各自的语义。最危险的情况,是数据表只有一个日期字段,开发者默认它同时代表报告期、公告期和交易可用期。
例如,一家公司披露某季度财务数据时,报告期结束日可能早于公告日;数据供应商又可能在公告后稍晚才完成解析和入库。对于市场回测,至少要回答两个问题:公告在什么时间公开,以及策略在什么时间能够读取到它。如果使用的是供应商整理后的数据,还要明确回测模拟的是市场公开信息,还是某个数据接口实际提供给策略的时间。
清洗流水线应当先记录,再处理
一个稳健的流程,应该尽量保留原始字段,不要在第一步就覆盖数据。可以按照以下顺序组织:
1. 载入原始数据,并保留供应商字段、版本信息和原始时间戳;
2. 识别交易日、停牌日、无成交日和接口缺失;
3. 统计字段、标的和时间维度上的缺失模式;
4. 根据缺失机制判断哪些值可以插补,哪些值应该保留为空;
5. 按当前回测时间截断可用数据,只保留公开时间不晚于该时点的记录;
6. 在截断后的数据上执行插补和标准化;
7. 保存插补标志、缺失持续时间和数据版本;
8. 对未来索引访问、异常填充和时间错位执行断言;
9. 将原始字段、处理字段和审计元数据一同入库。
其中最关键的一步,是先做时间截断,再做插补。如果先对完整历史表处理,再切分回测区间,未来信息已经在切分之前进入了数据。
这条顺序对财务数据尤其重要。假设某个报告期的指标在后来发生修订,今天下载的数据库只保留修订后的版本。如果回测直接读取这张表,即使把报告期正确地放回过去,也仍然可能使用了当时尚不存在的修订值。点时间数据不仅要按日期切分,还要按版本切分。
把时间边界写进接口,而不是写在注释里
插补函数应当显式接收当前时间参数,而不是在内部直接使用整张表的最大日期。所有函数都要对可用数据做边界过滤:公开时间晚于当前回测时点的数据不能进入当前计算。
在实现上,可以把数据处理拆成两个对象:一个负责产生当前时点可见的数据集,另一个负责在这个数据集内完成插补。这样做的好处是,插补模块不需要自行判断哪些日期属于未来,也不容易因为一次重构而绕过时间限制。
标准化同样如此。全样本的均值和标准差不应直接服务于历史回测。可以使用截至当前时点的扩展窗口,或者严格限定的滚动窗口。窗口大小、最小样本数和缺失处理方式都应该记录在配置中,而不是依赖库函数默认值。
对于公告数据,还应把市场公开时间与策略执行时间分开。收盘后发布的数据,即使日期标签与当日相同,也不应被用于当日收盘前生成的信号。研究系统如果只保存日期而没有时间,至少要采用保守规则,把这类信息推迟到下一个明确可用的交易时段。
原始字段和插补字段必须分开保存
如果插补结果直接覆盖原始字段,后续审计会非常困难。建议至少保留三类信息:
- 原始值:数据源最初提供的内容;
- 处理值:经过插补或清洗后供模型使用的内容;
- 状态字段:是否缺失、是否插补、使用何种方法、距离最近真实观测多久。
当策略出现异常时,研究者需要回答“这个信号是由真实数据触发,还是由填充值触发”。没有双版本存储和状态字段,就无法把问题定位到具体数据处理步骤。
如果数据存在多个版本,还应保存版本生效时间和版本来源。回测不一定要永远使用最初披露版本,但必须明确选择了哪一种口径。使用后续修订数据研究长期基本面关系,可以是一项独立研究;把它混入模拟当时交易决策的回测,则是另一回事。
用反事实重跑检查插补影响
插补审计不应只检查代码有没有报错,还要比较不同处理方案对策略的影响。
可以分别使用原始缺失、严格单向处理、保守剔除和候选复杂插补方案运行回测,然后观察:
- 信号出现时间是否改变;
- 因子排序是否改变;
- 缺失较多的标的是否贡献了异常收益;
- 交易成本和换手率是否受影响;
- 风险指标是否集中在插补区间;
- 结果是否依赖某一批修订后的数据;
- 只使用当时公开版本后,收益和回撤是否仍然成立。
如果策略只在某种复杂插补方案下表现良好,而在保守处理下完全失效,不能立即认为复杂方法更先进。更应该检查它是否利用了未来信息,或者把缺失状态中的风险信号错误地平滑掉了。
反事实重跑的价值,不在于找出一个“最漂亮”的填充方案,而在于判断策略结论是否依赖某个未经验证的数据假设。一个对处理方式高度敏感的策略,应该把这种敏感性本身视为风险,而不是继续通过调参掩盖它。
模型局限性与参数建议
任何插补方法都不是对 MNAR 的自动修复。对于停牌、低流动性、重大事件和披露异常等场景,缺失本身往往与风险状态有关。最稳妥的做法不是强行还原一个“看起来连续”的数值,而是明确告诉模型:这里的信息不完整。
一种方案是使用能够处理缺失值的模型,并将缺失标志作为独立特征。这样,模型可以学习“某字段缺失”是否与未来收益或风险有关,但必须防止模型把数据供应商的偶然故障当成稳定交易信号。
另一种方案是对缺失严重或机制明显非随机的样本做显式剔除。这会降低样本量,也可能改变策略适用范围,但至少不会用虚构数据代替真实的不确定性。剔除规则需要在回测前固定,不能根据结果临时调整。
还可以进行敏感性分析:对同一批缺失数据采用保持、前向填充、保守剔除等多种方案,观察策略结论是否稳定。如果收益、回撤和持仓结构对处理方式极其敏感,说明数据层仍然是策略风险的重要来源。
在配置层面,更值得关注的不是某个万能阈值,而是规则是否能够解释:
- 某字段缺失到什么程度后不再适合插补;
- 连续缺失多长时间后必须标记为异常状态;
- 财务因子多久未更新时需要降低信任度;
- 价格和成交量的缺失是否应触发交易限制;
- 发生修订时,历史回测是否必须重建版本;
- 新数据进入系统后,旧结果如何复现和审计。
这些规则不一定适用于所有市场和所有策略。短周期交易关注的是分钟级断流、成交确认和交易所状态;基本面策略更关注公告时间、版本修订和财报可见性。数据处理方案必须服从字段的经济含义和策略的交易节奏。
回测审计也不应只关注最终收益。每次运行至少应记录数据版本、点时间截止边界、插补方法、填充数量、缺失标志比例、被剔除样本和模型训练区间。只有这些信息完整,策略表现发生变化时,才有机会判断问题来自市场、模型还是数据处理。
金融数据缺失值处理的底线并不复杂:不把未知写成已知,不把未来写成过去,不把停牌写成稳定价格,也不把接口空值直接解释成市场行为。
策略回撤未必源于因子失效。很多时候,真正先失效的是数据层对“当时可见信息”的还原。插补算法只是其中一个环节,但它可能把缺失机制、时间关系和风险信号同时改写。
点时间数据的核心也不是排除某个日期之前的信息,而是准确重建每个回测时点能够获得的信息集:报告期说明数据描述的对象,公开时间说明市场何时可能看到它,入库时间说明研究系统何时接收到它,版本信息则说明这是不是当时已经存在的那一版。只有把这些时间含义分开,回测才不会把报告期误当成可见时间,也不会把后来入库或修订的数据提前带回历史。
只要点时间边界、原始字段和缺失状态没有被保留下来,任何漂亮的回测结果都需要重新审视。迷人的曲线可能不是信号更强,而是数据被处理得过于顺滑。
相关阅读: 交易员决策疲劳应对策略:减少日内无效交易的系统化方案 、 全职交易员的社交孤立:享受孤独还是走向心理失衡?.
