主页 > 下载imtoken被盗 > R语言使用随机技术差分进化算法优化的Nelson-Siegel

R语言使用随机技术差分进化算法优化的Nelson-Siegel

下载imtoken被盗 2023-03-11 05:21:03

1 简介

最近,一位客户要求我们撰写一份关于 Nelson-Siegel-Svensson 的研究报告,包括一些图形和统计输出。

在本教程中,我们将了解如何将 Nelson-Siegel-Svensson (NSS) 模型拟合到数据。 由于我们将使用随机技术进行优化,因此我们应该重新运行几次。 变量 nRuns 设置样本重新启动的次数。

> set.seed(112233)

2 将 NS 模型拟合到给定的零利率 NS 模型

我们使用给定参数 betaTRUE 创建“真实”收益率曲线 yM。 付款时间(以年为单位)在向量 tm 中。

> tm <- c(c(1, 3, 6, 9)/12, 1:10)
> betaTRUE <- c(6, 3, 8, 1)
> yM <- NS(betaTRUE, tm)
> par(ps = 11, bty = "n", las = 1, tck = 0.01, mgp = c(3, 0.2, 0), mar = c(4, 4, 1, 1))
> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")

比特币算法软件_比特币是什么算法_比特币算法优化

目标是通过这些点拟合平滑曲线。 我们从目标函数 OF 开始。 它有两个参数:参数和列表数据(包含所有其他变量)。 返回观察到的向量(“市场”)返回 yM 和参数 param 的模型返回之间的最大绝对差异。

我们针对导致“NA”值的参数值添加了一个粗略但有效的约束:目标函数返回较大的正值。 我们最小化它,所以产生 NA 值的参数被标记为坏的。 在第一个例子中,我们设置数据如下:

> data <- list(yM = yM, tm = tm, model = NS, ww = 0.1, min = c( 0,-15,-30, 0), max = c(15, 30, 30,10))

我们添加了一个模型(在本例中为 NS),它描述了从参数到收益率曲线的映射,以及我们稍后用作约束的向量 min 和 max。 ww 是惩罚权重,如下所述。

OF会取候选解的参数,通过data$model将这个解转化为return,并将这些return与yM进行比较,也就是计算最大的绝对差值。


> OF(param2, data) ## 得到正值
[1] 0.97686

我们还可以根据收益率曲线比较解决方案。

> par(ps = 11, bty = "n", las = 1, tck = 0.01, mgp = c(3, 0.2, 0), mar = c(4, 4, 1, 1))
> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")
> lines(tm, NS(param1, tm), col = "blue")
> lines(tm, NS(param2, tm), col = "red")
> legend(x = "topright", legend = c("true yields", "param1", "param2"), col = c("black", "blue", "red"), pch = c(1, NA, NA), lty = c(0, 1, 1))

比特币是什么算法_比特币算法软件_比特币算法优化

我们通常希望捕获参数以满足某些约束条件。 我们通过惩罚函数将它们包括在内。

我们已经有了数据,所以让我们看看这个函数对约束违反的解决方案做了什么。 假设我们有三个解决方案的整体 mP。

> param1 <- c( 6, 3, 8, -1)
> param2 <- c( 6, 3, 8, 1)
> param3 <- c(-1, 3, 8, 1)
> mP <- cbind(param1,param2,param3)
> rownames(mP) <- c("b1","b2","b3","lambda")
> mP
param1 param2 param3
b1 6 6 -1
b2 3 3 3
b3 8 8 8
lambda -1 1 1

第一个和第三个解决方案违反了约束。 在第一个解决方案中,λ 为负。 在第三种解中,β1 为负。

> penalty(mP,data)
param1 param2 param3
0.2 0.0 0.2

参数 ww 控制我们惩罚的程度。

> data$ww <- 0.5
> penalty(mP,data)
param1 param2 param3
1 0 1

对于有效的解决方案,惩罚应该为零。


> penalty(mP, data)
param1 param2 param3
0 0 0

请注意,处罚立即生效; 无需遍历解决方案。

这样我们就可以测试了。 我们首先定义 DE 的参数。 请特别注意,我们传递了一个惩罚函数并将 loopPen 设置为 FALSE。

然后用目标函数OF调用DEopt,列出数据和列表算法。

> sol <- DEopt(OF = OF, algo = algo, data = data)

差异进化。

最优解的目标函数值为0;

最终群体中 OF 的标准差为 3.0455e-16。

为了检查目标函数是否正常工作,我们将最大误差与返回的目标函数值进行比较——它们应该相同。

> max( abs(data$model(sol$xbest, tm) - data$model(betaTRUE, tm)) )
[1] 0
> sol$OFvalue
[1] 0 

作为基准,我们运行 stats 包中的函数 nlminb。

如果发现它优于 DE比特币算法优化,我们将强烈表明我们的 DE 实现存在问题。

我们使用随机起始值 s0。

> s0 <- algo$min + (algo$max - algo$min) * runif(length(algo$min))
> sol2 <- nlminb(s0, OF, data = data,
lower = data$min,
upper = data$max,
control = list(eval.max = 50000L,
iter.max = 50000L))

同样,我们将返回的目标函数值与最大误差进行比较。

> max( abs(data$model(sol2$par, tm) - data$model(betaTRUE,tm)) )
[1] 1.5787e-07
> sol2$objective
[1] 1.5787e-07

为了比较我们的两个解决方案(DE 和 nlminb),我们可以将它们与真实收益率曲线一起绘制。 但必须强调的是,两种算法的结果都是随机的:对于DE,因为它故意使用了随机性; 在 nlminb 的情况下,因为我们随机设置起始值。 为了获得更有意义的结果,我们应该多次运行这两种算法。 为了减少插图的构建时间,我们只运行一次这两种方法。


> plot(tm, yM, xlab = "maturities in years",
ylab = "yields in %")
> algo$printDetail <- FALSE
> for (i in seq_len(nRuns)) {
sol <- DEopt(OF = OF, algo = algo, data = data)
lines(tm, data$model(sol$xbest,tm), col = "blue")
s0 <- algo$min + (algo$max-algo$min) * runif(length(algo$min))
sol2 <- nlminb(s0, OF, data = data,
lower = data$min,
upper = data$max,
control = list(eval.max = 50000L,
iter.max = 50000L))
lines(tm,data$model(sol2$par,tm), col = "darkgreen", lty = 2)
}
> legend(x = "topright", legend = c("true yields", "DE", "nlminb"),
col = c("black","blue","darkgreen"),
pch = c(1, NA, NA), lty = c(0, 1, 2))

比特币算法软件_比特币算法优化_比特币是什么算法

毫无疑问,DE似乎通常只有一条曲线:实际上有nRuns条线,只是它们相互叠加。

其他约束

NS(和 NSS)模型的参数约束是为了确保生成的零利率是非负的。 但在实践中,它们并不能保证正利率。


> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")
> abline(h = 0)

比特币算法软件_比特币是什么算法_比特币算法优化

这确实是一个人为的例子,但尽管如此,我们可能希望包括对此类参数向量的约束:我们可以只包括一个所有速率都大于零的约束。

同样比特币算法优化,这可以通过惩罚函数来完成。

查看:

> penalty2(c(3, -2, -8, 1.5),data)
[1] 0.86343

这个惩罚函数只适用于单个解,所以直接写到目标函数中其实最简单。

所以,就像一个数值测试:假设上述参数为真,利率为负。

> algo$pen <- NULL; data$yM <- yM; data$tm <- tm
> par(ps = 11, bty = "n", las = 1, tck = 0.01,
mgp = c(3, 0.2, 0), mar = c(4, 4, 1, 1))
> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")
> abline(h = 0)
> sol <- DEopt(OF = OFa, algo = algo, data = data)
> lines(tm,data$model(sol$xbest,tm), col = "blue")
> legend(x = "topleft", legend = c("true yields", "DE (constrained)"),
col = c("black", "blue"),
pch = c(1, NA, NA), lty = c(0, 1, 2))

比特币算法优化_比特币算法软件_比特币是什么算法

3 将 NSS 模型拟合到给定的零利率

如果您想改为使用 NSS 模型,则只需进行少量更改。 我们只需要将不同的模型传递给目标函数即可。 下面是一个例子。 同样,我们固定真实参数并尝试恢复它们。

榜单数据和算法与之前几乎相同; 目标函数保持完全相同。

算法仍然需要运行。 (同样,我们检查返回的目标函数值。)

> sol <- DEopt(OF = OF, algo = algo, data = data)
> max( abs(data$model(sol$xbest, tm) - data$model(betaTRUE, tm)) )
[1] 7.9936e-15
> sol$OFvalue
[1] 7.9936e-15

我们将结果与 nlminb 进行比较。

最后,我们比较了从几次运行中获得的收益率曲线。

> par(ps = 11, bty = "n", las = 1, tck = 0.01,
mgp = c(3, 0.2, 0), mar = c(4, 4, 1, 1))
> plot(tm, yM, xlab = "maturities in years", ylab = "yields in %")
> for (i in seq_len(nRuns)) {
sol <- DEopt(OF = OF, algo = algo, data = data)
lines(tm, data$model(sol$xbest,tm), col = "blue")
s0 <- algo$min + (algo$max - algo$min) * runif(length(algo$min))
sol2 <- nlminb(s0, OF, data = data,
lower = data$min,
upper = data$max,
control = list(eval.max = 50000L,
iter.max = 50000L))
lines(tm, data$model(sol2$par,tm), col = "darkgreen", lty = 2)
}
> legend(x = "topright", legend = c("true yields", "DE", "nlminb"),
col = c("black","blue","darkgreen"),
pch = c(1,NA,NA), lty = c(0,1,2), bg = "white")

比特币是什么算法_比特币算法优化_比特币算法软件

参考

关于数值优化中“良好起始值”的注释,2010。= working_papers

比特币是什么算法_比特币算法软件_比特币算法优化