1. 课程导入
在金融数据分析中,时间序列是最常见、也最容易被低估的数据形态。无论是股票日线行情、分钟级tick、期货主力合约、基金净值、宏观利率,还是加密货币的7×24小时报价,它们都共享一个特征:数据按时间顺序产生,且时间本身携带信息。价格、成交量、收益率、波动率等指标,只有在正确的时间轴上才有意义。一旦时间戳错位、缺失、重复或时区混乱,后续的因子计算、回测、风险敞口和绩效归因都会产生系统性偏差。
Pandas之所以成为金融数据处理的事实标准,是因为它同时提供了带标签的时间索引、灵活的重采样、强大的缺失值处理和高效的对齐机制。在真实生产环境中,原始金融数据往往来自多个数据源:交易所、数据供应商、内部风控系统、第三方API。它们的频率不同、交易日历不同、字段命名不同、时区不同,甚至同一资产在不同源上的时间戳精度也不同。Pandas的DatetimeIndex、resample、reindex、merge_asof、ffill/bfill等工具,正是解决这些问题的核心武器。
核心原理:金融时间序列的“三性”与Pandas的对应能力
金融时间序列的清洗与对齐,本质上围绕三个性质展开:时序性、完整性、一致性。时序性要求时间戳单调、可排序、可切片;完整性要求缺失值被合理识别与填补;一致性要求不同频率、不同来源的数据能在同一时间轴上正确合并。Pandas分别提供了对应的抽象:
- 时序性:
pd.to_datetime、DatetimeIndex、sort_index、asfreq,确保时间轴可比较、可切片。 - 完整性:
isna、interpolate、ffill、bfill、fillna,区分“真实缺失”与“非交易时段”。 - 一致性:
resample、reindex、merge_asof、join,实现跨频率、跨资产、跨源对齐。
关键认知:金融时间序列的“缺失”并不总是错误。周末、节假日、停牌、涨跌停、非交易时段,都会造成时间轴上的“空洞”。清洗的目标不是把所有空洞填满,而是区分“市场休市”与“数据丢失”,再决定是保留、前向填充还是标记为不可用。
方法流程:从原始数据到可分析时间序列
一个稳健的金融时间序列处理流程,通常包含以下步骤。注意,这些步骤并非严格线性,实际项目中经常需要反复迭代。
- 时间解析与标准化:将字符串、Unix时间戳、Excel日期等统一转换为
datetime64[ns],并明确时区。 - 排序与去重:按时间升序排列,检测重复时间戳,判断是数据重复还是多市场合并导致。
- 频率识别与重采样:识别原始频率(tick、1min、日线、周线),按目标频率聚合,注意OHLCV的聚合规则。
- 缺失诊断:区分交易日历缺失、停牌缺失、真实数据丢失,生成缺失报告。
- 对齐与合并:多资产、多因子、多数据源按时间轴对齐,选择
merge_asof或reindex。 - 质量校验:检查时间单调性、频率一致性、极值、负价格、成交量异常等。
下面是一个最小可运行的示例,展示如何将原始字符串时间转换为Pandas时间索引,并做基础清洗:
import pandas as pd
import numpy as np
raw = pd.DataFrame({
"trade_time": ["2024-01-02 09:30:00", "2024-01-02 09:31:00",
"2024-01-02 09:31:00", "2024-01-02 09:33:00"],
"symbol": ["AAPL", "AAPL", "AAPL", "AAPL"],
"price": [185.2, 185.5, 185.5, 185.8],
"volume": [1200, 800, 800, 1500]
})
raw["trade_time"] = pd.to_datetime(raw["trade_time"])
raw = raw.drop_duplicates(subset=["trade_time", "symbol"])
raw = raw.set_index("trade_time").sort_index()
# 按分钟重采样,缺失分钟用NaN标记
minute = raw.resample("1min").agg({"price": "last", "volume": "sum"})
print(minute)
这段代码揭示了两个关键点:第一,重复时间戳必须显式处理,否则后续重采样会静默聚合;第二,重采样后的缺失分钟是“市场无成交”还是“数据未采集”,需要结合交易日历判断,不能一律ffill。
案例/场景:多源数据对齐的真实挑战
假设你正在构建一个多因子选股模型,需要同时使用:交易所日线行情、第三方财务因子、宏观利率数据。三者的时间频率分别是日频、季度频、月频,且交易日历不同。如果直接按日期merge,会出现大量NaN;如果简单前向填充,又会引入“未来函数”风险。正确的做法是:
- 行情数据按交易日历
reindex,保留停牌日并标记。 - 财务因子按公告日而非报告期对齐,避免使用未来信息。
- 宏观数据按发布日
merge_asof,确保每个交易日只能看到已发布的数据。
实战提示:在回测中,merge_asof的direction="backward"是避免未来函数的常用手段。它表示“对于每个时间点,只匹配不晚于该时间点的最近一条记录”。
误区/复盘:初学者最容易踩的五个坑
| 误区 | 典型表现 | 正确做法 |
|---|---|---|
| 把缺失当异常 | 对所有NaN统一ffill |
先区分休市、停牌、数据丢失,再分类处理 |
| 忽略时区 | 跨市场数据时间错位 | 统一为UTC或交易所本地时间,并记录转换规则 |
| 重采样聚合错误 | 用mean聚合OHLC |
开盘取first、最高取max、最低取min、收盘取last |
| 未来函数 | 用报告期对齐财务数据 | 用公告日+merge_asof向后匹配 |
| 重复时间戳未处理 | 回测收益翻倍或异常 | 先drop_duplicates或按业务规则聚合 |
这些误区的共同根源,是把时间序列当成普通表格处理。金融时间序列的每一行都携带“时间语义”,时间轴本身就是模型的一部分。清洗与对齐不是预处理的小步骤,而是决定策略有效性的基础设施。
本课程后续30章将围绕这条主线展开:从时间解析、频率转换、缺失诊断,到多源对齐、交易日历处理、未来函数防范,再到真实金融数据集的端到端实战。你将不仅学会Pandas的API,更会建立一套可复用、可验证、可解释的金融时间序列处理思维。清洗与对齐做对了,后面的因子挖掘和策略回测才有意义。