第二章:Python金融数据获取——用yfinance和pandas-datareader搞定数据源
做量化交易的朋友都知道,数据是策略的命根子。没有干净、及时的数据,再牛的模型也是白搭。今天这一章,我就带大家搞定两个最常用的数据获取工具:yfinance 和 pandas-datareader。一个管股票,一个管宏观,搭配起来用,效果谁用谁知道。
核心知识点速览:
- yfinance:美股、A股、港股实时/历史数据
- pandas-datareader:美联储、世界银行等宏观数据
- 数据清洗与异常处理实战技巧
2.1 为什么选这两个库?
市面上能获取金融数据的Python库不少,但yfinance和pandas-datareader是我用得最顺手的两个。原因很简单:免费、稳定、社区活跃。
yfinance是Yahoo Finance的非官方API封装。我最早用的时候它还叫fix-yahoo-finance,后来改版成了现在的yfinance。说实话,Yahoo Finance的数据质量在免费数据源里算第一梯队了,尤其是美股数据,覆盖面很广。
pandas-datareader呢,更像是一个数据源的「万能转接头」。它本身不生产数据,但能帮你从美联储、世界银行、OECD等官方机构拉数据。做跨市场分析的时候,宏观数据这块儿基本靠它。
我的小建议:如果你只做股票策略,yfinance一个库就够了。但要做跨市场联动分析,必须把pandas-datareader也加上。宏观数据是连接不同市场的「暗线」,少了它,很多相关性分析做不透。
2.2 安装与环境准备
安装很简单,一行命令搞定:
pip install yfinance pandas-datareader
如果你用的是Anaconda环境,我建议用conda安装:
conda install -c conda-forge yfinance pandas-datareader
嗯,这里要注意一点。pandas-datareader的版本更新比较频繁,有些旧版本的API接口已经废弃了。我建议安装最新版:
pip install --upgrade pandas-datareader
2.3 yfinance实战:美股、A股、港股数据获取
2.3.1 美股数据——最拿手的部分
美股是yfinance的「主场」。苹果、微软、特斯拉这些大票,数据质量非常高。来看个例子:
import yfinance as yf
# 获取苹果公司数据
aapl = yf.Ticker("AAPL")
# 获取历史行情(最近1年)
hist = aapl.history(period="1y")
print(hist.head())
# 获取公司基本信息
info = aapl.info
print(f"公司名称: {info['longName']}")
print(f"市值: {info['marketCap']:,} 美元")
print(f"市盈率: {info['trailingPE']}")
我个人习惯用period参数来指定时间范围,比start/end更简洁。常用的period参数有:
| 参数值 | 含义 |
|---|---|
| 1d | 1天 |
| 5d | 5天 |
| 1mo | 1个月 |
| 3mo | 3个月 |
| 1y | 1年 |
| 5y | 5年 |
| max | 全部历史数据 |
2.3.2 A股数据——加个后缀就行
很多新手不知道,yfinance也能拿A股数据。诀窍就是加后缀:股票代码 + .SS(上海)或 .SZ(深圳)。
# 获取贵州茅台(上海)
maotai = yf.Ticker("600519.SS")
hist_maotai = maotai.history(period="6mo")
print(hist_maotai.tail())
# 获取宁德时代(深圳)
catl = yf.Ticker("300750.SZ")
hist_catl = catl.history(period="6mo")
print(hist_catl.tail())
避坑指南:我曾经在A股数据上栽过跟头。yfinance的A股数据有时会缺失分红除权后的复权价格。如果你做回测,建议用auto_adjust=True参数:
hist = maotai.history(period="1y", auto_adjust=True)
这样拿到的就是调整后的价格,更接近真实交易场景。
2.3.3 港股数据——后缀是.HK
港股和A股类似,加后缀.HK就行。腾讯、阿里、美团这些都能拿:
# 获取腾讯控股
tencent = yf.Ticker("0700.HK")
hist_tencent = tencent.history(period="1y")
# 获取阿里巴巴(港股)
baba_hk = yf.Ticker("9988.HK")
hist_baba = baba_hk.history(period="1y")
你想想看,用同一个API就能拿三个市场的股票数据,做跨市场套利分析的时候有多方便?我经常把美股、A股、港股的数据拉到同一个DataFrame里,直接算相关系数。
2.3.4 批量下载——一次拿多只股票
做策略研究时,很少只分析一只股票。yfinance支持批量下载:
# 批量下载多只股票
tickers = ["AAPL", "MSFT", "GOOGL", "600519.SS", "0700.HK"]
data = yf.download(tickers, period="1y", group_by="ticker")
# 查看苹果的数据
print(data["AAPL"].head())
# 查看腾讯的数据
print(data["0700.HK"].head())
这里有个小技巧:group_by="ticker"会让返回的数据按股票代码分组,结构更清晰。如果不加这个参数,返回的是多级列索引,处理起来稍微麻烦点。
2.4 pandas-datareader实战:宏观数据获取
2.4.1 美联储FRED数据——利率、GDP、CPI
做跨市场分析,宏观数据是绕不开的。美联储的FRED数据库是全球最全的宏观经济数据库之一。pandas-datareader可以直接拉取:
import pandas_datareader.data as web
import datetime
# 设置时间范围
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2024, 12, 31)
# 获取美国10年期国债收益率(代码:DGS10)
treasury_10y = web.DataReader("DGS10", "fred", start, end)
print(treasury_10y.head())
# 获取CPI数据(代码:CPIAUCSL)
cpi = web.DataReader("CPIAUCSL", "fred", start, end)
print(cpi.head())
常用的FRED数据代码我整理了一份:
| 代码 | 含义 |
|---|---|
| DGS10 | 美国10年期国债收益率 |
| DGS2 | 美国2年期国债收益率 |
| CPIAUCSL | 美国CPI(消费者价格指数) |
| GDP | 美国GDP(季度) |
| UNRATE | 美国失业率 |
| FEDFUNDS | 联邦基金利率 |
我的经验:做跨市场联动分析时,我最常用的是「DGS10」和「FEDFUNDS」。利率变化对全球股市都有传导效应。比如美债收益率飙升时,A股的成长股往往承压。这个规律我验证过很多次,准确率还不错。
2.4.2 世界银行数据——全球宏观指标
如果你需要做跨国比较,世界银行的数据源就派上用场了:
# 获取中国GDP增长率(代码:NY.GDP.MKTP.KD.ZG)
china_gdp = web.DataReader("NY.GDP.MKTP.KD.ZG", "worldbank", start, end)
print(china_gdp.head())
# 获取中国、美国、日本的GDP数据对比
countries = ["CHN", "USA", "JPN"]
gdp_data = web.DataReader("NY.GDP.MKTP.CD", "worldbank", start, end)
print(gdp_data.loc[countries].head())
2.5 数据清洗与异常处理
数据拿到手,别急着用。我踩过的坑太多了,总结几条经验:
- 缺失值处理:yfinance偶尔会返回NaN,尤其是节假日。我一般用
ffill()向前填充,或者直接dropna()。 - 时间对齐:美股和A股交易时间不同,做对比分析时一定要对齐日期。我习惯用
pd.merge()做inner join。 - 数据频率:FRED的数据有的是日频,有的是月频。做回归分析前,记得统一频率。
# 数据清洗示例
import pandas as pd
# 假设我们拿到了美股和A股的数据
us_data = yf.download("AAPL", period="1y")["Close"]
cn_data = yf.download("600519.SS", period="1y")["Close"]
# 合并数据,只保留共同交易日
combined = pd.merge(
us_data, cn_data,
left_index=True, right_index=True,
how="inner", suffixes=("_US", "_CN")
)
# 处理缺失值
combined = combined.dropna()
# 计算日收益率
returns = combined.pct_change().dropna()
print(returns.head())
曾经踩过的坑:有一次我拿A股和美股做相关性分析,结果发现相关系数异常高。查了半天才发现,原来是日期没对齐——A股春节休市期间,美股还在交易,数据直接错位了。从那以后,我每次做跨市场分析都会先检查日期索引。
2.6 实战小案例:跨市场联动初探
最后,咱们来个综合案例。把美股、A股、港股和宏观数据结合起来,看看它们之间有没有联动关系:
# 1. 获取股票数据
tickers = ["SPY", "600519.SS", "0700.HK"]
stock_data = yf.download(tickers, period="1y")["Adj Close"]
# 2. 获取宏观数据
start = stock_data.index[0]
end = stock_data.index[-1]
treasury = web.DataReader("DGS10", "fred", start, end)
# 3. 对齐数据
combined = stock_data.join(treasury, how="inner")
combined.columns = ["SPY", "茅台", "腾讯", "美债10Y"]
# 4. 计算相关系数
corr = combined.corr()
print("跨市场相关系数矩阵:")
print(corr)
# 5. 可视化(简单打印)
print(f"\nSPY与茅台的相关系数: {corr.loc['SPY', '茅台']:.3f}")
print(f"腾讯与美债收益率的相关系数: {corr.loc['腾讯', '美债10Y']:.3f}")
这个案例虽然简单,但已经能看出一些端倪了。比如美债收益率上升时,腾讯的股价往往承压——这就是跨市场联动的典型表现。
核心要点回顾:
- yfinance:美股直接写代码,A股加.SS/.SZ,港股加.HK
- pandas-datareader:FRED拿宏观数据,worldbank做跨国对比
- 数据清洗:对齐日期、处理缺失值、统一频率
- 跨市场分析:把不同市场的股票和宏观数据放在一起算相关性
好了,这一章的内容就到这儿。数据获取是量化分析的「地基」,地基打牢了,后面建什么楼都稳当。下一章咱们聊聊数据可视化,把今天拿到的数据画出漂亮的图表。
公众号:蓝海资料掘金营,微信deep3321