第三章:Python环境搭建与数据获取
做利率曲线建模,第一步不是写模型,而是搞定数据。
我见过太多人,模型写得飞起,结果数据源一换,全盘崩溃。说白了,数据是地基,地基不稳,楼盖得再高也是危房。
这一章,咱们就踏踏实实把数据获取这件事捋清楚。我会带你用 pandas-datareader 拉美国国债收益率,再用 Treasury API 拿中国国债数据。两条腿走路,以后做跨境分析也不慌。
3.1 环境准备:先把家伙事儿备齐
我个人习惯,每次开新项目都先建一个干净的虚拟环境。别嫌麻烦,这能省掉后面80%的依赖冲突问题。
# 创建虚拟环境
python -m venv rates_env
source rates_env/bin/activate # Mac/Linux
# 或者 rates_env\Scripts\activate # Windows
# 安装核心库
pip install pandas numpy matplotlib seaborn
pip install pandas-datareader
pip install requests # 调用中国国债API用
嗯,这里要注意:pandas-datareader 的版本别太老,我建议用 0.10 以上。之前有个学员用 0.8 版本,死活连不上 FRED 的数据源,折腾了两小时才发现是版本问题。
3.2 美国国债收益率:用 pandas-datareader 搞定
美国国债收益率数据,最权威的来源是 FRED(联邦储备经济数据)。pandas-datareader 直接封装好了接口,用起来非常顺手。
你想想看,FRED 里存了上百年的利率数据,而且完全免费。做量化的人要是不知道 FRED,就像厨师不知道盐在哪。
3.2.1 获取关键期限的收益率
我们通常关注这几个期限:3个月、2年、5年、10年、30年。对应的 FRED 代码分别是:
| 期限 | FRED 代码 | 说明 |
|---|---|---|
| 3个月 | DGS3MO | 短期基准 |
| 2年 | DGS2 | 中期前端 |
| 5年 | DGS5 | 中期中段 |
| 10年 | DGS10 | 长期基准,最重要 |
| 30年 | DGS30 | 超长期 |
import pandas as pd
import pandas_datareader.data as web
from datetime import datetime
# 设置时间范围
start = datetime(2020, 1, 1)
end = datetime(2024, 12, 31)
# 定义要获取的收益率代码
tickers = ['DGS3MO', 'DGS2', 'DGS5', 'DGS10', 'DGS30']
# 一次性拉取所有数据
df_us = web.DataReader(tickers, 'fred', start, end)
# 重命名列,方便阅读
df_us.columns = ['3M', '2Y', '5Y', '10Y', '30Y']
# 查看前几行
print(df_us.head())
跑完这段代码,你会得到一个 DataFrame,每一列就是一条收益率曲线上的一个点。我在项目中遇到过一个问题:FRED 的数据在周末和节假日是缺失的。所以拿到数据后,第一件事就是检查缺失值。
# 检查缺失值比例
missing_ratio = df_us.isnull().sum() / len(df_us)
print(missing_ratio)
如果缺失比例超过 5%,我建议用前向填充法(ffill)补上。毕竟利率市场有连续性,周末的收益率通常沿用周五的值。
3.2.2 可视化:看一眼曲线长啥样
数据拉下来,别急着建模。先画个图,直观感受一下。
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
for col in df_us.columns:
plt.plot(df_us.index, df_us[col], label=col, linewidth=1.5)
plt.title('US Treasury Yield Curve (2020-2024)', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Yield (%)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
这张图一出来,你就能看到 2020 年疫情爆发时收益率暴跌,2022 年美联储加息后收益率飙升。嗯,这就是数据的力量——它把宏观事件刻在了曲线上。
3.3 中国国债收益率:用 Treasury API 获取
中国国债数据,情况稍微复杂一点。Wind 有,但收费。Tushare 也有,但需要积分。我个人最常用的,是中国债券信息网(ChinaBond)提供的公开 API。
说白了,就是直接请求一个 JSON 接口,解析一下就能用。虽然官方文档写得有点含糊,但摸清楚规律后,其实挺稳定的。
3.3.1 获取关键期限的收益率
中国国债的活跃期限包括:1年、3年、5年、7年、10年。对应的 API 参数如下:
import requests
import json
def fetch_china_bond_yields():
"""
从中国债券信息网获取国债收益率
返回一个字典,key为期限,value为收益率
"""
url = "https://yield.chinabond.com.cn/cbweb-mn/yc/ycDetail"
# 请求参数
params = {
'ycType': '0', # 0表示国债收益率曲线
'startDate': '2024-01-01',
'endDate': '2024-12-31',
'termType': '1' # 1表示关键期限
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
try:
response = requests.get(url, params=params, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
return data
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return None
# 调用函数
china_data = fetch_china_bond_yields()
我曾经踩过一个坑:这个 API 对请求频率有限制,如果你每秒发超过 5 次请求,会被封 IP 半小时。所以批量拉数据时,记得加个 time.sleep(0.3)。
3.3.2 解析返回的数据
API 返回的 JSON 结构有点嵌套,需要耐心拆解。我一般这样处理:
def parse_china_yields(raw_data):
"""
解析API返回的JSON数据
提取日期、期限、收益率
"""
records = []
# 假设返回结构中有 'data' 字段
if raw_data and 'data' in raw_data:
for item in raw_data['data']:
date = item.get('date')
term = item.get('term') # 期限,如 '1Y', '3Y'
yield_val = item.get('yield') # 收益率
if date and term and yield_val is not None:
records.append({
'date': date,
'term': term,
'yield': float(yield_val)
})
# 转为DataFrame
df = pd.DataFrame(records)
# 透视成宽表格式:行=日期,列=期限
df_pivot = df.pivot_table(
index='date',
columns='term',
values='yield'
)
return df_pivot
# 解析数据
df_cn = parse_china_yields(china_data)
print(df_cn.head())
你想想看,中美两国的收益率数据现在都在你手里了。接下来做利差分析、相对价值交易,素材就齐了。
3.4 数据质量检查:别让脏数据毁了模型
数据拿到手,别急着用。先做三件事:
- 检查缺失值:用
df.isnull().sum()看一眼 - 检查异常值:收益率突然跳升 500 个基点?那多半是数据错误
- 检查日期连续性:确保交易日都有数据,没有跳空
3.5 本章知识体系
下面这张图,帮你把本章的核心逻辑串起来:
好了,数据到手,环境就绪。下一章咱们就开始动手搭建第一条收益率曲线。记住,数据质量决定了模型的上限,别在这个环节偷懒。
公众号:蓝海资料掘金营,微信deep3321