今週も特にありません

進捗どうですか?

Rの金利の期間構造まわりのパッケージ

ほとんど使ったことがなかったRのファイナンス系のパッケージ(CRAN Task View: Empirical Finance)を探訪する

前回で利用したYieldCurveパッケージ以外にも金利の期間構造に関するパッケージが複数あることを知ったので、それを調査したメモ

今回、調査したのは、fBondsYieldCurveパッケージ

まずは、パッケージの読み込み

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で推定したもの
両方のパッケージを使って推定したイールドが重なることが確認できる

f:id:masaqol:20150111021312p:plain

イールドカーブの変動は、水準、傾き、曲率でほとんどが説明できると言われており、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()

f:id:masaqol:20150111172307p:plain

以上をまとめると、fBondsパッケージは使う必要はあまり感じない…
YieldCurveパッケージは、もう少しいろいろと充実していただけると…