2. 金融时间序列与横截面数据基础

在横截面均值回归与多资产统计研究中,数据质量决定了策略的上限。无论模型多精巧,如果收益率计算口径不一致、面板数据对齐错误,或清洗环节引入前视偏差,最终得到的统计显著性都可能是幻觉。本节从收益率计算出发,逐步建立面板数据结构,厘清横截面与时间序列的差异,并给出常见数据源与清洗方法。

一、收益率计算:从价格到可比较的收益

金融研究的第一步是把价格序列转换为收益率。常见形式有三种:简单收益率、对数收益率和超额收益率。

  • 简单收益率:\( r_t = P_t / P_{t-1} - 1 \),直观反映资产价值变化,适合计算组合权重与盈亏。
  • 对数收益率:\( r_t = \ln(P_t / P_{t-1}) \),具有时间可加性,适合统计建模与多期累计。
  • 超额收益率:减去无风险利率或市场基准,用于横截面比较与因子研究。

在横截面研究中,收益率必须满足“同一时间截面内可比”的原则。若不同资产使用不同复权方式、不同交易时区或不同频率,横截面排序就会失真。以下代码展示如何从原始价格计算对数收益率并处理缺失值:

import pandas as pd
import numpy as np

# 假设 prices 为 DataFrame,index 为日期,columns 为资产代码
prices = prices.sort_index()
prices = prices.ffill(limit=3)  # 有限前向填充,避免长期停牌污染

log_ret = np.log(prices / prices.shift(1))
log_ret = log_ret.replace([np.inf, -np.inf], np.nan)

# 横截面去极值:按日对收益率做 1%/99% 缩尾
def winsorize_cs(row, lower=0.01, upper=0.99):
    if row.notna().sum() < 5:
        return row
    lo, hi = row.quantile(lower), row.quantile(upper)
    return row.clip(lo, hi)

log_ret = log_ret.apply(winsorize_cs, axis=1)
对数收益率在单期较小时近似等于简单收益率,但在多期累计和统计建模中更稳定。横截面研究通常优先使用对数收益率或超额对数收益率。

二、面板数据:时间与截面的二维结构

面板数据(Panel Data)是横截面与时间序列的结合体,通常表示为三维结构:时间 × 资产 × 变量。在量化研究中,最常见的面板形式是“日期 × 资产代码”的二维矩阵,每个单元格存放收益率、因子暴露或财务指标。

面板数据的核心操作包括:对齐、分组、滚动计算和截面标准化。以下清单概括了面板数据处理的标准流程:

  1. 时间对齐:统一交易日历,处理不同市场休市日差异。
  2. 资产对齐:处理上市、退市、停牌和代码变更。
  3. 缺失处理:区分随机缺失与结构性缺失,避免简单填充。
  4. 截面标准化:按日对因子做 z-score 或排序,消除量纲影响。
  5. 滚动窗口:确保计算仅使用历史信息,防止前视偏差。

下表对比了横截面数据与时间序列数据在分析目标、统计方法和常见陷阱上的差异:

维度 时间序列 横截面
分析对象 单个资产的历史路径 同一时点多个资产的排序
核心问题 自相关、趋势、波动聚集 收益差异与因子的关系
常用方法 ARIMA、GARCH、协整 排序分组、Fama-MacBeth 回归
样本量 时间长度决定 资产数量决定
典型陷阱 非平稳、结构突变 幸存者偏差、前视偏差

三、横截面与时间序列的差异:为什么不能混用

时间序列关注“一个资产如何随时间变化”,横截面关注“同一时间不同资产为何不同”。两者的统计推断逻辑不同:时间序列的样本量来自时间维度,横截面的样本量来自资产维度。若在横截面回归中忽略时间序列自相关,标准误会被低估;若在时间序列分析中混入横截面排序,则可能引入选择偏差。

在均值回归策略中,这一差异尤为关键。时间序列均值回归研究单个资产价格偏离长期均值的回复速度;横截面均值回归研究的是“过去表现较差的资产是否在未来跑赢过去表现较好的资产”。前者依赖单资产历史,后者依赖横截面排序与分组。两者可以结合,但必须分别处理数据结构和统计假设。

常见误区:用全样本均值做横截面标准化。这会把未来信息泄露到历史截面中。正确做法是按日计算截面均值与标准差,或使用扩展窗口。

四、常见数据源与清洗方法

量化研究常见数据源包括:行情数据(日频、分钟频)、基本面数据(财报、估值)、另类数据(舆情、卫星、供应链)。不同数据源的频率、延迟和覆盖范围差异很大,清洗策略也需相应调整。

  • 行情数据:处理拆股、分红复权,统一复权方式;剔除停牌日与涨跌停无法成交的样本。
  • 基本面数据:按公告日而非报告期对齐,避免前视偏差;处理财报重述。
  • 另类数据:关注覆盖偏差与时间戳精度,做频率降采样与标准化。

以下是一个典型的数据清洗检查清单,可用于每日数据入库前的自动化校验:

def data_quality_check(df):
    report = {}
    report['missing_ratio'] = df.isna().mean().mean()
    report['duplicated_index'] = df.index.duplicated().sum()
    report['extreme_ret'] = (df.abs() > 0.5).sum().sum()
    report['zero_volume_days'] = (df == 0).sum().sum()
    return report

# 示例输出
# {'missing_ratio': 0.012, 'duplicated_index': 0,
#  'extreme_ret': 3, 'zero_volume_days': 47}
清洗的核心原则是“可追溯、可复现、可审计”。每一步填充、缩尾和剔除都应记录参数与影响范围,否则后续统计推断无法解释。

综合来看,收益率计算决定了数据的可比性,面板结构决定了分析的组织方式,横截面与时间序列的差异决定了统计方法的选择,而数据源与清洗方法决定了结论的稳健性。这四者共同构成横截面均值回归与多资产统计研究的数据基础。