Rの金利期間構造パッケージ fBonds
ほとんど使ったことがなかったRのファイナンス系のパッケージ(CRAN Task View: Empirical Finance)を探訪する
前回で利用したYieldCurveパッケージ以外にも金利の期間構造に関するパッケージが複数あることを知ったので、それを調査したメモ
今回、調査したのは、fBondsとYieldCurveパッケージ
まずは、パッケージの読み込み
library(fBonds) library(YieldCurve)
fBondsパッケージは、xtsと同様にRのcoreパッケージということのようだが、Nelson-SiegelモデルとSvenssonモデルへ当てはめる関数の二つのみで、coreパッケージというにしてはあっさりしている
Nelson-Siegelモデルをイールドカーブに当てはめる関数で比較
データは、財務省の国債金利情報から持ってきた
maturity <- c(1:10, 15, 20, 25, 30, 40) yield <- c(-0.013, -0.020, -0.014, -0.008, 0.016, 0.017, 0.073, 0.148, 0.216, 0.284, 0.589, 0.938, 1.063, 1.150, 1.260)
マイナス金利というモデルが作られた時には想定していない事態かもしれないが、このまま推定
par1 <- fBonds::NelsonSiegel(yield, maturity, doplot = TRUE) par2 <- YieldCurve::Nelson.Siegel(yield, maturity)
同じNelson-Siegelモデルへの当てはめでも、最適化に使う関数が違って、fBondsの方はnlminbを使い、YieldCurveの方はoptimizeでパラメータlambdaのみ一旦推定して、lmで線形モデルに当てはめ、残りのパラメータを推定している
このデータから推定したパラメータは、以下の通り
> par1$par beta0 beta1 beta2 tau1 1.805390 -1.659496 -2.991222 4.242192 > par2 beta_0 beta_1 beta_2 lambda [1,] 1.795689 -1.642322 -3.009073 0.239118
fBondsはフォワードレート、YieldCurveはスポットレートの形でモデルのパラメータ定義がされているので、ここでのパラメータの関係は、lambda = 1 / tau1となっている
比較のために、fBondsで推定した結果を変換して、格納しておく
> par1$par.t <- c(par1$par[-4], 1 / par1$par[4]) > names(par1$par.t) <- c("beta_0", "beta_1", "beta_2", "lambda") > par1$par.t beta_0 beta_1 beta_2 lambda 1.8053901 -1.6594964 -2.9912217 0.2357272
次は、この推定したパラメータからモデルイールドの値を計算
fBondsパッケージには、推定したパラメータから、Nelson-Siegelモデルのイールドを計算する関数は定義されていない
YieldCurveパッケージには、NSratesという関数が入っているが、時系列オブジェクトを要求してくるので、今回のような一日分のデータから、モデルイールドを求めたい場合には、一度xts等に変換が必要で面倒
ということで、Nelson-Siegelモデルのイールドを計算する関数を書いて比較
NSModelRates <- function(par, tau) { par[1] + par[2] * (1 - exp(-par[4] * tau)) / (par[4] * tau) + par[3] * ((1 - exp(-par[4] * tau)) / (par[4] * tau) - exp(-par[4] * tau)) }
それぞれのパッケージの関数で推定したパラメータを入れる
> NSModelRates(par1$par.t, maturity) [1] 0.025227873 -0.035976844 -0.053874588 -0.040757689 -0.005934127 [6] 0.043589340 0.102575961 0.167146462 0.234459168 0.302462379 [11] 0.615565858 0.854583921 1.026647584 1.150845555 1.312439110 > NSModelRates(par2, maturity) [1] 0.027722244 -0.036202635 -0.055344088 -0.042543069 -0.007486335 [6] 0.042562722 0.102197788 0.167431439 0.235356597 0.303885415 [11] 0.618089435 0.856425926 1.027194182 1.150083261 1.309627120
fBonds::NelsonSiegelを実行した際に出てくるプロットにYieldCurveで推定されたイールドを重ねる
lines(maturity, NSModelRates(par2, maturity), lty = 2, col = 2)
青がfBonds、赤がYieldCurveで推定したもの
両方のパッケージを使って推定したイールドが重なることが確認できる
イールドカーブの変動は、水準、傾き、曲率でほとんどが説明できると言われており、Nelson-Siegelモデルでは、それぞれの係数がそれらに対応している。これらはファクターローディングと呼ばれる
簡単な関数なので、自分で書いても良いが面倒な場合は、YieldCurveの説明には書かれていないが名前空間には定義されているので、それを使うことができる
> YieldCurve::<tab> YieldCurve::.beta1Forward YieldCurve::.beta1Spot YieldCurve::.beta2Forward YieldCurve::.beta2Spot YieldCurve::.factorBeta1 YieldCurve::.factorBeta2 YieldCurve::.NS.estimator YieldCurve::.NSS.estimator YieldCurve::Nelson.Siegel YieldCurve::NSrates YieldCurve::Srates YieldCurve::Svensson
YieldCurve::.factorBeta1とYieldCurve::.factorBeta2を使えば、各満期におけるファクターローディングが得られる
beta0.fl <- rep(1, length(maturity)) beta1.fl <- YieldCurve::.factorBeta1(par2[4], maturity) beta2.fl <- YieldCurve::.factorBeta2(par2[4], maturity) matplot(maturity, cbind(beta0.fl, beta1.fl, beta2.fl), type = "l", lwd = 2, col = c(1, 2, 4)) legend(30, 0.8, c(expression(beta[0]), expression(beta[1]), expression(beta[2])), lty = 1:3, lwd = 2, col = c(1, 2, 4)) grid()
以上をまとめると、fBondsパッケージは使う必要はあまり感じない…
YieldCurveパッケージは、もう少しいろいろと充実していただけると…