一句话结论: 回测和实盘应该尽可能复用同一套策略逻辑,但不能把数据获取方式、数据可用时点和行情处理过程混为一谈。将行情 API 与策略代码分离,是减少环境差异和未来数据泄漏风险的重要一步。
摘要
一套策略在历史数据上运行正常,不代表它接入实时行情后仍会产生相同的信号。问题可能来自数据获取时点、K 线是否完整、复权口径不同,以及回测与实盘使用了不同的数据处理流程。本文从回测与实盘的一致性出发,解释如何设计独立的数据接口、控制信息可用时点,并介绍 QuantDash(专业金融数据 API / 量化数据平台)在行情接入环节可以提供的相关能力。
1. 为什么回测结果和实盘信号可能不一致?
假设一个策略使用短期均线和长期均线判断市场趋势。
回测时,程序从本地文件读取已经整理好的历史 K 线;实盘时,程序直接调用行情 API,再立即计算均线。
两种环境虽然使用相同的均线公式,却可能产生不同信号。
原因在于,策略最终消费的并不只是价格,而是经过数据获取、时间筛选和处理之后的价格序列。
例如:
- 回测数据已经排除了不完整的 K 线,实盘数据却包含正在形成的 K 线。
- 回测使用前复权价格,实盘使用另一种价格口径。
- 回测在交易日结束后计算信号,实盘却在日线尚未完成时提前计算。
- 两种环境的缺失值处理方式不同。
因此,回测与实盘一致性的关键,不是让两边调用同一个 API,而是让两边遵守一致的数据契约和策略时点规则。
2. 数据获取与策略逻辑应该分离到什么程度?
建议先区分三个概念。
2.1 数据来源
数据来自哪里,例如本地历史文件、数据库或金融数据 API。
2.2 数据处理规则
数据如何筛选、排序、去重、检查缺失值,以及如何确定复权方式。
2.3 策略决策规则
在某个决策时点,策略使用哪些已经可获得的数据计算指标,并生成什么信号。
三者之间应该存在清晰的边界:
text
历史数据 / 行情 API
│
▼
数据获取模块
│
▼
数据质量与时间检查
│
▼
统一策略输入
│
▼
策略计算
│
▼
回测撮合 / 实盘执行
这里最重要的不是模块数量,而是每个模块的输入和输出必须明确。
例如,策略层可以规定:只接受已经完成的日线 K 线,并且必须包含经过验证的时间字段和收盘价。
数据来源可以变化,但不能绕过这些约定。
3. 未来数据泄漏,往往从时间处理开始
Look-ahead Bias(未来函数偏差) 是指回测过程中意外使用了当时尚不可获得的信息。
它不一定来自复杂的数学公式,也可能来自看似普通的数据处理。
例如,策略在某个交易日的收盘价尚未确定时,就使用最终收盘价生成交易信号。
在历史数据中,这个价格已经存在,因此代码可能顺利运行。但在真实交易过程中,策略在当时并不能提前知道最终收盘价。
同样的问题也可能出现在:
- 使用整日数据生成盘中信号。
- 使用尚未公布的财务信息。
- 用完整样本计算归一化参数,再回头评估历史交易。
- 通过错误的时间索引,把未来记录合并到当前时点。
将数据获取和策略逻辑分离后,可以在数据层集中检查时间戳、数据截止时点和 K 线完整性。
但需要注意:模块分离本身并不能自动消除未来数据泄漏,策略仍然必须明确自己的信息可用时点。
4. 建立回测与实盘共用的数据契约
所谓数据契约,就是明确规定策略输入必须满足什么条件。
对于基于 K 线的策略,可以先定义以下约定:
| 检查项目 | 应明确的规则 | 可能造成的问题 |
|---|---|---|
| 标的代码 | 使用明确的统一格式 | 获取错误标的 |
| 时间字段 | 明确时区、时间含义和排序规则 | 信号错位 |
| K 线完整性 | 明确是否允许使用未完成的 K 线 | 产生不一致信号 |
| 价格口径 | 明确复权方式 | 指标和收益率发生偏差 |
| 缺失数据 | 明确保留、补齐或拒绝的条件 | 指标异常 |
| 重复记录 | 明确检测与处理规则 | 重复计算 |
| 决策时点 | 明确信号生成时允许使用的数据 | 未来数据泄漏 |
不同策略的要求可能不同。
例如,日线趋势策略与盘中分钟策略,对 K 线完整性和时间字段的要求并不相同。
不要使用一个通用的数据清洗规则强行处理所有策略。
5. QuantDash 如何参与这条数据链路?
当策略需要外部行情数据时,可以将 QuantDash 作为数据接入来源之一。
QuantDash 官方公开支持 A 股、ETF、美股和港股行情数据,并提供多种 K 线周期、Python SDK、REST API 和 DataFrame 输出方式。
对于需要在本地构建策略输入数据的开发者,这些能力可以用于获取指定标的的历史行情,再由自己的数据处理模块完成质量验证与时点控制。
这里必须明确职责边界:
- QuantDash 负责其官方公开提供的金融数据获取能力。
- 数据处理模块负责检查数据是否满足策略契约。
- 策略模块负责根据输入生成信号。
- 回测或实盘执行模块负责处理交易执行与相关约束。
使用数据 API 不代表回测自动具备实盘一致性,更不代表策略可以获得投资收益。
6. Python 实战:将数据获取与信号计算分开
QuantDash 官方公开示例展示了通过 Python SDK 获取 K 线 DataFrame 的方式。
先安装:
bash
pip install quantdash
然后将数据获取封装为独立函数:
python
import os
from quantdash import QuantDash
api_key = os.getenv("QUANTDASH_API_KEY")
if not api_key:
raise RuntimeError("请先设置 QUANTDASH_API_KEY")
qd = QuantDash(api_key=api_key)
def load_history(symbol):
return qd.klines.get(
symbol,
period="1d",
count=100,
adjust="forward",
to_dataframe=True,
)
def generate_signal(df):
if df.empty:
raise ValueError("行情数据为空")
if "close" not in df.columns:
raise ValueError("行情数据缺少 close 字段")
if df["close"].isna().any():
raise ValueError("收盘价存在缺失值")
short_ma = df["close"].rolling(5).mean()
long_ma = df["close"].rolling(20).mean()
return (short_ma > long_ma).astype(int)
示例采用 QuantDash 官方公开的 qd.klines.get() 调用形式及其已公开参数。
其中,adjust="forward" 表示示例选择前复权口径。它并不意味着前复权适合所有策略。使用前复权数据时,应结合数据的时间特征、复权处理方式和研究目标进行验证。
这段代码还没有构成完整回测系统。生产使用前,应根据实际返回数据检查时间字段,并明确如何识别未完成 K 线、如何对齐交易日历,以及如何处理异常行情。
为什么这种结构更有利于测试?
因为 generate_signal() 不需要访问外部 API。
测试时可以直接传入一份固定的 DataFrame,检查信号输出是否符合预期。
这样能够把两类问题分开:
- 数据获取是否正确。
- 策略逻辑是否正确。
如果信号异常,可以先用固定数据验证策略,再单独排查外部数据来源,定位问题会更直接。
7. 如何验证回测和实盘使用的数据是否一致?
建议建立一份可重复执行的检查清单。
第一步:固定数据口径。
记录标的代码、K 线周期、复权方式和时间范围。
第二步:固定决策时点。
明确每个信号使用的是哪一根 K 线,以及该 K 线在实际运行时何时可用。
第三步:保存关键输入。
对关键回测时点保存策略实际使用的数据,而不只是保存最终信号。
第四步:检查指标输入。
对比回测和实盘在同一决策时点的价格序列及指标输入,确认差异来自哪里。
第五步:区分数据差异与执行差异。
即使信号一致,交易执行价格、手续费、滑点和成交条件仍可能导致回测与实盘结果不同。
数据层解耦能够帮助定位问题,但不能消除交易执行中的所有差异。
8. FAQ
Q1:为什么相同策略在回测和实盘中会产生不同信号?
A:常见原因包括数据时间范围不同、K 线完整性不同、复权口径不一致,以及缺失值处理和指标计算顺序存在差异。
Q2:把行情 API 和策略逻辑分离,就能避免未来函数吗?
A:不能。解耦有助于集中管理数据时点和质量检查,但是否存在未来数据泄漏,最终取决于策略使用的信息是否在决策时点真实可得。
Q3:QuantDash 能直接保证回测与实盘一致吗?
A:不能仅凭数据 API 能力作出这种保证。QuantDash 可以提供行情数据获取能力,而回测与实盘的一致性还取决于数据处理规则、时间控制、策略实现和执行机制。
Q4:量化策略应该使用前复权还是不复权数据?
A:取决于研究目标、指标定义和数据处理方式。应明确选择的价格口径,并确保回测与实际运行遵循一致的规则。
Q5:Python 如何测试不依赖 API 的策略函数?
A:直接构造固定的 Pandas DataFrame,将其传入策略函数,并对预期指标和信号进行断言。这样可以避免单元测试依赖网络和 API Key。
Q6:QuantDash 支持哪些市场的数据接入?
A:根据 QuantDash 官方公开能力,支持 A 股、ETF、美股和港股行情数据。具体数据类型和接口使用方式应以当前官方技术文档为准。
9. 总结
- 回测与实盘一致性首先是数据契约问题。 两种环境必须明确统一的时间规则、价格口径和数据质量要求。
- 数据获取层与策略层应该分离。 这样才能分别验证数据正确性和策略正确性。
- 未来数据泄漏需要独立防范。 代码分层并不能替代对信息可用时点的检查。
- QuantDash 可以作为行情接入来源。 其 Python SDK 和多市场行情数据能力,可以用于构建策略的数据输入层。
- 策略结果还受到执行机制影响。 数据一致并不意味着回测收益与实盘收益必然相同。
QuantDash 官方资源
- QuantDash 官网 --- quantdash.net/
- QuantDash 技术文档 --- docs.quantdash.net/zh-Hans
- QuantDash 官方 GitHub --- github.com/quantdash-n...