Nelson-Siegel-Svensson in Python;使用纳尔逊-西格尔-斯文森估计即期汇率曲线(1994)

news2024/10/6 8:29:20

一、说明

        Nelson-Siegel-Svensson (1994) 模型通过添加 1987 个额外的曲线估计参数来修改 Nelson-Siegel (2) 模型。虚拟任何收益率曲线形状都可以使用这两种模型进行插值,这两种模型在世界各地的银行中广泛使用。

图1

二、插值和外推

        有时,时间序列数据集中存在缺失值。例如,可能存在第 1 年到 3 年的利率,然后是第 5 年到 8 年,然后是第 10 年。纳尔逊-西格尔模型也可用于预测或推断超出可用数据时间段的未来时间段的值。

        已知 X 值表示轴上的值是预先已知的值,例如时间或年份),已知 Y 值表示 y 轴上的值(在本例中为已知利率)。y 轴变量通常是您希望从将来插入缺失值或将值外推到将来的变量。

三、纳尔逊-西格尔-斯文森〔1994〕 模特

        Nelson-Siegel-Svensson(1994)模型用于生成利率和收益率曲线估计的期限结构。需要计量经济学建模技术来校准此模型中多个输入的值。

        Nelson-Siegel-Svensson (1994) 模型通过添加额外的广义参数来修改 Nelson-Siegel (1987) 模型。虚拟任何收益率曲线形状都可以使用这两种模型进行插值,这两种模型在世界各地的银行中广泛使用。

        Nelson-Siegel-Svensson (1994) 模型使用 6 个曲线估计参数运行,而 Nelson-Siegel (1987) 模型使用 4 个曲线估计参数运行。如果建模得当,Nelson-Siegel-Svensson(1994)模型几乎可以适应任何收益率曲线形状。

        校准Nelson-Siegel-Svensson(1994)模型中的输入需要计量经济学建模和误差优化技术。Nelson-Siegel-Svensson(1994)模型用于“填补缺失的现货收益率和利率期限结构的空白”,该模型可用于插值利率时间序列中的缺失数据点(以及其他宏观经济变量,如通货膨胀率和商品价格或市场回报),也可用于推断给定或已知范围之外, 用于预测目的。

四、纳尔逊-西格尔-斯文森收益率曲线拟合法

        纳尔逊-西格尔方法以其简单性而闻名,但它可能无法与在紧张的市场环境中观察到的所有到期日的零收益率相匹配。

图2

1994年,斯文森试图通过在现有的纳尔逊-西格尔公式中添加一个额外的项来创建更灵活的版本,该公式包含两个额外的参数。他漂亮而简单的想法是通过重用他前任方程的最后一个项来创建附加项。

这是最终公式:

图3

其中 β0、β1、β2、β3、λ0 和 λ1 是常数参数,T 是以年为单位的成熟时间。

在我们进入任何python之前,让我们描述一下我们的问题。

五、根本问题

        我们生活在一个叫以色列的国家(以色列在中东的某个地方,它的首都叫耶路撒冷)。在耶路撒冷坐落着以色列的中央银行,称为以色列银行。

        以色列银行提供标准的无风险收益率曲线,是该国风险最低的银行(因此,它提供标准收益率曲线。例如,假设以色列银行只有一定数量的债券。

        让我们看看以色列政府目前有哪些债券未偿还。所以它有:

  • 1年期债券,目前的收益率为0.39%。
  • 2年期债券,目前的收益率为0.61%。
  • 5年期债券,目前的收益率为1.66%。
  • 10年期债券,目前的收益率为2.58%。
  • 25年期债券,目前的收益率为3.32%。

        好吧,这很好,唯一的问题是,如果我们从这些数字建立收益率曲线,问题是我们之间没有任何数字。我们希望得到一个漂亮的收益率曲线。

        为什么我们要得到一个完整的漂亮曲线?例如,之所以说原因是因为我们有一个客户在以色列与我们联系,为了从这个特定客户那里获得 10,000,000 以色列谢克尔 (ILS) 的利润,我们需要对两件事有一个非常好的估计:

  • 以色列银行20年期国债收益率。
  • 以色列银行30年期国债收益率。

        不幸的是,当然,正如我们从我们的列表中看到的那样,我们没有这些数字,我们有10年,我们有25年,但我们没有20年,我们没有30年。那么,我们是否要向客户的ILS 10,000,000利润挥手告别?或者我们是否会有一个非常好的受过教育的尝试,试图在特定收益率曲线上创造那些缺失的点点滴滴?

嗯,我们可以。我们可以使用一种叫做纳尔逊-西格尔-斯文森方法的东西来产生真正有根据的猜测,关于中间的那些位应该是什么,以及那些外推的点应该是什么。

六、The Jupyter Notebook

        让我们创建一个新的 jupyter 笔记本。

from scipy.optimize import fmin
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

dd = pd.read_csv('ns.csv')
df = dd.copy()
df.style.format({'Maturity': '{:,.0f}'.format,'Yield': '{:,.2%}'})

 

图4

        你会注意到我们没有我们想插值的20年,我们没有我们想推断的30年,因为如果我们能推断这些东西,那么我们将计算出这些数字。我们将能够获得10,000,000新谢克尔的利润,这就是我们想要做的。

sf = df.copy()
sf = sf.dropna()
sf1 = sf.copy()
sf1['Y'] = round(sf['Yield']*100,4)
sf = sf.style.format({'Maturity': '{:,.2f}'.format,'Yield': '{:,.4%}'})
import matplotlib.pyplot as plt
import matplotlib.markers as mk
import matplotlib.ticker as mtick
fontsize=15
fig = plt.figure(figsize=(13,7))
plt.title("Nelson-Siegel-Svensson Model - Unfitted Yield Curve",fontsize=fontsize)
ax = plt.axes()
ax.set_facecolor("black")
fig.patch.set_facecolor('white')
X = sf1["Maturity"]
Y = sf1["Y"]
plt.scatter(X, Y, marker="o", c="blue")
plt.xlabel('Period',fontsize=fontsize)
plt.ylabel('Interest',fontsize=fontsize)
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
ax.xaxis.set_ticks(np.arange(0, 30, 5))
ax.yaxis.set_ticks(np.arange(0, 4, 0.5))
ax.legend(loc="lower right", title="Yield")
plt.grid()
plt.show()

图5

所以,你可以看到我们这里有这种粗糙的收益率曲线。我们需要知道20年和30年。让我们看看我们将如何获得这种纳尔逊-西格尔-斯文森方法。

我们需要做的第一件事是输入 3 个校准数字。如果您在互联网上搜索纳尔逊-西格尔-斯文森模型,您会发现您可以输入的这些校准数字。

我建议这些是相当不错的猜测,因此对于 4 个 beta 数字,将 0.01 放入 2 个 lambda 放射性衰变样式数字,我建议 1.0 是一个很好的起始值。现在这些将由一个名为scipy.optimize.fmin的函数进行更改。

β0 = 0.01
β1 = 0.01
β2 = 0.01
β3 = 0.01
λ0 = 1.00
λ1 = 1.00

        我们现在要做的是构建一条曲线,这条曲线不会有任何好处,但稍后会通过称为 fmin 函数的特殊 scipy.optimize 魔法进行更改。我需要在我的数据帧上名为“NSS”的新列中构建另一条曲线,当我在此列中构建另一条曲线时,神奇的技术解决方案将移动这些曲线以使收益率曲线(即我的数据帧上的“收益率”列)符合上述数字。

        让我们把 Nelson-Siegel-Svensson 公式放在这里,我们现在要使用它

Figure 5

        正如你所看到的,它有点像一个怪物。


df['NSS'] = (β0)+(β1*((1-np.exp(-df['Maturity']/λ0))/(df['Maturity']/λ0)))+(β2*((((1-np.exp(-df['Maturity']/λ0))/(df['Maturity']/λ0)))-(np.exp(-df['Maturity']/λ0))))+(β3*((((1-np.exp(-df['Maturity']/λ1))/(df['Maturity']/λ1)))-(np.exp(-df['Maturity']/λ1))))
df.style.format({'Maturity': '{:,.0f}'.format,'Yield': '{:,.2%}','NSS': '{:,.2%}'})

图6

让我们可视化未拟合的收益率曲线

df1 = df.copy()
df['Y'] = round(df['Yield']*100,4)
df['NSS'] =(β0)+(β1*((1-np.exp(-df['Maturity']/λ0))/(df['Maturity']/λ0)))+(β2*((((1-np.exp(-df['Maturity']/λ0))/(df['Maturity']/λ0)))-(np.exp(-df['Maturity']/λ0))))+(β3*((((1-np.exp(-df['Maturity']/λ1))/(df['Maturity']/λ1)))-(np.exp(-df['Maturity']/λ1))))
df['N'] = round(df['NSS']*100,4)
df2 = df.copy()
df2 = df2.style.format({'Maturity': '{:,.2f}'.format,'Y': '{:,.2%}', 'N': '{:,.2%}'})
import matplotlib.pyplot as plt
import matplotlib.markers as mk
import matplotlib.ticker as mtick
fontsize=15
fig = plt.figure(figsize=(13,7))
plt.title("Nelson-Siegel-Svensson Model - Unfitted Yield Curve",fontsize=fontsize)
ax = plt.axes()
ax.set_facecolor("black")
fig.patch.set_facecolor('white')
X = df["Maturity"]
Y = df["Y"]
x = df["Maturity"]
y = df["N"]
ax.plot(x, y, color="orange", label="NSS")
plt.scatter(x, y, marker="o", c="orange")
plt.scatter(X, Y, marker="o", c="blue")
plt.xlabel('Period',fontsize=fontsize)
plt.ylabel('Interest',fontsize=fontsize)
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
ax.xaxis.set_ticks(np.arange(0, 30, 5))
ax.yaxis.set_ticks(np.arange(0, 4, 0.5))
ax.legend(loc="lower right", title="Yield")
plt.grid()
plt.show()

图7

        我们现在得到的是,我们现在已经走了未拟合的曲线,这就像我们制作西装之前西装的材料一样,我们将对这些校准统计数据进行一些定制,我们将使西装适合蓝点,我们将使用特殊的 fmin 函数来做到这一点。在我们执行此操作之前,我需要在数据帧上名为“残差”的新列中构建另一条曲线。

        我们采用一种称为特殊残差的东西,我们将采用蓝点和未拟合曲线之间的一些误差。我们将采用这些错误,然后对这些错误进行平方以消除任何负号。

df['Residual'] =  (df['Yield'] - df['NSS'])**2
df22 = df[['Maturity','Yield','NSS','Residual']]  
df22.style.format({'Maturity': '{:,.0f}'.format,'Yield': '{:,.2%}','NSS': '{:,.2%}','Residual': '{:,.9f}'})

 

图8

        现在我们采用存在于蓝点和蓝点存在的橙色点之间的所有这些误差项,因此我们采用这些项对它们进行平方。然后我要做的是把它们都加起来。

np.sum(df['Residual'])

0.0011625691502601255

        现在这就是魔力的用武之地。我要做的是调用 fmin 函数,我将在上述 6 个值上运行它,求解将上下摇晃这些东西,上下摇晃,上下,上下,这将使“NSS”列上的值上下波动, 上下,上下,我们将尝试最小化“残差”列上的值,使它们共同加起来尽可能低的数字,这样做希望它们会使这条橙色线适合这条虚线蓝线。

        我们希望通过更改上述 6 个数字来最小化“残差”列的总和,使其尽可能小。在这里,我们可以接受负数,没有问题,只需设置默认算法,然后调用fmin。

def myval(c):
    df = dd.copy()
    df['NSS'] =(c[0])+(c[1]*((1-np.exp(-df['Maturity']/c[4]))/(df['Maturity']/c[4])))+(c[2]*((((1-np.exp(-df['Maturity']/c[4]))/(df['Maturity']/c[4])))-(np.exp(-df['Maturity']/c[4]))))+(c[3]*((((1-np.exp(-df['Maturity']/c[5]))/(df['Maturity']/c[5])))-(np.exp(-df['Maturity']/c[5]))))
    df['Residual'] =  (df['Yield'] - df['NSS'])**2
    val = np.sum(df['Residual'])
    print("[β0, β1, β2, β3, λ0, λ1]=",c,", SUM:", val)
    return(val)
    
c = fmin(myval, [0.01, 0.01, 0.01, 0.01, 1.00, 1.00])
图 9

图 10

 

        所发生的情况是,解算器根据我的原始输入上下抖动了上述 6 个数字,使橙色曲线符合我们之前看到的那些蓝色点。这不是一个奇妙的魔法吗?

        现在,让我们得到 6 位数字的结果

β0 = c[0]
β1 = c[1]
β2 = c[2]
β3 = c[3]
λ0 = c[4]
λ1 = c[5]
print("[β0, β1, β2, β3, λ0, λ1]=", [c[0].round(2), c[1].round(2), c[2].round(2), c[3].round(2), c[4].round(2), c[5].round(2)])
图11

让我们可视化拟合的收益率曲线

df = df1.copy()
df['NSS'] =(β0)+(β1*((1-np.exp(-df['Maturity']/λ0))/(df['Maturity']/λ0)))+(β2*((((1-np.exp(-df['Maturity']/λ0))/(df['Maturity']/λ0)))-(np.exp(-df['Maturity']/λ0))))+(β3*((((1-np.exp(-df['Maturity']/λ1))/(df['Maturity']/λ1)))-(np.exp(-df['Maturity']/λ1))))
sf4 = df.copy()
sf5 = sf4.copy()
sf5['Y'] = round(sf4['Yield']*100,4)
sf5['N'] = round(sf4['NSS']*100,4)
sf4 = sf4.style.format({'Maturity': '{:,.2f}'.format,'Yield': '{:,.2%}', 'NS': '{:,.2%}'})
M0 = 0.00
M1 = 3.50
import matplotlib.pyplot as plt
import matplotlib.markers as mk
import matplotlib.ticker as mtick
fontsize=15
fig = plt.figure(figsize=(13,7))
plt.title("Nelson-Siegel-Svensson Model - Fitted Yield Curve",fontsize=fontsize)
ax = plt.axes()
ax.set_facecolor("black")
fig.patch.set_facecolor('white')
X = sf5["Maturity"]
Y = sf5["Y"]
x = sf5["Maturity"]
y = sf5["N"]
ax.plot(x, y, color="orange", label="NSS")
plt.scatter(x, y, marker="o", c="orange")
plt.scatter(X, Y, marker="o", c="blue")
plt.xlabel('Period',fontsize=fontsize)
plt.ylabel('Interest',fontsize=fontsize)
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
ax.xaxis.set_ticks(np.arange(0, 30, 5))
ax.yaxis.set_ticks(np.arange(0, 4, 0.5))
ax.legend(loc="lower right", title="Yield")
plt.grid()
plt.show()

图12

这个纳尔逊-西格尔-斯文森方程非常出色,它可能是这类方程中最好的一个,它比创建这些非线性线和这些曲线的多项式方程更好,大多数中央银行和软件绘制这些类型的线正在使用这种纳尔逊-西格尔-斯文森方法来创建这些线。

df.style.format({'Maturity': '{:,.0f}'.format,'Yield': '{:,.2%}','NSS': '{:,.2%}'})
图 13

 

        你可以看到这在创建完整的收益率曲线方面做得有多好,现在我可以看到20年期可能收益率为3.2%,我推断出30年期可能收益率为3.4%。所以,我认为这很好,这意味着我们现在可以获得10,000,000新谢克尔的利润。

        这就是您实现纳尔逊-西格尔-斯文森方法的方式,以便从有限的信息中创建收益率曲线。

七、后记

        希望这篇文章能让您很好地了解如何使用 Nelson-Siegel-Svensson 方法生成收益率曲线。如您所见,它非常简单,简单且快速。

        现在是时候走出去,开始对数据进行插值和推断了。试试这个算法,让我知道它是怎么回事。我很高兴收到有关上述任何内容的反馈或问题。罗伊·波兰尼策

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/939834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

oracle19c-静默安装(centos7)

目录 一.环境准备1.关闭防火墙2.关闭SELINUX3.配置本地yum源4.安装ORACLE先决条件的软件包5.修改LINUX的内核文件6.添加下列参数到/etc/security/limits.conf7.添加下列条目到/etc/pam.d/login8.环境变量中添加下列语句9.创建文件目录和相应的用户10.配置oracle用户的环境变量1…

CSPM是什么证书?有啥用?

重要的事情说三遍!!! CSPM开始报名!CSPM开始报名!CSPM开始报名! 今天给大家介绍一个新的项目管理国标证书(CSPM)——项目管理专业人员能力评价等级证书。下面我将从以下6个方面详细…

长胜证券:为什么股票分红后下跌?分红是好事吗?

股票分红是上市公司回报股东的一种方法,其也会影响股票的价格走势。那么为什么股票分红后跌落?分红是功德吗?港陆证券也为我们准备了相关内容,以供参考。 为什么股票分红后跌落? 1、市场机制调节,股票分红…

QNAP(威联通)NAS外远程访问指南,免费内网穿透工具的应用和配置指导——“cpolar内网穿透”

文章目录 前言1. 威联通安装cpolar内网穿透2. 内网穿透2.1 创建隧道2.2 测试公网远程访问 3. 配置固定二级子域名3.1 保留二级子域名3.2 配置二级子域名 4. 使用固定二级子域名远程访问 前言 购入威联通NAS后,很多用户对于如何在外在公网环境下的远程访问威联通NAS…

AdMob无效流量问题,如何预防及解决?

AdMob是Google推出的移动广告平台,开发者可以集成AdMob SDK广告到应用中获得收入,并使用 AdMob 的工具和功能来管理广告展示和优化收入。 很多开发者在使用AdMob平台时,可能会遇到无效流量的警告,尤其是对刚刚使用的用户来说&…

58从零开始学Java之String字符串常量池和intern方法

作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在之前的文章中,壹哥给大家介绍了String字符串的不可变性及其实现原理,其中给…

Springboot 配置使用 Kafka

Springboot 配置使用 Kafka 前言一、Linux 安装 Kafka二、构建项目三、引入依赖四、配置文件生产者yml 方式Config 方式 消费者yml 方式Config 方式 五、开始写代码生产者发送成功回调和异常处理 消费者接收异常处理 七、开始测试测试普通单条消息测试消费者异常处理测试延时消…

【JAVA基础——final关键字】

JAVA基础 final 关键字 文章目录 JAVA基础概述final修饰类final修饰方法final修饰变量非final类内 final修饰的方法和变量可以被继承类调用 概述 在 Java 中,final 是一个关键字,用于修饰类、方法和变量。 final 类: 不可被继承。final 常…

Linux用户与组管理(02)(七)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、批量创建 二、修改属性 三、密码设置 四、删除 总结 前言 今天学习的是上次剩余的用户组的内容,也是相对于刚学习Linux系统比较重要的部分&#x…

人民日报--全站图文数据库信息采集

支持2020-2023所有图文数据采集 #!/usr/bin/python3 # -*- coding:utf-8 -*- import requests import re from lxml import etree from sdk.utils.util_decorate import retryretry(retry3,sleep5) def get_html(url):response requests.get(url)response.encoding "u…

Leetcode刷题笔记--Hot31-40

1--颜色分类&#xff08;75&#xff09; 主要思路&#xff1a; 快排 #include <iostream> #include <vector>class Solution { public:void sortColors(std::vector<int>& nums) {quicksort(nums, 0, nums.size()-1);}void quicksort(std::vector<int…

Java虚拟机

文章目录 JVM运行时数据区域HotSpot虚拟机对象探秘实战&#xff1a;OutOfMemoryError异常 JVM 运行时数据区域 HotSpot虚拟机对象探秘 实战&#xff1a;OutOfMemoryError异常

01-6W2H方法

前言&#xff1a;6W2H法是我们制定策略时的黄金策略&#xff0c;并有不同的衍生版本&#xff0c;比如5W1H、3W1H等等&#xff0c;都是结合实际情况进行的剪裁运用。通过6W2H思想方法来进行研发管理以及问题分析&#xff0c;具备清晰的思路。 脑图&#xff1a;//参考

【Flutter】Flutter 使用 flex_color_scheme 创建美观的 Material Design 主题

【Flutter】Flutter 使用 flex_color_scheme 创建美观的 Material Design 主题 文章目录 一、前言二、FlexColorScheme 简介三、开始使用 FlexColorScheme四、实际业务中的应用五、FlexColorScheme 的高级功能六、完整实际业务代码示例七、总结 一、前言 今天&#xff0c;我想…

【算法刷题之字符串篇】

目录 1.leetcode-344. 反转字符串&#xff08;1&#xff09;方法&#xff1a;双指针 2.leetcode-541. 反转字符串 II&#xff08;1&#xff09;方法一&#xff1a;模拟&#xff08;2&#xff09;方法二&#xff1a;双指针 3.leetcode-剑指 Offer 05. 替换空格&#xff08;1&…

【大数据知识】大数据平台和数据中台的定义、区别以及联系

数据行业有太多数据名词&#xff0c;例如大数据、大数据平台、数据中台、数据仓库等等。但大家很容易混淆&#xff0c;也很容易产生疑问&#xff0c;今天我们就来简单聊聊大数据平台和数据中台的定义、区别以及联系。 大数据平台和数据中台的定义 大数据平台&#xff1a;一个…

AUTOSAR系列专题--诊断模块(下)

往期小怿向各位小伙伴介绍了&#xff0c;文章内容过多分为了两期&#xff0c;本期为大家介绍《AUTOSAR模块之诊断篇&#xff08;下&#xff09;》。 目录 1.概述 2.DCM 3.DEM 4.FIM 5.结语 点击查看前文&#xff1a;AUTOSAR系列专题--诊断模块&#xff08;上&#xff09;…

设备维护管理软件哪家好?设备巡检系统对企业经营管理有什么好处?

随着时代的不断进步&#xff0c;科学技术的飞速发展以及自动化水平的持续提高&#xff0c;设备维护保养工作在日常工作生产中扮演着至关重要的角色。然而&#xff0c;在实际生产中&#xff0c;由于对设备性能和保养规程的不熟悉&#xff0c;常常出现误操作、保养不到位或无法及…

如何修改字符串内容?

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; String 1. 修改字符串2. StringBuilder和…

bpmnjs Properties-panel拓展(属性设置篇)

最近有思考工作流相关的事情&#xff0c;绘制bpmn图的工具认可度比较高的就是bpmn.js了&#xff0c;是一个基于node.js的流程图绘制框架。初始的框架只实现了基本的可视化&#xff0c;想在xml进行客制化操作的话需要拓展&#xff0c;简单记录下几个需求的实现过程。 修改基础 …