数据获取与预处理:金融时间序列的源头活水
做市场关联性网络,第一步就是搞数据。这活儿看着简单,其实坑特别多。我刚开始做量化那会儿,觉得数据嘛,拉下来就能用,结果被各种奇葩问题折磨得够呛。今天咱们就把这块掰开揉碎了讲清楚。
2.1 数据来源:去哪儿拿靠谱的数据?
金融数据源,说白了就两类:免费的跟付费的。咱们做研究,免费的基本够用。
2.1.1 Yahoo Finance
这个大家应该不陌生。Yahoo Finance 的数据覆盖面广,全球主要市场的股票、ETF、指数都有。我习惯用 yfinance 这个 Python 库来拉数据,简单粗暴。
import yfinance as yf
# 下载贵州茅台和五粮液的历史数据
tickers = ["600519.SS", "000858.SZ"]
data = yf.download(tickers, start="2020-01-01", end="2023-12-31")
print(data.head())
2.1.2 Tushare
做 A 股研究,Tushare 是绕不开的。数据质量高,字段全,就是需要注册拿 token。我个人觉得,花几分钟注册一下,绝对值。
import tushare as ts
# 设置 token
ts.set_token('你的token')
pro = ts.pro_api()
# 获取平安银行日线数据
df = pro.daily(ts_code='000001.SZ', start_date='20200101', end_date='20231231')
print(df.head())
2.1.3 其他数据源
除了上面两个,还有几个我偶尔会用:
- Quandl:宏观数据很全,适合做因子研究
- Alpha Vantage:免费但有次数限制
- Wind / Choice:机构用的多,数据最干净,但贵
2.2 数据清洗:脏数据是模型的毒药
数据拉下来,千万别直接算收益率。你想想看,如果原始数据里有个跌停价被记成了涨停价,那算出来的相关系数全歪了。我吃过这个亏,现在每次拿到数据第一件事就是清洗。
2.2.1 缺失值处理
金融时间序列的缺失值,常见原因有:停牌、节假日、数据源抽风。处理方式分几种:
| 方法 | 适用场景 | 我的建议 |
|---|---|---|
| 向前填充 | 停牌导致的价格缺失 | 最常用,用上一个交易日的价格 |
| 插值法 | 日内数据的小缺口 | 线性插值简单有效 |
| 直接删除 | 缺失比例超过 20% | 这种股票建议直接剔除 |
# 向前填充缺失值
df.fillna(method='ffill', inplace=True)
# 或者用插值
df.interpolate(method='linear', inplace=True)
2.2.2 异常值处理
异常值怎么找?我一般用两种方法:
- 3σ 原则:超过均值±3倍标准差的值,标记为异常
- 百分位法:低于 0.5% 或高于 99.5% 分位数的值,需要检查
2.3 收益率计算:简单还是对数?
收益率计算,是构建关联性网络的核心输入。这里有两个选择:
2.3.1 简单收益率
公式:R_t = (P_t - P_{t-1}) / P_{t-1}
优点:直观,容易理解。缺点:时间不可加,多期收益率不能直接相加。
2.3.2 对数收益率
公式:r_t = ln(P_t / P_{t-1})
优点:时间可加性,多期收益率可以直接相加。而且对数收益率近似正态分布,很多统计模型都喜欢它。
import numpy as np
# 计算对数收益率
df['log_return'] = np.log(df['close'] / df['close'].shift(1))
# 去掉第一行的 NaN
df.dropna(inplace=True)
2.4 数据对齐与频率统一
做关联性网络,最怕什么?时间轴对不上。比如 A 股和港股,节假日不一样,交易时间也不一样。如果不做对齐,算出来的相关系数就是错的。
2.4.1 时间对齐
我常用的方法是:以某个基准时间序列为准,其他序列按这个时间轴对齐。缺失的用 NaN 填充,然后统一处理。
# 假设 df1 是基准,df2 和 df3 需要对齐
aligned_data = pd.concat([df1, df2, df3], axis=1, join='inner')
# join='inner' 只保留所有数据都存在的日期
2.4.2 频率统一
不同数据源的频率可能不一样。Yahoo Finance 默认是日频,Tushare 可以选日、周、月。做关联性网络,我建议统一用日频。为什么?
- 日频数据量够大,统计显著性好
- 周频和月频会丢失太多信息
- 高频数据(分钟级)噪声太大,不适合做网络分析
知识体系总览
下面这张图,把数据获取与预处理的整个流程串起来了。你可以把它当作一个检查清单,每次做数据准备时对照着来。
嗯,数据准备这块就讲这么多。记住一句话:数据质量决定了你模型的上限。花 80% 的时间在数据上,一点都不夸张。