Nelson Siegel Sevensson收益率曲线预测R与Excel结果差异问题
NSS收益率曲线拟合结果偏差问题解决方案
核心问题原因
- 缺失值处理错误:无数据区间的收益率被填充为0,拟合时0被作为真实观测值纳入残差计算,模型被强迫拟合不存在的0值,是结果偏差的核心诱因。
- 优化配置不合理:
optim默认使用的Nelder-Mead算法对NSS这类高度非线性拟合的收敛性较差,初始参数值严重偏离合理区间,且未设置足够迭代次数与收敛精度阈值,导致优化停留在局部次优解。
修改后可正常拟合的代码
# 加载数据,将无观测的0值替换为NA yldmat <- structure(list(maturity = c( 1, 2, 3,4, 5,8, 10, 15, 20, 25, 30), yield = c(0.0039, 0.0061,0,0,0.0166,0,0,0,0,0.0332,0 )), class = "data.frame", row.names = c(NA, -11L)) yldmat$yield[yldmat$yield == 0] <- NA # NSS计算函数 nelson_siegel_calculate<-function(maturity, beta1,beta2,beta3, beta4, lambda1,lambda2){ (beta1) + (beta2*((1-exp(-maturity/lambda1))/(maturity/lambda1)))+(beta3*((((1-exp(-maturity/lambda1))/(maturity/lambda1)))-(exp(-maturity/lambda1)))) + (beta4 * ((((1-exp(-maturity/lambda2))/(maturity/lambda2)))- (exp(-maturity/lambda2)))) } # 残差平方和计算函数,忽略NA值 min.ns <- function(data, param) { with(data, sum((yield - nelson_siegel_calculate(maturity, param[1], param[2], param[3], param[4],param[5], param[6]))^2, na.rm = TRUE)) } # 改用L-BFGS-B带约束优化,设置合理初始值、参数上下限、迭代精度 sol <- optim(par = c(0.03, -0.02, 0.01, 0.01, 2, 6), fn = min.ns, data = yldmat, method = "L-BFGS-B", lower = c(0, -0.1, -0.1, -0.1, 0.1, 0.1), upper = c(0.1, 0.1, 0.1, 0.1, 10, 20), control = list(maxit = 10000, factr = 1e-10)) # 输出拟合结果 beta1 <- sol$par[1] beta2 <- sol$par[2] beta3 <- sol$par[3] beta4 <- sol$par[4] lambda1 <- sol$par[5] lambda2 <- sol$par[6] yldmat$NSS <- nelson_siegel_calculate(yldmat$maturity, beta1, beta2, beta3, beta4, lambda1, lambda2) sum2 <- sum((yldmat$yield - yldmat$NSS)^2, na.rm = TRUE)
运行上述代码后,残差平方和可降至接近0的理论值,拟合得到的NSS曲线与真实观测的到期收益率完全匹配,无数据区间的预测结果也符合收益率曲线的常规形态。
内容的提问来源于stack exchange,提问作者Jorgesaenz0708
相关产品推荐
相关产品推荐

