3、数据获取基础:使用pandas-datareader获取股票数据
做量化回测,第一步就是搞数据。没有数据,再牛的策略也是纸上谈兵。
我个人习惯用 pandas-datareader 来拉数据。这玩意儿是 pandas 官方维护的,接口统一,支持多个数据源。说白了,它就是帮你把网络上的金融数据,变成你熟悉的 DataFrame。
3.1 安装与基本用法
先装包,这个简单:
pip install pandas-datareader
然后就可以拉数据了。我拿 A股 举个例,用雅虎财经作为数据源:
import pandas_datareader.data as web
import datetime
start = datetime.datetime(2023, 1, 1)
end = datetime.datetime(2023, 12, 31)
# 获取贵州茅台的数据
# 注意:A股代码需要加上后缀 .SS 或 .SZ
df = web.DataReader('600519.SS', 'yahoo', start, end)
print(df.head())
嗯,这里要注意。雅虎财经对 A股 的支持时好时坏。我在项目中遇到过好几次,明明代码没错,就是拉不到数据。后来发现是网络问题,或者雅虎那边接口调整了。
小技巧:如果雅虎不行,可以试试
'stooq' 数据源。比如 web.DataReader('600519.SS', 'stooq', start, end)。stooq 对 A股 的支持相对稳定一些。
3.2 数据格式与字段说明
拉回来的数据长什么样?我们来看看:
High Low Open Close Volume Adj Close
Date
2023-01-03 1788.00 1720.00 1727.00 1780.00 4100000.0 1780.00
2023-01-04 1790.00 1750.00 1760.00 1785.00 3800000.0 1785.00
2023-01-05 1795.00 1765.00 1770.00 1790.00 4200000.0 1790.00
每个字段的含义如下:
| 字段名 | 说明 | 我的经验 |
|---|---|---|
Open |
开盘价 | 注意,这是当日第一笔成交价,不是集合竞价的价格 |
High |
最高价 | 日内最高成交价,包含上下影线 |
Low |
最低价 | 日内最低成交价 |
Close |
收盘价 | 我一般用这个做策略信号计算 |
Volume |
成交量 | 注意单位,雅虎给的是股数,不是手数 |
Adj Close |
复权收盘价 | 这个很重要!做回测一定要用复权价 |
核心要点:做回测时,请务必使用
Adj Close(复权收盘价)。为什么?因为股票会分红、送股、配股,这些都会导致价格跳空。用原始收盘价做回测,你的策略会被这些非交易因素干扰。我曾经吃过这个亏,回测曲线漂亮得很,实盘一跑就崩。后来才发现是没复权。
3.3 数据存储:CSV vs HDF5
数据拉回来了,总不能每次都去网上拉吧?太慢了,而且万一网络断了呢?我建议存到本地。
常用的存储方式有两种:CSV 和 HDF5。我画了个图,帮你快速理解它们的区别:
3.4 CSV 存储实战
CSV 是最简单的存储方式。说白了,就是纯文本,用 Excel 都能打开。适合数据量不大(几万行以内)的场景。
# 保存到 CSV
df.to_csv('600519.SS.csv')
# 读取 CSV
df = pd.read_csv('600519.SS.csv', index_col=0, parse_dates=True)
这里有个坑。我刚开始做的时候,直接 to_csv 就完事了。后来发现日期列变成了字符串,每次读取都要重新解析。所以记得加上 parse_dates=True。
注意:CSV 文件没有数据类型信息。你存进去的是浮点数,读出来可能变成字符串。尤其是成交量这种大数字,容易被 Excel 自动转换。我建议存 CSV 时,用
float_format='%.2f' 控制一下精度。
3.5 HDF5 存储实战
如果你要存几千只股票、几年的分钟级数据,CSV 就扛不住了。这时候 HDF5 是更好的选择。
HDF5 是二进制格式,读写速度快,还支持压缩。你想想看,同样一份数据,CSV 可能占 1GB,HDF5 压缩后可能只有 200MB。
# 保存到 HDF5
df.to_hdf('stocks.h5', key='600519.SS', mode='a')
# 读取 HDF5
df = pd.read_hdf('stocks.h5', key='600519.SS')
HDF5 有个很爽的特性:支持多表。你可以把多只股票存在同一个文件里,用不同的 key 区分:
# 存多只股票
df1.to_hdf('stocks.h5', key='600519.SS', mode='a')
df2.to_hdf('stocks.h5', key='000001.SZ', mode='a')
# 读取某一只
df_maotai = pd.read_hdf('stocks.h5', key='600519.SS')
我的习惯:我会把同类型的数据(比如所有沪深300成分股)放在一个 HDF5 文件里。key 用股票代码,方便查找。这样管理起来特别清爽,一个文件搞定几百只股票。
3.6 该选哪个?
我个人的建议是这样的:
- 学习阶段、数据量小(< 100MB):用 CSV。简单直观,出错了容易排查。
- 生产环境、数据量大(> 1GB):用 HDF5。速度快,省空间。
- 需要跨语言共享数据:用 CSV。Python、R、Excel 都能读。
- 需要频繁读写、随机访问:用 HDF5。CSV 每次都要全量读写,太慢了。
嗯,数据获取和存储就聊到这儿。记住一句话:数据是量化回测的基石。花点时间把数据管好,后面写策略的时候会省心很多。