第四章:金融数据获取——从Tushare到AkShare的实战之路

数据是量化交易的基石,这话一点不夸张。我见过太多人把精力全花在策略上,结果数据源出了问题,回测跑得飞起,实盘一塌糊涂。今天咱们就聊聊怎么把数据这关过好。

核心要点:本章覆盖数据获取、清洗、存储三大环节。你会掌握Tushare和AkShare两个主流库,学会处理常见的数据坑,并选择最适合的存储方式。

4.1 为什么选Tushare和AkShare?

国内做量化,绕不开这两个库。我个人习惯是:需要高频数据或机构级数据时用Tushare Pro日常研究、快速验证用AkShare。为什么这么分?

  • Tushare Pro:数据质量高,覆盖全面,但需要积分(说白了就是付费)。适合做严肃的回测和实盘。
  • AkShare:完全免费,接口丰富,更新快。但数据源来自公开网站,偶尔会有格式问题。适合学习和快速原型。

我在项目中遇到过这样的情况:用AkShare抓了半年的日线数据,回测收益曲线漂亮得不行。结果一核对,发现某几天数据因为网站改版漏掉了。嗯,从那以后我养成了双源校验的习惯。

4.2 安装与基础配置

先装库,这步没什么难度:

# 安装Tushare
pip install tushare

# 安装AkShare(建议用最新版)
pip install akshare --upgrade

用Tushare需要注册获取token。你想想看,免费的东西往往最贵——这里的「贵」体现在你需要花时间申请权限。不过流程很简单:

import tushare as ts

# 设置token(去tushare.pro官网注册获取)
ts.set_token('你的token_here')
pro = ts.pro_api()

小技巧:我习惯把token写在环境变量里,而不是硬编码在代码中。这样换机器或分享代码时不会泄露密钥。

4.3 实战:获取股票数据

4.3.1 用Tushare获取日线数据

获取某只股票的历史日线,代码很简洁:

# 获取平安银行(000001.SZ)2023年全年日线数据
df = pro.daily(
    ts_code='000001.SZ',
    start_date='20230101',
    end_date='20231231'
)
print(df.head())

返回的字段包括:trade_dateopenhighlowclosevolamount等。注意,Tushare默认按日期降序排列,我一般会手动排序:

df = df.sort_values('trade_date')

4.3.2 用AkShare获取实时行情

AkShare的实时数据接口很丰富。比如获取A股实时行情:

import akshare as ak

# 获取A股实时行情数据
df_real = ak.stock_zh_a_spot_em()
print(df_real.head())

这里有个坑——AkShare返回的列名是中文。我曾经直接拿去做计算,结果报错半天才发现是列名编码问题。建议第一时间重命名:

df_real.columns = ['代码', '名称', '最新价', '涨跌幅', ...]  # 按实际列数调整

注意:AkShare的数据源是东方财富等网站,如果对方接口调整,你的代码可能突然失效。我建议每次运行前检查一下返回的列数是否正常。

4.4 数据清洗与预处理

拿到原始数据只是第一步。真实的数据往往千疮百孔——缺失值、异常值、格式问题,应有尽有。我总结了一套标准流程:

4.4.1 处理缺失值

股票数据最常见的缺失是停牌日。比如某股票停牌一周,那几天的数据就是空的。处理方法:

# 检查缺失值
print(df.isnull().sum())

# 前向填充(用上一个交易日的数据填充)
df.fillna(method='ffill', inplace=True)

# 或者直接删除缺失行(如果缺失不多)
df.dropna(inplace=True)

我个人习惯用前向填充。为什么?因为停牌期间信息没有变化,用前值填充最合理。但如果是财务数据缺失,我会用插值法。

4.4.2 处理异常值

你想想看,一只股票突然涨了1000%,这正常吗?大概率是数据错误。我常用的方法是:

# 用3倍标准差法检测异常
mean = df['close'].mean()
std = df['close'].std()
df = df[(df['close'] > mean - 3*std) & (df['close'] < mean + 3*std)]

不过要注意,新股上市首日涨跌幅可能很大,别误杀了。我曾经就犯过这个错,把一只刚上市的新股数据全删了,回测结果直接少了一段。

4.4.3 统一日期格式

Tushare返回的日期是字符串,AkShare可能是datetime。统一转换成标准格式:

df['trade_date'] = pd.to_datetime(df['trade_date'])
df.set_index('trade_date', inplace=True)

把日期设为索引,后续做时间序列分析会方便很多。

4.5 数据存储:CSV、Excel还是HDF5?

数据清洗完了,得存起来。三种方式各有优劣,我直接给你对比:

存储方式 优点 缺点 适用场景
CSV 通用性强,任何工具都能打开 不支持多表,读写慢,无压缩 小数据量、临时分析
Excel 可视化好,支持多Sheet 速度慢,有行数限制(104万行) 数据量小、需要人工查看
HDF5 读写快,支持压缩,支持大数据 需要额外库,不直观 大规模数据、高频数据

我的建议是:日常研究用CSV生产环境用HDF5。Excel我基本不用,除非要给不懂代码的同事看。

4.5.1 CSV存储示例

df.to_csv('stock_000001.csv', encoding='utf-8-sig')
# 用utf-8-sig编码,避免Excel打开乱码

4.5.2 HDF5存储示例

# 需要安装:pip install tables
df.to_hdf('stock_data.h5', key='000001', mode='a')

# 读取
df_read = pd.read_hdf('stock_data.h5', key='000001')

HDF5支持按key存储多个DataFrame,我习惯把不同股票存到同一个文件的不同key下,读取时按需加载,速度飞快。

避坑指南:我曾经把全市场5000只股票的日线数据存到一个CSV文件里,结果文件超过2GB,打开一次要等5分钟。后来改用HDF5,按股票代码分key存储,读取单只股票的数据只需毫秒级。

4.6 本章知识体系

下面这张图帮你理清整个数据获取与处理的流程:

金融数据获取与处理流程 数据源层 Tushare Pro(付费/高质量) AkShare(免费/快速) 数据清洗与预处理层 缺失值处理(前向填充/删除) 异常值检测(3σ/分位数) 日期格式统一 列名标准化 · 数据类型转换 数据存储层 CSV(通用/小数据) Excel(可视化/小数据) HDF5(高性能/大数据) 量化策略分析与回测

从数据源到最终策略,每一步都有讲究。别想着一步到位,先把数据基础打牢。

本章小结:

  • Tushare适合严肃场景,AkShare适合快速验证
  • 数据清洗是重中之重,缺失值和异常值必须处理
  • 存储方式按需选择,大数据量优先考虑HDF5
  • 养成双源校验的习惯,避免数据错误导致策略失效

好了,数据获取这块就聊到这儿。记住,好的策略需要好的数据支撑。下一章咱们会把这些数据用起来,开始构建第一个量化策略。


公众号:蓝海数据掘金营,微信deep3321