第三章:金融数据获取——量化系统的“水源”

做量化交易,第一件事不是写策略,而是搞数据。

我见过太多人,策略写得天花乱坠,结果数据源一断,整个系统直接瘫痪。说白了,数据就是量化系统的“水源”。水源不干净,后面再好的管道也白搭。

核心观点:数据获取不是简单的“下载”,而是一个完整的工程流程——选源、清洗、存储、管理。每一步都可能踩坑。

金融数据获取 A股数据(Tushare) 美股数据(Yahoo Finance) 数据清洗与预处理 日线/分钟线 财务/基本面 实时行情 历史数据 缺失值处理 复权/对齐 数据存储:CSV / HDF5 / 数据库

3.1 用Tushare获取A股数据

Tushare是国内用得最多的免费数据源之一。我个人习惯用它来拉A股的日线数据,稳定且字段齐全。

先装包:

pip install tushare

然后注册一个token(去tushare.pro官网申请,免费的)。

看个例子:

import tushare as ts

# 设置token
ts.set_token('你的token')

# 初始化接口
pro = ts.pro_api()

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

小提示:Tushare的接口有频率限制,普通用户每分钟最多200次。我建议你写个简单的限流器,不然跑着跑着就被封了。

除了日线,Tushare还能拿财务数据、行业分类、龙虎榜等。比如拿个利润表:

# 获取利润表
income = pro.income(ts_code='000001.SZ', start_date='20230101', end_date='20231231')
print(income.columns.tolist())

嗯,这里要注意——财务数据是按季度发布的,不是每天都有。你拉下来之后会发现很多空值,后面清洗的时候要处理。

3.2 用Yahoo Finance获取美股数据

美股数据,我首选Yahoo Finance。免费、覆盖广、历史数据全。不过它有个毛病——经常被墙,需要科学上网。

推荐用 yfinance 这个库,比原生的 pandas-datareader 好用太多:

pip install yfinance

拉取苹果公司的数据:

import yfinance as yf

# 下载苹果公司数据
aapl = yf.download('AAPL', start='2023-01-01', end='2023-12-31')
print(aapl.head())

yfinance返回的是pandas DataFrame,列名是Open、High、Low、Close、Volume、Adj Close。注意,它默认返回的是调整后的价格(Adj Close),这个在回测时很重要。

避坑指南:我曾经在回测时直接用Close价格,结果发现分红除权后价格跳空,策略信号全乱了。后来才意识到要用Adj Close。你想想看,如果不用复权价格,你的回测结果就是错的。

yfinance还能拿财报数据:

# 获取苹果公司财报
aapl_info = yf.Ticker('AAPL')
financials = aapl_info.financials
print(financials.head())

3.3 数据清洗与预处理

数据拉下来之后,千万别直接用。我敢说,90%的原始数据都有问题。

常见的坑:

  • 缺失值:停牌日、节假日、数据源漏了
  • 异常值:价格突然跳变、成交量少个零
  • 时间不对齐:A股和美股交易时间不同,合并时要注意
  • 复权问题:前复权还是后复权?不同策略要求不同

我的清洗流程一般是这样的:

import pandas as pd
import numpy as np

# 假设df是原始数据
def clean_data(df):
    # 1. 删除全空的行
    df = df.dropna(how='all')
    
    # 2. 填充缺失值(用前向填充)
    df = df.fillna(method='ffill')
    
    # 3. 删除异常值(比如价格小于0)
    df = df[df['close'] > 0]
    
    # 4. 排序(按时间升序)
    df = df.sort_index()
    
    return df

# 使用
df_clean = clean_data(df)

重点:前向填充(ffill)是处理金融时间序列最常用的方法。因为停牌日的价格应该等于上一个交易日,而不是0或者空。

还有一个容易被忽略的点——时间对齐。如果你同时做A股和美股,它们的交易时间不一样。A股是9:30-15:00,美股是21:30-04:00(夏令时)。合并数据时,我习惯把时间统一成UTC+8,然后按日对齐。

3.4 数据存储:CSV / HDF5 / 数据库

数据清洗完了,得存起来。三种方式各有优劣:

存储方式 优点 缺点 适用场景
CSV 简单、通用、可读 慢、占用空间大 小数据量、调试用
HDF5 快、压缩率高、支持大数据 二进制、不易查看 中等数据量、日常回测
数据库(MySQL/PostgreSQL) 支持复杂查询、并发访问 部署复杂、维护成本高 生产环境、团队协作

我个人习惯:

  • 开发调试时用CSV,方便看数据
  • 回测时用HDF5,速度快
  • 上线后用数据库,支持多进程读写

存成CSV很简单:

df_clean.to_csv('aapl_data.csv', index=False)

存成HDF5:

df_clean.to_hdf('market_data.h5', key='aapl', mode='w')

存到MySQL:

from sqlalchemy import create_engine

engine = create_engine('mysql+pymysql://user:password@localhost/mydb')
df_clean.to_sql('stock_data', engine, if_exists='replace', index=False)

小技巧:HDF5支持压缩,存同样的数据,体积只有CSV的1/3左右。而且读取速度比CSV快10倍以上。我建议你回测时都用HDF5。

嗯,数据存储这块,其实没有绝对的好坏。你想想看,如果你只是自己跑跑策略,CSV完全够用。但如果你要搭建一个实盘系统,数据库是必须的。

好了,这一章的内容就到这里。数据获取是整个量化系统的基石,花时间把这一步做好,后面会省很多事。


专注资料整理