Python实现基于年期的CDS利率线性插值方案问询
年期CDS利率插值函数修改方案
现有数据
标准年期CDS利率数据
Maturity Company 1 Company 2 0 0.5 186.73 186.73 1 1.0 210.65 210.65 2 2.0 249.09 249.09 3 3.0 285.4 285.4 4 4.0 317.59 317.59 5 5.0 344.06 344.06 6 6.0 363.01 363.01 7 7.0 375.69 375.69 8 8.0 384.31 384.31 9 9.0 391.0 391.0 10 10.0 396.12 396.12
待插值的非标准年期数据
Maturity Years 28 0.10410958904109589 29 0.1863013698630137 30 0.27671232876712326 ... 139 9.35191637630662
原日期型对数线性插值函数
此前针对日期型期限实现的函数:
def loglinearinterpolation(df, list_of_dates, dt_rng_name, rate_rng_name): asofDate = pd.to_datetime(list_of_dates) low_lim = df[df[dt_rng_name] <= asofDate].tail(1) upper_lim = df[df[dt_rng_name] >= asofDate].head(1) if low_lim.index == upper_lim.index: return low_lim[rate_rng_name].iloc[0] mat_dt_min = low_lim[dt_rng_name].iloc[0] mat_dt_max = upper_lim[dt_rng_name].iloc[0] y_min = low_lim[rate_rng_name].iloc[0] y_max = upper_lim[rate_rng_name].iloc[0] return np.exp(((np.log(y_max) - np.log(y_min))/((mat_dt_max - mat_dt_min).days))*(asofDate - mat_dt_min).days + np.log(y_min)) df_Libor_interpolated = pd.DataFrame() df_Libor_interpolated = [(pd.to_datetime(x), loglinearinterpolation(df_libor_curve, pd.to_datetime( x), 'Dates', 'value')) for x in df_client_curve['Date'].unique()]
遇到的问题
修改原函数适配年期数据时,因保留日期转换逻辑导致numpy与时间戳类型不匹配报错;使用np.interp的替代方案未达到团队预期结果,需修改原函数适配年期CDS利率插值。
解决方案
1. 对数线性插值(适配年期版本)
保留原函数的对数线性插值逻辑,移除日期相关转换,直接基于数值型年期计算:
import numpy as np import pandas as pd def loglinear_interpolation_years(df, target_year, maturity_col, rate_col): target = float(target_year) # 找到目标年期的上下限记录 low_lim = df[df[maturity_col] <= target].tail(1) upper_lim = df[df[maturity_col] >= target].head(1) # 目标点正好在已有期限上,直接返回对应利率 if low_lim.index.equals(upper_lim.index): return low_lim[rate_col].iloc[0] y_min = low_lim[rate_col].iloc[0] y_max = upper_lim[rate_col].iloc[0] t_min = low_lim[maturity_col].iloc[0] t_max = upper_lim[maturity_col].iloc[0] # 对数线性插值计算 log_y_min = np.log(y_min) log_y_max = np.log(y_max) slope = (log_y_max - log_y_min) / (t_max - t_min) log_interp = log_y_min + slope * (target - t_min) return np.exp(log_interp)
2. 普通线性插值(适配年期版本)
如果团队预期是普通线性插值而非对数线性,可使用以下版本:
def linear_interpolation_years(df, target_year, maturity_col, rate_col): target = float(target_year) low_lim = df[df[maturity_col] <= target].tail(1) upper_lim = df[df[maturity_col] >= target].head(1) if low_lim.index.equals(upper_lim.index): return low_lim[rate_col].iloc[0] y_min = low_lim[rate_col].iloc[0] y_max = upper_lim[rate_col].iloc[0] t_min = low_lim[maturity_col].iloc[0] t_max = upper_lim[maturity_col].iloc[0] # 普通线性插值计算 slope = (y_max - y_min) / (t_max - t_min) return y_min + slope * (target - t_min)
3. 使用示例
假设CDS数据存储在df_cds,待插值数据在df_cds_interpolated中,生成插值结果:
# 生成Company 1的对数线性插值结果 df_cds_interpolated['Company 1 LogLinear'] = df_cds_interpolated['Maturity Years'].apply( lambda x: loglinear_interpolation_years(df_cds, x, 'Maturity', 'Company 1') ) # 生成Company 1的普通线性插值结果 df_cds_interpolated['Company 1 Linear'] = df_cds_interpolated['Maturity Years'].apply( lambda x: linear_interpolation_years(df_cds, x, 'Maturity', 'Company 1') )
关键修改说明
- 移除所有日期转换和日期差计算逻辑,直接使用数值型年期进行运算,避免类型不匹配报错
- 保留原函数"定位上下限→判断是否为已有点→插值计算"的核心流程,确保和原日期型插值行为一致
- 提供两种插值方式,可根据团队预期选择对应版本
内容的提问来源于stack exchange,提问作者ARE
相关产品推荐
相关产品推荐

