4. 数据基础设施

组合级回测引擎的可靠性,首先取决于数据基础设施是否稳固。与单资产策略不同,多资产组合会同时面对股票、ETF、期货、期权、外汇甚至加密资产,它们的交易时段、报价单位、复权方式、结算规则和时区各不相同。如果数据层没有统一建模,回测结果往往在“看起来能跑”的表象下隐藏着严重偏差。本节围绕五件事展开:行情数据、基本面数据、交易日历、时区对齐、清洗与存储。

一、核心原理:统一时间轴与统一资产标识

多资产回测的第一性原理是:所有数据必须能映射到同一根时间轴和同一套资产主键上。时间轴由交易日历定义,资产主键由统一符号体系定义。行情数据回答“某资产在某时刻的价格与成交量”,基本面数据回答“某资产在某报告期的财务状态”,两者通过资产主键和时间对齐后,才能进入组合权重计算与撮合模拟。

常见错误是直接用自然日或本地时间拼接数据。例如A股使用北京时间,使用美东时间,期货夜盘跨越自然日。若不统一,跨市场组合会在错误的时间点触发调仓。正确做法是:内部统一使用UTC时间戳存储,展示和交易日判断时再转换为交易所本地时区。

关键原则:存储用UTC,判断用交易所日历,展示用本地时区。三者分离,避免混用。

二、方法流程:从采集到可回测数据

  1. 资产主键标准化:为每个资产分配唯一ID,如 ASSET_ID,并维护交易所、币种、资产类型、上市与退市日期等元数据。
  2. 行情数据采集:按资产类型分别采集日线、分钟线或Tick,保留原始字段与采集时间戳。
  3. 基本面数据采集:记录报告期、公告日期、生效日期,避免使用未来信息。
  4. 交易日历构建:为每个交易所维护开市、闭市、半日市、临时休市规则。
  5. 时区对齐:将各交易所时间转换为UTC,再按统一频率重采样。
  6. 数据清洗:处理缺失、重复、异常值、停牌、涨跌停和复权。
  7. 存储与版本化:采用列式存储加元数据版本,保证可复现。

三、案例/场景:跨市场组合的日频对齐

假设组合同时持有A股、港股和。A股与港股在北京时间交易,在美东时间交易。若直接按自然日合并,会出现“当日收盘价对应北京时间次日凌晨”的错位。正确流程是:先将各市场时间戳转为UTC,再以UTC交易日为键,取每个市场在该交易日内的最后有效价格,最后按组合调仓规则生成权重。

# 伪代码:多市场日频对齐
for market in ["CN", "HK", "US"]:
    df = load_raw(market)
    df["ts_utc"] = to_utc(df["ts_local"], market.timezone)
    df["trade_date_utc"] = df["ts_utc"].dt.date
    daily = df.sort_values("ts_utc").groupby("trade_date_utc").last()
    store(market, daily)

panel = merge_on_utc_date(["CN", "HK", "US"])
panel = panel.fillna(method="ffill", limit=1)  # 谨慎使用
前向填充必须设置上限,并区分“停牌”与“无数据”。停牌期间价格不可交易,直接填充会高估策略可执行性。

四、数据清洗与存储方案

清洗环节需要建立可审计的规则清单。下表给出常见问题与处理策略:

问题类型典型表现处理策略
缺失值某日无行情区分停牌、退市、数据源缺失,分别标记
重复记录同一时间戳多条按采集时间保留最新,记录去重日志
异常价格价格为0或负置为缺失并告警,不直接删除
复权不一致前复权与后复权混用统一使用后复权或原始价加因子
基本面未来函数使用未公告财报按公告日期对齐,而非报告期

存储方案建议采用分层结构:原始层保留采集原文,清洗层存放标准化数据,特征层存放回测可直接使用的面板数据。格式上优先选择Parquet或Feather等列式存储,配合分区目录,例如按资产类型和日期分区。元数据中记录数据版本、清洗规则版本和生成时间,确保回测可复现。

data/
  raw/
    equities/2024-01-01.parquet
  clean/
    equities/asset_id=000001/2024.parquet
  features/
    panel_daily/2024.parquet
  meta/
    calendar_cn.json
    data_version.json

五、误区与复盘

  • 误区一:用自然日代替交易日历。 会导致节假日产生虚假调仓信号。复盘时应检查调仓日是否全部落在开市日。
  • 误区二:忽略时区导致跨市场错位。 应统一UTC存储,并在回测日志中打印每个市场的对齐时间。
  • 误区三:基本面数据按报告期对齐。 必须按公告日期或生效日期对齐,否则引入未来信息。
  • 误区四:清洗规则不可追溯。 每次清洗应输出日志和版本号,便于对比不同版本的回测差异。
建议在回测引擎启动时执行一次“数据健康检查”:检查时间轴连续性、资产主键覆盖率、缺失率、时区偏移和日历一致性。将检查结果写入日志,作为回测报告的一部分。

数据基础设施不是一次性工程,而是随资产池扩展持续演进的系统。把时间轴、资产主键、清洗规则和存储版本四件事做扎实,后续的组合权重、风险模型和撮合模拟才有可靠基础。