数据与算法

数据与算法常见问题解答

凌晨三点,屏幕还亮着。LSTM的损失曲线终于收敛到一个让人暂时安心的数值,回测报告里的夏普比率也像一盏昏黄的灯,照着一条看起来相当顺滑的净值曲线。你揉了揉眼睛,觉得这一周的失眠总算有了回报——直到模型接入实盘的第一天,信号开始偏离,成交价格和回测假设对不上,盈亏曲线像一根被风吹散的线。…

数据与算法常见问题解答

那一刻,很多人会先怀疑模型:是不是网络层数不够,参数没有调好,特征还不够丰富,或者还需要换一种更复杂的算法?但量化系统从回测走向实盘时,最先暴露出来的问题,常常并不在算法本身,而在数据进入算法之前已经悄悄发生了变化。

回测使用的数据可能缺了集合竞价,实盘接收的行情却包含了另一套时间戳;研究阶段使用的是经过复权处理的历史序列,交易阶段拿到的却是未复权或复权方式不同的数据;训练特征按照收盘后的信息生成,回测却把它当成了开盘前已经知道的信号。模型没有突然变笨,只是它在研究环境里看到的市场,和真实交易中的市场从来不是同一个市场。

在量化交易的实际研发中,数据工程往往占据远超直觉的工作量。这个比例没有必要被固定成一个看似精确的数字,因为不同策略、市场和数据频率差异很大,但方向是确定的:模型训练只是链条的一部分,数据采集、清洗、对齐、存储、验证和回放,才是决定这条链能不能稳定运行的基础。

我们太容易被算法的名字吸引,也太愿意相信更复杂的模型会带来更确定的未来,却常常忘记:模型只是数据讲述的故事,而故事是否可信,从落笔的第一行就已经埋下伏笔。

模型只是数据讲述的故事,而故事是否可信,从落笔的第一行就已经埋下伏笔。

数据工程:量化模型研发的基石与时间分配

模型之外,时间究竟花在了哪里

初学者往往把量化研发理解成一个相对直接的过程:获取行情,构造因子,训练模型,运行回测,然后根据结果调整参数。真正进入流水线后,才会发现每一步后面都藏着大量不显眼的工作。

数据工程的时间通常被消耗在这些地方:

  • 检查交易日历,确认不同市场的开闭市时间是否一致;
  • 校验证券代码、合约代码和品种名称,避免同一资产在不同数据源中对应不同标识;
  • 处理停牌、涨跌停、临时停牌和无成交时段;
  • 判断缺失值是市场真实状态,还是数据供应商没有返回数据;
  • 区分零成交、零价格、空值和无效记录;
  • 对齐行情、财务数据、指数数据、宏观数据以及事件数据的生效时间;
  • 确认复权方式是否和研究目标一致;
  • 对重复记录、乱序记录和异常跳点进行标记,而不是简单删除;
  • 记录每次数据修订的来源、时间和处理规则;
  • 让回测环境能够重放当时实际可获得的信息,而不是使用今天回头整理过的历史数据。

这些工作没有技术博客中常见的炫目效果。一个清洗过的时间戳,和一个没有清洗过的时间戳,在图表上可能看不出区别;一条被正确剔除的异常成交,也不会在最终报告里留下醒目的标记。但它们会改变模型学习到的关系,改变回测中的成交顺序,甚至改变策略是否能在实盘中正常下单。

金融数据并不是一张静态表格。它带有时间、状态、来源和市场规则。每一个字段都有自己的语境,不能因为字段名看起来熟悉,就默认它可以直接进入模型。

例如,价格序列里的“收盘价”可能代表连续竞价阶段的最后成交,也可能经过某种补齐、调整或聚合。成交量可能是单市场的成交量,也可能包含不同口径的统计。财务指标可能按照公告日、报告期或数据入库日进行组织。若不先确定字段的经济含义,后面的特征工程再精细,也可能是在精确地处理一个错误对象。

数据字典不是文档装饰

量化团队经常拥有一套字段表,但字段表如果只记录名称和数据类型,作用仍然有限。真正有用的数据字典,至少应该回答几个问题:

1. 这个字段描述的是什么事件?

2. 它在什么时间点对市场参与者可见?

3. 它来自哪个数据源,是否经过供应商加工?

4. 它的缺失代表没有发生,还是暂时没有采集到?

5. 它是否会在未来被修订?

6. 它能否直接用于某个时间点的交易决策?

7. 它在不同市场、不同合约或不同交易阶段中是否保持相同含义?

这最后一个问题尤其容易被忽略。同名字段不一定同义,不同名字段也不一定完全不同。股票、期货、指数和基金的行情结构各有差异。股票有停牌和除权除息,期货有到期、换月、主力合约切换和夜盘,指数可能来自一套独立的计算规则。把它们强行放入统一表结构,虽然方便调用,却可能把重要的市场差异抹掉。

数据工程的目标并不是把所有数据变得一样,而是在统一接口的同时保留必要的差异。模型需要稳定的输入格式,研究人员却不能因此忘记这些输入各自代表什么。

数据管道要能解释,也要能回放

一套成熟的数据管道,不仅要把数据送到模型面前,还要能够解释数据为什么会变成现在的样子。

如果某一天的行情出现异常,研究人员应该能够追溯:

  • 原始数据是什么;
  • 哪个步骤修改了记录;
  • 修改依据是什么;
  • 是否有其他数据源可以交叉验证;
  • 修正后的结果会影响哪些策略;
  • 这次修正是否需要重新运行历史回测。

这也是版本管理在量化系统中的意义。数据版本并不是软件工程里的附属要求,而是研究可复现性的前提。同一套策略,如果使用不同时间下载、不同修订状态或不同复权结果的数据,回测结果出现差异并不奇怪。真正危险的是团队没有意识到差异的来源,最后把数据变化误判为策略变化。

对于生产系统,原始数据最好保留不可变副本,清洗后的数据则通过明确的处理流程生成。这样做会增加存储和维护成本,但能够避免一种非常麻烦的情况:某次清洗规则覆盖了原始记录,之后任何人都无法判断历史结果究竟来自市场,还是来自一条已经被遗忘的数据处理逻辑。

行情数据清洗的常见质量缺陷与处理标准

如果把数据比作一条河流,那么清洗并不是简单地把河水过滤一遍。金融数据里的泥沙有时来自采集错误,有时来自市场机制本身,还有一些则是不同数据源之间的口径差异。处理它们之前,必须先区分这三种情况。

缺失值:不是所有空白都应该填上

缺失值是行情处理中最常见的问题之一,也最容易被粗暴处理。很多流程会直接使用前值填充、线性插值或均值填充,但在金融市场里,填充行为本身可能创造出不存在的价格路径。

停牌期间没有成交,不等于价格沿用上一笔成交价自然移动;一个期货合约在某段时间没有交易,也不等于市场在这段时间里产生了连续的可交易报价;逐笔成交缺失,更不意味着可以用相邻成交记录补出一条看似完整的交易轨迹。

处理缺失值时,可以先把缺失分成几类:

  • 结构性缺失:某个品种在某个时段本来就没有交易,缺失是市场状态的一部分;
  • 采集性缺失:行情供应商或网络链路出现问题,原本应该存在的数据没有被记录;
  • 字段性缺失:某些品种不适用某个字段,例如部分资产没有与股票相同的财务指标;
  • 暂时性缺失:数据尚未到达,但后续可能补齐;
  • 异常性缺失:记录存在,但关键字段为空或不符合交易规则。

不同类型的缺失,处理方式不能相同。用于展示的日线图可以采用较温和的补齐方式,但用于成交模拟的逐笔数据,通常更需要保留缺失事实,并把数据不可用的区间传递给回测引擎。宁可让策略在某段时间明确无法交易,也不要用虚构的价格替它做决定。

异常值:先判断市场异常,再判断数据异常

价格突然跳变,不一定是坏数据。涨跌停、除权除息、合约换月、重大公告和流动性骤降,都可能导致价格出现明显变化。如果仅凭统计阈值删除极端值,可能把真实市场事件当作噪声抹掉。

相反,有些异常值并不显眼。例如:

  • 成交时间早于上一条记录;
  • 同一时间出现重复成交;
  • 成交量为负数;
  • 买一价高于卖一价;
  • 价格精度超过该市场允许的最小变动单位;
  • 成交价格明显偏离当时的盘口,却没有任何事件记录;
  • 某个品种的价格单位在数据源切换后发生变化;
  • 一分钟聚合数据的最高价低于最低价;
  • 合约已经到期,数据却仍然被当作可交易标的使用。

因此,异常检测不能只依赖一条规则。比较稳妥的做法是同时进行格式校验、市场规则校验、时间顺序校验和横截面比较。比如,某只股票单独出现跳点时,可以对照指数、同行业股票和原始逐笔记录;某个期货合约出现异常时,还要检查主力合约切换和夜盘时段。

处理异常值也不应只有“删除”这一种选项。可以根据问题性质进行标记、隔离、回补、降权或暂停使用。保留异常记录及其标签,往往比直接删除更有价值,因为未来策略研究可能恰恰需要区分正常市场波动和数据事故。

集合竞价:被忽略的开盘信息

许多低频或免费数据源对开盘前后的处理并不完整,尤其容易忽略集合竞价阶段。对于日线策略而言,这段数据未必总是决定性的;但对于开盘跳空、开盘反转、隔夜信息消化和短周期信号来说,集合竞价是市场重新定价的重要过程。

同样幅度的上涨,如果发生在集合竞价阶段和连续竞价阶段,其含义并不相同。前者可能体现大量订单在开盘前集中调整,后者则反映交易时间内逐步形成的买卖力量。模型如果只看到开盘价和收盘价,就无法分辨这两种路径。

这里有两个容易混淆的问题。第一,集合竞价数据是否完整;第二,策略在实际交易时是否能够使用这些数据。即使研究数据包含集合竞价,也不能自动假设策略能够以理论上的撮合价格成交。开盘价是在订单汇集和撮合后形成的结果,研究阶段不能把形成结果的信息反过来用于预测形成结果的决策。

时间戳对齐:所有因子都必须有明确的可见时刻

时间戳问题是数据泄露最常见的入口之一。指数行情、个股行情、新闻、财务公告、订单簿和外部数据,往往由不同系统产生,时间精度、时区、服务器时钟和推送延迟都可能不同。

在分钟级或日线级策略中,一些毫秒差异可能对结果影响有限;但对盘口因子、订单流因子和高频策略来说,毫秒甚至更细的时间顺序都可能改变因果关系。数据里先出现的记录,不一定先在市场中发生;数据接收时间,也不一定等于交易所发生时间。

实际处理时,至少要区分几种时间:

  • 事件发生时间;
  • 交易所时间;
  • 数据供应商接收时间;
  • 本地系统接收时间;
  • 写入数据库时间;
  • 策略实际可见时间。

用于研究的时间,不能只选择最精确的一个字段,而要根据策略的交易逻辑确定。若策略只能在数据到达后作出反应,那么使用事件发生时间进行无延迟回测,会高估策略的反应能力。若某个字段在收盘后才发布,就不能仅因为它的日期属于当天,就把它放入当天开盘信号。

时间对齐还涉及不同频率数据的合并。将日线财务指标与分钟行情合并时,应该按照“信息可见时间”连接,而不是简单按照自然日连接。将宏观数据和期货行情合并时,也要考虑数据发布时间和交易时段。看起来只是一次数据库连接,实际上决定了模型是否看到了当时不可能看到的信息。

复权处理:连续价格不等于真实成交价格

前复权和后复权各有用途,但它们不能被当成一种无差别的价格修饰。

前复权通常更适合观察历史价格变化,使价格序列在分红、送转或拆并股等事件后保持相对连续;后复权则更接近以当前价格为基准回看历史资产价值。两种处理会改变历史价格的数值,进而影响收益率、技术指标、波动率、突破信号和机器学习特征。

问题不在于哪一种方法绝对正确,而在于研究目的、交易模拟和数据口径是否一致。使用复权价格生成信号时,成交模拟不能不加说明地使用另一种价格。若策略研究的是可实现收益,必须明确分红、拆分、交易限制以及实际成交价格如何进入收益计算。

复权处理还可能带来信息时间问题。某些调整系数在回看历史时已经知道,但在当时交易过程中并不一定以同样形式存在。若数据供应商直接用今天的公司行为信息修订整个历史序列,研究者需要确认这种处理是否会改变当时可观测的信息。

机器学习量化模型中的数据泄露与过拟合防范

数据泄露未必表现为明显的代码错误。很多泄露来自一个看似合理的统计操作:用全样本计算标准化参数,用全历史筛选股票,用最终成分股名单回看过去,或者在多次观察测试集之后继续调整模型。

这些做法不会让程序报错,却会让回测结果失去原本的含义。

训练集、验证集和测试集不是三份随意切开的数据

量化数据具有时间顺序,最基本的划分原则是让模型只能使用当时已经发生或已经公布的信息。训练集用于学习参数,验证集用于选择模型和超参数,测试集用于进行尽量接近最终评估的检验。测试集一旦被反复查看并影响决策,它就不再是真正独立的测试集。

时间序列不能完全照搬随机打乱的交叉验证。随机切分会把相邻时段甚至未来样本混入训练过程,尤其在具有自相关、重叠标签和持有期较长的策略中,结果会比真实情况乐观得多。

更稳妥的做法是采用按时间滚动的训练和验证方式。模型在过去一段时间训练,在之后一段时间验证,然后随着时间推进更新训练窗口。对于预测未来若干交易日收益的标签,还要注意标签区间和训练区间发生重叠的问题。否则,虽然样本的起始日期看起来不同,模型实际上仍然间接接触到了未来区间的结果。

标准化、特征选择和降维也会泄露信息

数据泄露不只来自标签。任何使用统计量的预处理,都需要考虑统计量是在什么时候计算的。

例如,对全样本计算均值和标准差,再把结果用于早期训练数据,相当于让早期样本获得了未来分布的信息。对全市场、全时期进行特征筛选,也可能把后来才显现的相关性带入过去。降维、缺失值填充、异常值处理和行业中性化,同样需要按照时间滚动执行。

在工程上,预处理步骤应该被封装进与训练过程绑定的流程中,而不是先对整张数据表处理完,再把处理后的结果交给模型。每个时间点使用的参数都应该能够追溯。这样做看起来繁琐,却能避免研究阶段最容易发生的“先处理、后切分”。

幸存者偏差:今天的股票池不是过去的股票池

幸存者偏差通常发生在股票池、指数成分和期货合约选择中。回测如果只使用当前仍然活跃、仍然上市或仍然属于某个指数的标的,就会排除那些已经退市、合并、长期停牌或被剔除的资产。

这会让历史样本看起来更健康,也会让策略避开许多真实交易中必须面对的风险。一个当时并不属于指数的标的,不能因为今天属于指数,就被加入过去的回测。一个已经停止交易的合约,也不能因为它的历史数据完整,就被默认视为持续可交易。

处理幸存者偏差,需要让每个时间点的资产池尽量回到当时真实可获得的状态。成分股要使用历史成分,合约要记录上市、交割、到期和可交易时间,股票还要考虑停牌、退市整理和流动性限制。资产池的变化本身也可能是策略信号的一部分,不能在回测里悄悄抹平。

时间旅行:最隐蔽的未来函数

所谓时间旅行,是指模型或策略在过去某一时刻使用了未来信息。它可能来自一行非常普通的代码,也可能来自数据表的设计。

常见情况包括:

1. 用当天收盘后才能确定的收盘价、财务指标或公告内容,生成当天开盘甚至当天盘中的信号;

2. 用全周期最高价、最低价或波动率计算历史特征;

3. 使用经过未来修订的指数成分和财务数据;

4. 按自然日期合并数据,没有考虑实际发布时间;

5. 把整段行情先聚合,再用聚合结果决定同一根K线内的交易;

6. 用未来成交价格验证当前订单是否成交;

7. 在回测结束后根据完整曲线筛选参数,再把筛选结果当作事先确定的策略。

时间旅行最危险的地方,是它通常会产生一条非常漂亮的曲线。它不像网络断开那样立刻报错,而是让研究者越来越相信模型有效。直到实盘中信号明显变差,才开始回头检查数据处理流程。

测试未来函数时,可以主动把数据截断到某个历史时点,只允许系统读取当时已经存在的数据,再重新生成信号。也可以对同一个信号设置严格的发布时间、可见时间和下单时间,检查三者是否被错误地压缩成同一个时间点。

过拟合不只发生在模型参数里

过拟合通常被理解为模型层数太多、参数太复杂或训练轮数太长,但量化策略的过拟合往往更广泛。因子筛选、股票池选择、持有期设置、止盈止损、交易时段、成本假设和异常样本处理,都可能成为调参对象。

当研究者反复修改这些选项,只保留表现最好的组合时,即使最终使用的是一个非常简单的模型,也可能已经对历史噪声完成了拟合。

因此,防止过拟合不能只依靠减少参数。更重要的是减少无意识的试验自由度,并完整记录每次试验。一个经过大量尝试后才找到的简单规则,并不一定比事先有明确逻辑、但回测结果普通的规则更可靠。

稳健性检查可以从几个方向展开:

  • 更换时间区间,观察策略是否只依赖某一段行情;
  • 更换资产池,确认结果不是由少数标的支撑;
  • 调整手续费、滑点和成交限制,判断收益是否对成本极度敏感;
  • 改变参数范围,观察性能是否存在过窄的尖峰;
  • 将信号延迟一个合理的执行周期,检验策略是否依赖不现实的即时成交;
  • 分析收益来源,确认盈利是否集中在少数交易日或少数资产;
  • 使用未参与研究决策的新数据进行最终检验。
回测曲线越漂亮,越需要追问它是如何漂亮起来的。

策略回测失效的深层原因:幸存者偏差与时间旅行

回测失效并不意味着回测没有价值。问题在于,回测经常被误解成对未来收益的直接承诺。实际上,它更像是一套关于研究假设的压力测试:如果数据口径、交易规则和执行条件都成立,策略在历史样本中会怎样表现。

只要其中一个条件被悄悄放宽,回测就可能从分析工具变成叙事工具。

成交价格不是一个可以随意选择的数字

许多回测默认在收盘价成交,因为收盘价容易获得,计算也简单。但如果信号是在收盘后生成,策略不可能同时在该收盘价完成交易;如果信号在收盘前生成,也未必能够知道最终收盘价。

更接近真实交易的模拟,需要明确:

  • 信号在什么时间产生;
  • 订单在什么时间发送;
  • 市场允许使用什么价格成交;
  • 订单是否有足够的盘口深度;
  • 交易量是否会影响成交;
  • 涨跌停、停牌和熔断等状态如何处理;
  • 未成交订单是否撤销、延续或改价。

对期货而言,还要考虑合约乘数、保证金、交易时段、夜盘、涨跌停限制、换月和交割等因素。连续合约适合观察和研究,但不一定等于一个真实存在、始终可以按同一规则交易的合约。若连续合约的拼接规则没有处理好,换月附近可能出现并不存在的价格跳跃或收益。

交易成本是策略结构的一部分

手续费和滑点不是回测报告最后附加的一行扣减项。它们会影响策略是否值得交易,甚至影响因子本身是否存在。

高换手策略对成交成本尤其敏感,但低换手策略也不能完全忽略成本。大额交易可能面对冲击成本,流动性不足的标的可能无法按理论价格成交,期货策略还可能受到换月成本和保证金占用的影响。

成本模型不必一开始就复杂到无法维护,但至少应该与策略的交易频率、资产类型和订单方式相匹配。固定滑点适合做初步压力测试,却不能替代对盘口深度和成交量的分析。对于成交量约束明显的策略,还应设置单笔订单占市场成交量的上限,避免回测在纸面上吃掉市场中不存在的流动性。

回测中的稳定,不等于收益稳定

一条净值曲线看起来平滑,并不意味着策略风险低。收益可能集中在少数极端行情中,也可能来自某个特定行业、某几只股票或某一段波动环境。把总收益拆开观察,往往比只看年化结果更有信息量。

可以从以下角度重新检查收益来源:

  • 按年份、季度或市场状态拆分;
  • 按资产、行业和合约拆分;
  • 按多空方向拆分;
  • 按持仓周期和换手率拆分;
  • 区分隔夜收益与盘中收益;
  • 区分正常交易和极端行情;
  • 观察最大盈利日、最大亏损日及其占比;
  • 检查收益是否依赖少数无法稳定成交的交易。

如果策略只在某一种波动环境中有效,就应该把它描述成有条件的策略,而不是泛化为始终有效的模型。市场状态会变化,数据分布会变化,参与者也会变化。任何回测结论都需要带上它成立的条件。

高频交易中的微观结构与实时数据管道构建

当视野从日线和分钟线拉升到更高频率,数据的含义会发生变化。传统K线保留了开盘价、最高价、最低价、收盘价和成交量,却隐藏了价格在这一时间段内如何形成。

同一根一分钟K线,可以由连续而稳定的成交构成,也可以由几次快速冲击、撤单和反向成交构成。它们的最终开高低收可能接近,但市场的流动性、订单压力和成交路径完全不同。

Tick数据带来的不只是更高频率

逐笔成交数据记录了单笔成交,委托数据则进一步描述订单进入、撤销和修改的过程。两者提供的信息不同,不能简单混称为“高频数据”。

逐笔成交可以帮助研究:

  • 成交方向和主动买卖压力;
  • 成交量在不同价格层级的分布;
  • 短时间内的交易集中程度;
  • 价格变化与成交强度之间的关系;
  • 大单、连续成交和短期冲击。

订单簿数据则可以观察:

  • 买卖盘深度;
  • 买卖价差;
  • 委托撤单速度;
  • 某个价位的挂单持续时间;
  • 盘口不平衡;
  • 流动性在价格移动前后的变化。

但高频数据越细,不代表信号越可靠。更高频率意味着更多微小噪声、更复杂的延迟、更严格的数据质量要求,也意味着回测中任何不现实的假设都会被放大。

实时管道的关键不只是吞吐量

高频数据通常通过长连接接入。管道需要完成接收、解析、校验、排序、去重、聚合、存储和实时计算。常见架构会把原始事件流、标准化事件流和策略特征流分开保存,让不同阶段的结果可以独立检查。

一条可用的实时管道,至少需要处理几类问题:

1. 断线重连:网络中断后,系统能否恢复连接,是否会漏掉断线期间的数据;

2. 重复消息:重连或供应商重发可能造成同一事件重复进入;

3. 乱序消息:消息到达顺序和事件发生顺序可能不一致;

4. 时间漂移:本地时钟和交易所时钟长期运行后可能产生偏差;

5. 突发流量:开盘、收盘和重大事件期间,数据量可能突然增加;

6. 背压处理:下游处理速度不足时,系统如何避免内存持续堆积;

7. 数据落盘:实时计算完成后,原始数据是否可靠保存;

8. 故障恢复:服务重启后,能否从某个明确位置继续处理;

9. 监控告警:系统如何发现延迟升高、字段异常或数据中断。

吞吐量和延迟当然重要,但它们不是唯一目标。一个极快却经常丢包、乱序和重复的系统,无法为策略提供稳定输入。实时系统首先要知道自己正在处理什么,其次才是处理得多快。

微观结构信号必须和执行能力匹配

订单簿上的压力变化可能很快消失。研究阶段能够读取完整盘口,不代表实盘下单时也能以同样速度响应。信号生成延迟、网络延迟、交易接口排队、交易所撮合顺序,都会改变实际结果。

因此,高频策略的回测应尽量把事件顺序和执行顺序分开建模。策略看到数据的时间、发出订单的时间和订单产生结果的时间,不能被简化为同一个时间戳。

还要警惕“信号越短越高级”的错觉。很多微观结构信号在极短窗口内具有解释力,但在扣除手续费、滑点和延迟后可能失去交易价值。真正需要回答的不是信号在历史数据上是否存在,而是它在可执行条件下是否还剩下足够的边际收益。

量化策略性能评估的核心指标体系

当我们终于跑完一轮回测,看到那些五颜六色的绩效曲线时,评估才真正开始。指标的作用不是替策略下结论,而是从不同角度揭示策略的行为。

维度主要衡量内容容易被忽略的限制
年化收益率在一段时间内获得收益的速度不说明收益路径和回撤体验
最大回撤历史净值从高点到低点的最大跌幅不说明未来回撤一定不会更大
夏普比率单位波动或风险下的收益表现对收益分布和尾部风险较敏感
胜率盈利交易在全部交易中的比例不体现单笔盈亏金额
盈亏比平均盈利与平均亏损的关系不体现连续亏损和等待时间
换手率策略交易频繁程度不等于实际成交成本
卡玛比率收益与最大回撤之间的关系仍然依赖历史区间
尾部损失极端亏损可能造成的影响需要足够长、足够有代表性的样本
收益稳定性收益在时间和资产上的分布不能替代对交易机制的理解

收益率:最容易被误读的第一印象

年化收益率直观,却对收益路径不敏感。两个策略可能拥有相近的年化结果,一个主要依靠连续的小幅收益,另一个则依靠少数几次极端行情。它们对资金、心理和执行能力的要求完全不同。

观察收益率时,不应只看最终数字,还要看收益是如何产生的。收益是否集中在少数交易日,是否依赖单一资产,是否在扣除成本后仍然存在,是否需要持续满仓,都会改变这个数字的实际含义。

最大回撤:不仅是亏损幅度,也是恢复时间

最大回撤是判断策略风险的重要指标,但只记录跌幅还不够。回撤持续了多久,恢复用了多久,历史上出现过几次类似回撤,同样值得关注。

一个回撤幅度不大的策略,如果长期没有恢复,也可能给资金和信心带来持续压力。相反,短期出现较深回撤但迅速修复的策略,也不一定适合所有投资者。回撤的形态比单一数值更接近真实持有体验。

还应区分收盘回撤、盘中回撤和资金曲线回撤。若策略存在杠杆、保证金或日内高波动,仅看收盘价可能掩盖盘中实际承受的风险。

夏普比率:有用,但不能成为安慰剂

夏普比率提供了一个便于比较的尺度,因此经常出现在回测报告的最前面。它可以帮助我们观察收益相对于波动的效率,却不能独立判断策略是否可靠。

当收益分布存在明显偏度和厚尾时,波动率并不能完整描述风险。策略可能大多数时间平稳,偶尔出现严重亏损;也可能收益来自少数极端行情。此时,单一夏普数值会把复杂的收益结构压缩成一个容易被误读的结论。

使用夏普比率时,最好同时查看收益分布、回撤、偏度、峰度、极端交易和不同时间段表现。如果策略有明显的非正态特征,还应采用更适合的尾部风险分析,而不是仅仅因为夏普比率较高就放松警惕。

胜率与盈亏比:两种完全不同的交易节奏

高胜率策略通常能够带来更频繁的正反馈,但如果单次亏损远大于单次盈利,一次极端亏损就可能抹去多次小额收益。低胜率、高盈亏比策略则相反,可能长时间连续亏损,等待少数大行情兑现。

这两类策略没有脱离场景的绝对优劣。关键在于收益分布、连续亏损长度、资金规模和交易者是否能够承受对应节奏。只报告胜率而不报告盈亏比,或者只报告盈亏比而不报告最大连续亏损,都会让策略画像缺少重要部分。

统计显著性与经济显著性不是一回事

一个信号在统计上具有相关性,不代表扣除交易成本后具有经济价值。样本量不足、试验次数过多、标签重叠和市场状态集中,都可能让相关性看起来比实际更可靠。

另一方面,统计结果一般的信号,也可能因为执行成本低、容量高或与其他策略相关性较低,成为组合中有用的一部分。策略评估不能只追求单项指标最大化,而要放回组合和交易约束中理解。

组合层面的评估

单个策略表现良好,不代表组合一定稳定。多个策略可能使用相似因子、相似数据源或相似交易时段,在压力行情中同时失效。

组合评估需要关注:

  • 策略之间的收益相关性;
  • 回撤是否在同一时期集中发生;
  • 资产和行业暴露是否重叠;
  • 资金分配是否放大了某一类风险;
  • 极端行情下的共同亏损;
  • 数据源、交易接口和系统依赖是否存在共同故障。

量化系统不是一组彼此独立的模型,而是一套共同面对市场、数据和执行条件的系统。组合层面的脆弱性,常常不是从某个单独策略的报告里看出来的。

把研究环境和实盘环境连接起来

回测与实盘之间的差距,很多时候不是某一个参数造成的,而是两套系统在不知不觉中使用了不同的定义。

研究环境可能使用完整的历史数据,实盘环境只能看到逐步到达的消息;研究环境可以随意读取已整理好的文件,实盘环境必须应对断线、延迟和乱序;研究环境知道一根K线最终如何收盘,实盘环境只能在K线尚未结束时做决定。

要缩小差距,研究流程应该尽量模拟真实的时间和信息边界。数据进入系统的顺序、信号生成的时点、订单发送的延迟、成交回报的处理,都应该能够在历史回放中重现。

这并不意味着每个回测都必须建立极其复杂的交易所撮合模型,而是要明确哪些假设会显著影响结果。对于低频策略,日内撮合细节可能不是核心;对于高频策略,几乎每个时间顺序都可能成为核心。模型复杂度应该服从交易逻辑,而不是为了显得先进而增加。

上线前还可以进行一段影子运行:策略生成真实信号,但暂不实际下单,用于比较研究环境和实时环境中的数据、信号、延迟与成交估计。这个阶段可能暴露出比回测更有价值的问题,例如某个字段在实时数据里始终晚到,某类资产在夜盘无法正常更新,或者研究阶段使用的交易日历与接口实际规则并不一致。

与数据和解

量化交易中的数据与算法,并不是一个冷冰冰的工程问题。它牵涉的是我们如何面对不确定性,如何处理那些看不见的裂缝,如何在每一次回测和实盘的落差之间安放自己的期待。

数据清洗是一种耐心。它要求我们承认,一条看起来完整的价格序列可能并不完整;一个字段名称清楚的数据表可能并不真正说明字段含义;一次异常波动既可能是市场事件,也可能只是供应商出了问题。

防范数据泄露是一种自律。它要求我们把测试集当作真正未知的未来,而不是一个可以被反复查看、反复修正的答案。它也要求我们对漂亮的回测保持一点距离:收益越顺滑,越应该检查它是否使用了不可能获得的信息。

策略评估则是一种对自身承受力的诚实审视。年化收益、最大回撤、夏普比率、胜率和盈亏比,都只能描述策略的一部分。真正重要的问题还包括:亏损会怎样发生,策略在什么环境中失效,执行成本是否会吞掉边际收益,连续亏损时是否仍然能够坚持,系统故障时是否有清晰的处理方案。

我们常常在策略失效时责怪市场,却很少回到最初的数据,看看那里是否藏着被忽略的时间错位、复权差异或样本偏差。我们也常常在模型表现优异时拥抱它,却很少检查那份优异是否来自未来函数、幸存者偏差或过度试验。

这些首先是技术问题,但不只是技术问题。它们还反映了研究者如何面对自己的期待。我们希望策略有效,于是很容易把每个模糊的结果解释成支持;我们希望模型稳定,于是容易把偶然的历史优势包装成规律。真正稳健的研究,不是消除所有不确定性,而是把不确定性明确写进系统里。

量化交易的难处,不在于找到一个听起来完美的算法,而在于愿意一次次回到最朴素的数据面前,承认自己并没有提前知道答案。

当数据版本清楚,时间边界明确,交易成本被认真对待,回测可以回放,实时管道能够监控,策略指标也不再被单一数字绑架时,量化研发才真正从模型实验走向交易系统。

市场不会因为我们希望它整齐,就按照整齐的方式运行。数据也不会因为我们把它放进一张表,就自动变得可靠。我们能做的,是持续检查每一个时间点、每一个字段和每一个交易假设,尽量让模型看到的世界接近策略真正要面对的世界。

算法仍然重要,但它不再是故事的全部。很多时候,决定策略能否活下来的,不是最后那一层网络,也不是报告里最醒目的指标,而是那些无人注意的基础工作:一次正确的时间对齐,一条没有被错误填补的缺失记录,一个没有被未来信息污染的特征,以及一套能够在实盘中诚实反映现实的执行逻辑。

这也是数据与算法之间最值得被反复确认的关系:算法可以放大信息,却不能替数据创造真实性。只有精品是把数据处理得更接近它本来的样子,模型才有机会在现实里保持自己的面孔。

相关阅读: 量化策略失效的归因逻辑:明日排查数据与算法偏差的实操指南量化策略的终极博弈:为什么高质量数据比复杂算法更决定成败.

常见问题

为什么回测表现优异的策略在实盘中会失效?
这通常是因为回测环境与实盘环境存在差异,例如使用了未来信息、未考虑真实的交易成本、数据口径不一致,或者回测中存在幸存者偏差和时间旅行等问题。
量化研发中数据工程主要包含哪些工作?
主要包括数据采集、清洗、对齐、存储、验证和回放,具体涉及处理缺失值、异常值、时间戳对齐、复权处理以及确保数据版本可追溯等。
如何处理金融数据中的缺失值?
不能简单地进行填充,应先区分缺失类型,如结构性缺失、采集性缺失或异常性缺失。对于逐笔数据,通常建议保留缺失事实,避免用虚构的价格路径误导回测。
什么是量化回测中的“时间旅行”?
指模型在过去某一时刻使用了未来信息,例如用收盘后才发布的财务指标生成盘中信号,或使用全周期数据计算历史特征,这会导致回测结果虚高。
如何评估量化策略的稳健性?
应通过更换时间区间、资产池,调整手续费和滑点假设,以及分析收益来源(如是否依赖少数极端行情)来进行压力测试,避免过度拟合历史噪声。