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)是横截面与时间序列的结合体,通常表示为三维结构:时间 × 资产 × 变量。在量化研究中,最常见的面板形式是“日期 × 资产代码”的二维矩阵,每个单元格存放收益率、因子暴露或财务指标。
面板数据的核心操作包括:对齐、分组、滚动计算和截面标准化。以下清单概括了面板数据处理的标准流程:
- 时间对齐:统一交易日历,处理不同市场休市日差异。
- 资产对齐:处理上市、退市、停牌和代码变更。
- 缺失处理:区分随机缺失与结构性缺失,避免简单填充。
- 截面标准化:按日对因子做 z-score 或排序,消除量纲影响。
- 滚动窗口:确保计算仅使用历史信息,防止前视偏差。
下表对比了横截面数据与时间序列数据在分析目标、统计方法和常见陷阱上的差异:
| 维度 | 时间序列 | 横截面 |
|---|---|---|
| 分析对象 | 单个资产的历史路径 | 同一时点多个资产的排序 |
| 核心问题 | 自相关、趋势、波动聚集 | 收益差异与因子的关系 |
| 常用方法 | 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}
综合来看,收益率计算决定了数据的可比性,面板结构决定了分析的组织方式,横截面与时间序列的差异决定了统计方法的选择,而数据源与清洗方法决定了结论的稳健性。这四者共同构成横截面均值回归与多资产统计研究的数据基础。