数据基础与预处理:金融数据源介绍、数据清洗、数据对齐与重采样
做量化这些年,我踩过最大的坑,不是策略失效,而是数据本身出了问题。你想想看,模型再漂亮,喂进去的数据是脏的,结果就是垃圾进、垃圾出。今天咱们就聊聊金融数据的那些事儿——从源头到清洗,再到对齐和重采样,把地基打牢。
金融数据源介绍
金融数据源五花八门,我习惯把它们分成三类:
- 行情数据:股票、期货、外汇的实时或历史价格。包括开盘价、收盘价、最高价、最低价、成交量。
- 基本面数据:财务报表、市盈率、市净率、营收增长率。这些数据更新慢,但价值高。
- 另类数据:新闻情绪、社交媒体热度、卫星图像。嗯,这个领域水很深,但机会也多。
我在项目中遇到过最头疼的事——同一只股票,不同数据源给出的收盘价竟然差了0.01元。别小看这0.01,回测时可能让你多赚或少亏几个点。所以,选数据源要谨慎。
| 数据源 | 特点 | 适用场景 |
|---|---|---|
| Wind | 国内最全,但贵 | 机构级策略 |
| 聚宽/米筐 | API友好,适合回测 | 个人研究 |
| Yahoo Finance | 免费,但数据质量一般 | 快速验证 |
数据清洗:去重与缺失值处理
数据清洗,说白了就是给数据“洗澡”。我见过最离谱的情况——同一个交易日,某只股票出现了三条完全相同的记录。为什么?数据源推送重复了。
去重
去重其实很简单,但要注意“伪重复”。比如,同一只股票在同一天有多个成交记录,但价格不同——这不是重复,是正常数据。真正的重复是:时间戳、代码、价格、成交量全部一模一样。
# 伪代码示例:去重
df = df.drop_duplicates(subset=['date', 'code', 'price', 'volume'])
我曾经因为没去重,导致回测结果虚高。嗯,那感觉就像考试作弊被抓——尴尬又后悔。
缺失值处理
金融数据缺失太常见了。停牌、节假日、数据源故障,都会导致缺失。处理方式有三种:
- 删除:如果缺失比例小于5%,直接删掉。简单粗暴,但有效。
- 填充:用前值填充(ffill)或后值填充(bfill)。我习惯用ffill,因为金融数据有惯性。
- 插值:线性插值或多项式插值。适合时间序列数据。
# 伪代码示例:缺失值处理
df['close'] = df['close'].fillna(method='ffill') # 前值填充
数据对齐与重采样
数据对齐,是量化里最容易被忽视的环节。你想想看,A股和港股交易时间不同,美股还有盘前盘后。如果不做对齐,你的因子计算就是错的。
数据对齐
对齐的核心是“时间戳对齐”。我常用的方法是:
- 确定一个基准时间(比如每天下午3点)。
- 把所有数据源的时间戳对齐到这个基准。
- 如果某个数据源在基准时间没有数据,用前值填充。
举个例子:A股收盘是15:00,港股收盘是16:00。如果你要计算A股和港股的联动因子,必须把港股数据对齐到15:00。否则,你用的就是未来数据——回测时看起来很美,实盘时一塌糊涂。
重采样
重采样,就是把高频数据转成低频,或者反过来。比如,把分钟级数据转成日级数据。我常用的重采样方法:
- 降采样:高频转低频。用OHLC(开盘、最高、最低、收盘)聚合。
- 升采样:低频转高频。用插值或填充。
# 伪代码示例:降采样
df_daily = df_minute.resample('1D').agg({
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum'
})
我个人习惯在做因子发现时,统一使用日级数据。为什么?因为分钟级数据噪声太大,而且计算量也大。除非你做高频交易,否则日级数据足够了。
知识体系总览
下面这张图,是我自己总结的数据预处理流程。每次做新项目,我都会先过一遍这个流程。
你看,数据预处理不是一锤子买卖。它是个循环——回测发现问题,再回来清洗。我做过一个项目,来回迭代了五次,才把数据质量提到可接受的水平。
好了,数据基础就聊到这儿。记住一句话:数据质量决定策略上限。你的模型再牛,也救不了脏数据。