上一篇:【基于python的金融分析和风险管理 学习笔记】基础篇 第3到5章 移动统计量 解方程 正态分布检验 回归模型 波动率模型ARCH GARCH
目录
专栏简介
教材信息
《基于python的金融分析和风险管理》 第二版 作者:斯文
《基于python的金融实战案例精粹》第二版 作者:斯文
(从本篇开始,学习笔记结合这两本书)
专栏说明
- 本专栏跳过《基于python的金融分析和风险管理》第1、4章的python语法部分,重点介绍案例和金融分析风险管理领域的知识。案例为原书中的精简概况,出处已标注。
专栏的案例省略了原书在语法讲解上的例子,所以序号不连贯
数据为书中的配套数据,分析与代码为本人原创,如有错误欢迎评论
- 因为从第六章开始就进入了中级篇,所以会出现《基于python的金融实战案例精粹》第二版 中的内容,具体图书如下

知识概括
思维导图:

难点解释:
1. 回购利率
回购利率本质上就是"用债券作抵押借钱的利息 "。比如一家银行短期缺钱,就把手里的国债"卖给"另一家机构,同时约定过几天再买回来,这个过程其实就是借钱,期间支付的利息就是回购利率。它反映的是金融市场上短期资金的紧张程度 ,利率高说明市场缺钱,利率低说明钱比较宽松。
2. 抵补套利(Covered Interest Arbitrage)
抵补套利是一种"锁定汇率风险的套利方式 "。简单说,如果国内和国外的利率不一样,你可以把钱换成外币去赚更高利息,同时在外汇市场上提前锁定未来换回来的汇率(用远期汇率)。这样无论汇率怎么变,你都能确定收益。如果市场没有套利空间,说明利率和汇率之间是"合理匹配"的。
3. 银行间同业拆借利率
这是银行之间"无抵押借钱"的利率 。比如一家银行短期缺资金,就直接向另一家银行借钱,不用抵押物,这种借款叫"同业拆借"。对应的利率就是同业拆借利率。它是金融体系中最基础的资金价格之一,类似"银行之间的基准短期利率"。
4. 央票利率(中央银行票据利率)
央票是央行发行的一种短期债券,用来回收市场上的资金 。当央行觉得市场上钱太多,就发行央票让银行来买,从而把钱"吸走"。央票利率就是这些票据的收益率。利率越高,银行越愿意买,说明央行在收紧流动性。
5. 央行回购利率(公开市场回购利率)
这是央行通过回购操作向市场投放或回收资金时的利率。比如央行用债券做抵押向银行"借钱"或"放钱",对应的利率就是央行回购利率。它是央行调控市场流动性的一个重要工具,直接影响市场上的资金成本,是政策信号很强的利率。
6. 再贴现利率
再贴现可以理解为"银行把已经贴现的票据再拿去央行换钱"。企业拿商业汇票去银行贴现,银行再把这些票据拿给央行换现金,这个过程就是再贴现。央行收取的利息就是再贴现利率。它主要用于支持实体经济融资,属于央行对银行提供资金的一种方式。
7. 再贷款利率
再贷款是央行直接向商业银行提供贷款(通常有政策用途,比如支持农业、小微企业等)。再贷款利率就是央行借钱给银行的利率。它通常比市场利率更有"政策导向" ,用于引导银行把钱投向特定领域,是一种结构性货币政策工具。
案例分析
请先下载数据:点击下载
跟踪并判断全球主要金融市场的基准市场利率走势
《金融实战案例精粹》原书1.9
跟踪并判断全球主要金融市场的基准市场利率走势,基本任务如下:
部分数据如下:
分析
题目解读:
这三列数据分别表示中国、美国(美元)、欧洲(欧元)三大金融市场中银行之间3个月短期资金的借贷利率,本质上都是衡量不同经济体短期资金成本的核心基准利率
SHIBOR3M → 3个月Shibor
指中国的银行间同业拆借利率(Shanghai Interbank Offered Rate),期限为3个月。
可以理解为:中国银行之间短期借钱(3个月)的利率水平,是中国货币市场的重要基准利率。
美元LIBOR3M → 3个月美元Libor
指伦敦银行间美元拆借利率(London Interbank Offered Rate),期限为3个月。
代表国际市场上银行之间用美元借款3个月的成本,长期是全球最重要的利率基准之一。
Euribor:欧元:3个月 → 3个月欧元Euribor
指欧元区银行间同业拆借利率(Euro Interbank Offered Rate),期限为3个月。
表示欧洲银行之间用欧元借款3个月的利率水平,是欧元区的核心市场利率。
实验结果与解读:


本研究选取了2021年5月10日至2021年5月28日期间的三类国际基准利率数据,包括3个月Shibor、3个月美元Libor以及3个月欧元Euribor,共计15个交易日的观测值。从数据特征来看,3个月Shibor整体处于约2.48%至2.54%的区间,明显高于另外两类利率;美元Libor处于0.13%至0.17%之间,水平较低;而欧元Euribor则始终为负值,约在-0.55%至-0.53%之间波动。这表明三大经济体在短期资金价格上存在显著差异,且欧元区处于负利率环境。

从折线图可以直观观察到三类利率的走势差异。Shibor曲线位于最上方,整体呈现小幅下行趋势,说明中国短期资金成本在样本期间有所缓解;美元Libor曲线位于中间,波动较小且略有下降,表现出较强的稳定性;欧元Euribor曲线始终位于零值以下,整体较为平稳,仅存在轻微波动。三条曲线之间的间距较大,反映出不同市场利率水平的明显分层结构。
含义与结论:
从均值和波动率的结果来看,中国Shibor不仅利率水平最高,而且波动幅度也最大,说明中国短期资金市场对流动性变化较为敏感,利率更容易受到政策调控和市场供求变化的影响 。美元Libor处于中等水平且波动适中,体现出美国金融市场较为成熟和稳定的特征 。欧元Euribor长期处于负利率且波动最小,反映出欧元区持续宽松的货币政策环境,市场利率被压低且变化有限 。对金融市场参与者而言,这意味着不同市场在融资成本、风险水平以及利率稳定性方面存在明显差异:高利率往往伴随更高波动,而低利率环境则通常更加稳定但收益较低。
综合分析可知,在研究期间内,三类基准利率在水平和波动性上均呈现出明显的层级结构 ,即Shibor最高且波动最大,美元Libor居中,欧元Euribor最低且最稳定。这一结果不仅反映了不同经济体货币政策取向的差异,也体现了各自金融市场的运行特征。总体而言,中国市场利率较高且变化更为活跃,美国市场相对稳健,而欧洲则处于低利率、低波动的宽松状态。
代码
python
'''
1-9 跟踪并判断全球主要金融市场的基准市场利率走势
'''
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
# ======================
# 0) 解决中文方块问题
# ======================
def set_chinese_font():
candidates = [
"Microsoft YaHei", "SimHei", "PingFang SC",
"Noto Sans CJK SC", "WenQuanYi Micro Hei"
]
available = {f.name for f in font_manager.fontManager.ttflist}
for name in candidates:
if name in available:
plt.rcParams["font.sans-serif"] = [name]
break
plt.rcParams["axes.unicode_minus"] = False
set_chinese_font()
# ======================
# 1) 读取数据
# ======================
data_path = r'C:\Users\victo\Desktop\book_HOPF\ch01\data\1.9 案例数据\Shibor、美元Libor以及欧元Euribor的利率报价.xlsx'
df = pd.read_excel(data_path)
df.columns=df.columns.str.strip()
print("列名:", df.columns.tolist()) # 不是普通的首行即列名的表格
# 更改列名
df = df.rename(columns={
'指标名称': '日期',
'SHIBOR3M': '3个月Shibor',
'美元LIBOR3M': '3个月美元Libor',
'Euribor:欧元:3个月': '3个月欧元Euribor'
})
# 转换日期
df['日期'] = pd.to_datetime(df['日期'])
# 筛选时间区间
df = df[(df['日期'] >= '2021-05-10') & (df['日期'] <= '2021-05-28')]
# ======================
# 2) 任务1:lambda计算均值
# ======================
mean_func = lambda x: np.mean(x)
shibor_mean = mean_func(df['3个月Shibor'])
libor_mean = mean_func(df['3个月美元Libor'])
euribor_mean = mean_func(df['3个月欧元Euribor'])
print("===== 均值(百分之) =====")
print(f"Shibor均值: {shibor_mean:.6f}")
print(f"Libor均值: {libor_mean:.6f}")
print(f"Euribor均值: {euribor_mean:.6f}")
# ======================
# 3) 任务2:def + for计算波动率(标准差)
# ======================
def calc_volatility(series):
n = len(series)
mean = sum(series) / n
var = 0
for i in series:
var += (i - mean) ** 2
var = var / (n - 1)
return np.sqrt(var)
shibor_vol = calc_volatility(df['3个月Shibor'])
libor_vol = calc_volatility(df['3个月美元Libor'])
euribor_vol = calc_volatility(df['3个月欧元Euribor'])
print("\n===== 波动率 =====")
print(f"Shibor波动率: {shibor_vol:.6f}")
print(f"Libor波动率: {libor_vol:.6f}")
print(f"Euribor波动率: {euribor_vol:.6f}")
# ======================
# 4) 任务3:结果比较
# ======================
print("\n===== 比较分析 =====")
means = {
"Shibor": shibor_mean,
"Libor": libor_mean,
"Euribor": euribor_mean
}
vols = {
"Shibor": shibor_vol,
"Libor": libor_vol,
"Euribor": euribor_vol
}
# 均值排序
mean_sorted = sorted(means.items(), key=lambda x: x[1], reverse=True)
vol_sorted = sorted(vols.items(), key=lambda x: x[1], reverse=True)
print("均值(百分之)从大到小排序:")
for k, v in mean_sorted:
print(k, v)
print("\n波动率从大到小排序:")
for k, v in vol_sorted:
print(k, v)
# ======================
# 5) 可视化
# ======================
plt.figure(figsize=(10,6))
plt.plot(df['日期'], df['3个月Shibor'], label='Shibor')
plt.plot(df['日期'], df['3个月美元Libor'], label='美元Libor')
plt.plot(df['日期'], df['3个月欧元Euribor'], label='欧元Euribor')
plt.title('三大基准利率走势对比')
plt.xlabel('日期')
plt.ylabel('利率')
plt.legend()
plt.grid()
plt.show()
撰写汇率分析报告
《金融实战案例精粹》原书3.1
撰写汇率分析报告,基本任务:
部分数据:
分析
实验结果解释:

本研究选取了2021年6月1日至2021年6月11日期间美元兑主要货币的汇率数据,共包含9个交易日、5类汇率指标,分别为欧元兑美元、英镑兑美元、澳元兑美元、美元兑加元以及美元兑日元。从数据结构来看,前3类汇率属于直接标价法(外币兑美元),而后2类属于间接标价法(美元兑外币),因此在数值水平上存在明显差异。其中,英镑兑美元整体水平最高(约1.41附近),澳元兑美元最低(约0.77附近),欧元兑美元和美元兑加元大致处于1.20左右,而美元兑日元则在109--110区间波动。整体来看,各汇率在样本期内波动幅度较小,呈现出短期稳定但存在局部波动的特征,尤其在6月3日附近出现较为明显的阶段性变化。




从可视化结果来看,欧元兑美元汇率在样本期内整体呈现"先下降后小幅回升再回落"的走势,6月3日出现阶段性低点,随后略有反弹,但最终在6月11日再次回落至样本区间低位。三种汇率(英镑兑美元、澳元兑美元、美元兑加元)的对比图显示,这三类汇率在6月4日至9日期间波动较为平缓,走势较为稳定,仅存在轻微的日间波动。五种汇率整体走势图进一步表明,各汇率之间具有一定的同步性,但波动幅度存在差异;通过对美元兑日元进行单位调整后,其走势与其他汇率的对比更加直观。最后,从2021年6月3日的横截面柱状图可以看出,不同货币之间的汇率水平差异显著,英镑兑美元最高,澳元兑美元最低,而美元兑日元(调整后)处于中间水平。
含义和结论:
从短期走势来看,欧元兑美元在样本期内整体偏弱,表明欧元相对于美元略有贬值压力 ,这可能与当时欧洲经济复苏节奏或货币政策预期有关。相比之下,英镑兑美元表现相对稳定,波动较小,说明市场对英镑的预期较为平稳 ;澳元兑美元则略有下行趋势,反映出商品货币在该阶段可能受到外部需求或大宗商品价格波动的影响 。美元兑加元整体呈现小幅上升趋势,意味着加元相对美元略有贬值,这通常与能源市场(如原油价格)变化存在一定关联。美元兑日元波动较小,显示日元在短期内保持相对稳定的避险货币特征。
从多汇率对比来看,不同货币对美元的反应存在差异,但整体波动区间较小,说明在该时间窗口内外汇市场处于相对平稳状态,未出现剧烈冲击或趋势性行情 。同时,各汇率之间呈现一定程度的联动性,说明全球外汇市场在短期内具有较强的整体性和同步性。
综合数据与图形分析结果,可以得出以下结论:在2021年6月初这一短期区间内,美元兑主要货币汇率整体波动幅度较小,外汇市场运行相对稳定;欧元和澳元相对美元略有走弱,而英镑表现较为稳健,加元与日元则基本维持窄幅波动。从结构上看,不同货币之间存在一定的联动关系,但由于经济基本面、政策预期及市场属性差异,其波动方向与幅度并不完全一致。总体而言,该阶段外汇市场未出现明显趋势性行情,而是以震荡整理为主,这一特征对于短期汇率预测和风险管理具有重要参考价值。
代码
python
'''
撰写汇率分析报告
'''
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
# 读取Excel文件
file_path = r"C:\Users\victo\Desktop\book_HOPF\ch03\data\3.1 案例数据\美元兑主要货币汇率.xlsx"
df = pd.read_excel(file_path)
# 去掉列名前后空格
df.columns = df.columns.str.strip()
# 日期列转为 datetime
df["日期"] = pd.to_datetime(df["日期"])
print("原始列名:", list(df.columns))
print(df.head())
# =========================
# 任务1
# =========================
# 先创建包含 2021年6月1日 至 11日 期间欧元兑美元汇率数据的数组
mask1 = (df["日期"] >= "2021-06-01") & (df["日期"] <= "2021-06-11")
df1 = df.loc[mask1, ["日期", "欧元兑美元"]].copy()
date_array = df1["日期"].to_numpy()
eurusd_array = df1["欧元兑美元"].to_numpy()
# 通过数组创建包含该汇率的序列(索引是交易日期)
eurusd_series = pd.Series(data=eurusd_array, index=df1["日期"], name="欧元兑美元")
# 创建包含 6月3日 这5种汇率数据的序列,索引是汇率名称
row_0603 = df.loc[df["日期"] == pd.to_datetime("2021-06-03")].iloc[0]
cols_5 = ["欧元兑美元", "英镑兑美元", "澳元兑美元", "美元兑加元", "美元兑日元"]
series_0603 = pd.Series(data=row_0603[cols_5].values, index=cols_5, name="2021-06-03")
print("\n===== 任务1 =====")
print("交易日期数组:")
print(date_array)
print("\n欧元兑美元汇率数组:")
print(eurusd_array)
print("\n欧元兑美元汇率序列:")
print(eurusd_series)
print("\n2021-06-03 五种汇率序列:")
print(series_0603)
# =========================
# 任务2
# =========================
# 创建 2021年6月4日 至 9日 期间 英镑兑美元、澳元兑美元、美元兑加元 3种汇率数据的数组
mask2 = (df["日期"] >= "2021-06-04") & (df["日期"] <= "2021-06-09")
df2 = df.loc[mask2, ["日期", "英镑兑美元", "澳元兑美元", "美元兑加元"]].copy()
gbpusd_array = df2["英镑兑美元"].to_numpy()
audusd_array = df2["澳元兑美元"].to_numpy()
usdcad_array = df2["美元兑加元"].to_numpy()
# 通过数组生成一个数据框
task2_df = pd.DataFrame({
"英镑兑美元": gbpusd_array,
"澳元兑美元": audusd_array,
"美元兑加元": usdcad_array
}, index=df2["日期"])
print("\n===== 任务2 =====")
print("英镑兑美元数组:")
print(gbpusd_array)
print("\n澳元兑美元数组:")
print(audusd_array)
print("\n美元兑加元数组:")
print(usdcad_array)
print("\n由数组生成的数据框:")
print(task2_df)
# =========================
# 任务3
# =========================
# 创建 2021年6月1日 至 11日 期间 5种汇率数据的数据框
# 行索引是日期,列名是汇率名称
task3_df = df.loc[mask1, ["日期"] + cols_5].copy()
task3_df = task3_df.set_index("日期")
print("\n===== 任务3 =====")
print(task3_df)
# =========================
# 任务4
# =========================
# 将任务1中的欧元兑美元汇率序列转换为列表
eurusd_list = eurusd_series.tolist()
# 将 6月3日 5种汇率数据的序列转换为数组
series_0603_array = series_0603.to_numpy()
# 将任务2中的数据框转换为数组
task2_array = task2_df.to_numpy()
print("\n===== 任务4 =====")
print("任务1中的欧元兑美元序列转换为列表:")
print(eurusd_list)
print("\n6月3日五种汇率序列转换为数组:")
print(series_0603_array)
print("\n任务2中的数据框转换为数组:")
print(task2_array)
# =========================
# 解决中文方块问题
# =========================
def set_chinese_font():
fonts = ["Microsoft YaHei", "SimHei", "SimSun"]
available = {f.name for f in font_manager.fontManager.ttflist}
for f in fonts:
if f in available:
plt.rcParams["font.sans-serif"] = [f]
break
plt.rcParams["axes.unicode_minus"] = False
set_chinese_font()
# =========================
# 数据预处理(日元除以100)
# =========================
task3_df_adj = task3_df.copy()
task3_df_adj["美元兑日元"] = task3_df_adj["美元兑日元"] / 100
task2_df_adj = task2_df.copy()
series_0603_adj = series_0603.copy()
series_0603_adj["美元兑日元"] = series_0603_adj["美元兑日元"] / 100
# =========================
# 图1:欧元兑美元
# =========================
plt.figure(figsize=(12, 6))
plt.plot(eurusd_series.index, eurusd_series.values, marker='o')
plt.title("欧元兑美元汇率走势(2021-06-01 ~ 2021-06-11)")
plt.xlabel("日期")
plt.ylabel("汇率")
# 显示所有日期
plt.xticks(eurusd_series.index, eurusd_series.index.strftime('%m-%d'), rotation=45)
plt.grid()
plt.tight_layout()
plt.show()
# =========================
# 图2:任务2(三种汇率)
# =========================
plt.figure(figsize=(12, 6))
for col in task2_df_adj.columns:
plt.plot(task2_df_adj.index, task2_df_adj[col], marker='o', label=col)
plt.title("三种汇率走势对比(6月4日-9日)")
plt.xlabel("日期")
plt.ylabel("汇率")
plt.xticks(task2_df_adj.index, task2_df_adj.index.strftime('%m-%d'), rotation=45)
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
# =========================
# 图3:五种汇率(含日元调整)
# =========================
plt.figure(figsize=(14, 7))
for col in task3_df_adj.columns:
if col == "美元兑日元":
plt.plot(task3_df_adj.index, task3_df_adj[col], marker='o', label="美元兑日元(/100)")
else:
plt.plot(task3_df_adj.index, task3_df_adj[col], marker='o', label=col)
plt.title("五种汇率整体走势(已调整日元单位)")
plt.xlabel("日期")
plt.ylabel("汇率")
plt.xticks(task3_df_adj.index, task3_df_adj.index.strftime('%m-%d'), rotation=45)
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
# =========================
# 图4:6月3日横截面
# =========================
plt.figure(figsize=(10, 6))
labels = list(series_0603_adj.index)
values = series_0603_adj.values
# 单独标注日元
labels = [l if l != "美元兑日元" else "美元兑日元(/100)" for l in labels]
plt.bar(labels, values)
plt.title("2021-06-03 各汇率对比(已调整日元)")
plt.xlabel("汇率类型")
plt.ylabel("汇率值")
plt.xticks(rotation=45)
plt.grid(axis='y')
plt.tight_layout()
plt.show()
测算远期利率
《金融实战案例精粹》原书6.2
测算远期利率,基本任务:
部分数据:
分析
题目解读:

实验结果和解释:




从计算结果来看,四个时点(2020年9月、2020年12月、2021年3月、2021年6月)的远期利率整体呈现出明显的期限分层特征。短端(1→2年、2→3年)远期利率均为负值,且波动幅度较小,基本维持在-0.0015%附近,反映出短期利率长期处于负利率区间。中端(4→7年)远期利率逐步向零附近收敛,并在部分时点(如2021年3月)转为微弱正值,说明市场对中期利率的预期有所改善。长端(7→10年)远期利率明显上升,且各期均为正值,其中9→10年远期利率在四个时点中均达到最高水平(约0.005%左右),表明长期利率预期持续走高。此外,从时间维度看,2021年整体远期利率水平较2020年有所抬升,尤其是中长期区间,呈现出一定程度的上移趋势。

从图形上看,即期利率曲线整体较为平缓,而远期利率曲线呈现出更明显的上升斜率,尤其在中长期期限段差异显著。2020年9月与12月的利率曲线形态较为相似,均表现为短端低迷、长端上升的结构,但12月的长端远期利率略高于9月,曲线更陡峭。进入2021年后,这一特征更加明显,3月和6月的远期利率曲线在5年期之后快速上升,形成典型的"陡峭化"结构。同时,即期利率曲线始终位于远期利率曲线下方,且变化幅度较小,说明远期利率对未来利率预期的变化更加敏感。总体来看,图中呈现出从短端负利率到长端正利率的明显过渡过程,并且这种结构在2021年进一步强化。
含义和结论:
上述结果反映出典型的"期限结构上升"特征,即远期利率随期限增加而上升,这意味着市场普遍预期未来利率将逐步回升 。在日本长期实行宽松货币政策甚至负利率政策的背景下,短端利率维持在负值区间是政策导向的直接结果,而中长期远期利率转正则反映了市场对未来经济复苏、通胀回升或政策边际收紧的预期 。此外,远期利率曲线在2021年明显陡峭化,说明市场对未来利率上升的预期增强,风险溢价可能有所提高,这通常与经济修复阶段或金融环境逐步正常化有关。
综合分析可得,日本国债利率的远期结构在样本期间内呈现出由短端负利率向长端正利率过渡的上升趋势,且这种趋势在2021年进一步强化。远期利率相较于即期利率更能反映市场对未来利率路径的预期,其持续上升表明市场预期未来利率水平将逐步提高。总体而言,利率期限结构的变化揭示了宏观经济预期改善及货币政策可能调整的信号,对债券投资决策及利率风险管理具有重要参考价值。
代码
python
'''
测算远期利率
'''
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager
# =========================
# 1. 中文字体
# =========================
def set_chinese_font():
candidates = ["Microsoft YaHei", "SimHei", "PingFang SC"]
available = {f.name for f in font_manager.fontManager.ttflist}
for c in candidates:
if c in available:
plt.rcParams['font.sans-serif'] = [c]
break
plt.rcParams['axes.unicode_minus'] = False
set_chinese_font()
# =========================
# 2. 读取数据
# =========================
file_path = r"C:\Users\victo\Desktop\book_HOPF\ch06\data\6.2 案例数据\日本国债利率数据.xlsx"
df = pd.read_excel(file_path)
# 打印列名确认
print("列名如下:")
print(df.columns.tolist())
# 日期处理
df.iloc[:,0] = pd.to_datetime(df.iloc[:,0])
df = df.set_index(df.columns[0])
# =========================
# 3. 解析期限(适配"1年期")
# =========================
def parse_maturity(col):
return float(col.replace('年期', ''))
maturities = np.array([parse_maturity(c) for c in df.columns])
print("\n解析后的期限:", maturities)
# =========================
# 4. 远期利率函数
# =========================
def calc_forward_rates(yields, maturities):
forwards = []
labels = []
for i in range(len(maturities)-1):
t1 = maturities[i]
t2 = maturities[i+1]
R1 = yields[i] / 100
R2 = yields[i+1] / 100
f = (R2 * t2 - R1 * t1) / (t2 - t1)
forwards.append(f * 100)
labels.append(f"{int(t1)}→{int(t2)}年")
return np.array(forwards), labels
# =========================
# 5. 指定日期
# =========================
dates_needed = [
"2020-09-30",
"2020-12-31",
"2021-03-31",
"2021-06-30"
]
data_dict = {}
for d in dates_needed:
idx = df.index.get_indexer([pd.to_datetime(d)], method='nearest')[0]
real_date = df.index[idx]
yields = df.iloc[idx].values.astype(float)
fwd, labels = calc_forward_rates(yields, maturities)
data_dict[d] = (fwd, yields, labels)
print(f"\n==== {d}(实际使用 {real_date.date()})====")
for l, v in zip(labels, fwd):
print(f"{l} 远期利率: {v:.4f}%")
# =========================
# 6. 画图(1x2)
# =========================
fig, axes = plt.subplots(1, 2, figsize=(14,6))
# --- 2020年 ---
for d, color in zip(["2020-09-30", "2020-12-31"], ['blue','red']):
fwd, spot, labels = data_dict[d]
axes[0].plot(maturities[1:], fwd, marker='o', label=f"{d} 远期利率", color=color)
axes[0].plot(maturities, spot, linestyle='--', label=f"{d} 即期利率", color=color)
axes[0].set_title("2020年远期 vs 即期利率")
axes[0].set_xlabel("期限(年)")
axes[0].set_ylabel("利率 (%)")
axes[0].legend()
axes[0].grid(True)
# --- 2021年 ---
for d, color in zip(["2021-03-31", "2021-06-30"], ['green','orange']):
fwd, spot, labels = data_dict[d]
axes[1].plot(maturities[1:], fwd, marker='o', label=f"{d} 远期利率", color=color)
axes[1].plot(maturities, spot, linestyle='--', label=f"{d} 即期利率", color=color)
axes[1].set_title("2021年远期 vs 即期利率")
axes[1].set_xlabel("期限(年)")
axes[1].set_ylabel("利率 (%)")
axes[1].legend()
axes[1].grid(True)
plt.tight_layout()
plt.show()







