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。我画了个图,帮你快速理解它们的区别:

数据存储方案对比 pandas-datareader CSV 存储 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 每次都要全量读写,太慢了。

嗯,数据获取和存储就聊到这儿。记住一句话:数据是量化回测的基石。花点时间把数据管好,后面写策略的时候会省心很多。


专注资料整理