イールドカーブを取り扱う抽象クラスql.YieldTermStructure
の機能を、具象クラスql.ZeroCurve
で確認する。
カーブ構築
ql.ZeroCurve
オブジェクトを生成する。ql.ZeroCurve
は、与えられたノードからノード間のゼロレートを線形補間したイールドカーブ。
カーブ構築
import math
import QuantLib as ql
# spot_datesの最初の日付はカーブの基準日、つまりDF=0となる日とすること。
spot_dates = [ql.Date(18, 1, 2020), ql.Date(18, 7, 2020), ql.Date(18, 1, 2021), ql.Date(18, 7, 2021), ql.Date(18, 1, 2022), ql.Date(18, 7, 2022), ql.Date(18, 1, 2023)]
spot_rates = [0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07]
zero_curve = ql.ZeroCurve(spot_dates, spot_rates, ql.Actual365Fixed())
zero_curve.enableExtrapolation() #node外を補外
ノードを表示
zero_curve.nodes()
ゼロ レート
ゼロ レートの計算を確認する。
ゼロ レート
date_m = ql.Date(18, 4, 2021)
rate_m = zero_curve.zeroRate(date_m, zero_curve.dayCounter(), ql.Continuous).rate()
print(rate_m) # 0.034972375690607786
先のゼロ レートが線形補間で計算されていることを確認
date_l = ql.Date(18, 1, 2021)
rate_l = zero_curve.zeroRate(date_l, zero_curve.dayCounter(), ql.Continuous).rate()
t_l = zero_curve.dayCounter().yearFraction(zero_curve.referenceDate(), date_l)
date_r = ql.Date(18, 7, 2021)
rate_r = zero_curve.zeroRate(date_r, zero_curve.dayCounter(), ql.Continuous).rate()
t_r = zero_curve.dayCounter().yearFraction(zero_curve.referenceDate(), date_r)
t_m = zero_curve.dayCounter().yearFraction(zero_curve.referenceDate(), date_m)
rate_m2 = rate_l + (rate_r - rate_l) / (t_r - t_l) * (t_m - t_l)
print(rate_m2) # 0.034972375690607675
ディスカウント ファクター
ディスカウント ファクターの計算を確認する。
ディスカウント ファクター
date_m = ql.Date(18, 4, 2021)
df = zero_curve.discount(date_m)
print(df) # 0.9572492080611358
ディスカウント ファクターの計算方法を確認
rate_m = zero_curve.zeroRate(date_m, zero_curve.dayCounter(), ql.Continuous).rate()
t_m = zero_curve.dayCounter().yearFraction(zero_curve.referenceDate(), date_m)
df2 = math.exp(-rate_m * t_m)
print(df2) # 0.9572492080611358
フォワード レート
時点$t_1$スタート、時点$t_2$エンドのフォワードレート$fwd(t_1, t_2)$は、ディスカウント ファクターの関係式
$$
e^{-r_2 t_2} = e^{-fwd(t_1, t_2)\times(t_2 - t_1)} \times e^{-r_1 t_1}
$$
より、
$$
fwd(t_1, t_2) = \frac{r_2 t_2 - r_1 t_1}{t_2-t_1}
$$
となる。
forwardRateメソッド
d_1 = ql.Date(18, 1, 2021)
d_2 = ql.Date(18, 7, 2021)
print(zero_curve.forwardRate(d_1, d_2, zero_curve.dayCounter(), ql.Continuous).rate())
# 0.06022099447513828
forwardRateの計算方法を確認
t_1 = zero_curve.dayCounter().yearFraction(zero_curve.referenceDate(), d_1)
r_1 = zero_curve.zeroRate(d_1, zero_curve.dayCounter(), ql.Continuous).rate()
t_2 = zero_curve.dayCounter().yearFraction(zero_curve.referenceDate(), d_2)
r_2 = zero_curve.zeroRate(d_2, zero_curve.dayCounter(), ql.Continuous).rate()
fwd = (r_2 * t_2 - r_1 * t_1) / (t_2 - t_1)
print(fwd)
# 0.060220994475138234
フォワード カーブ
フォワード レートで、時点$t_1$を固定して、時点$t_2$を動かせば、時点$t_1$のイールド カーブとみなせる。これがフォワード カーブ。
ql.ImpliedTermStructure
fwd_curve = ql.ImpliedTermStructure(ql.YieldTermStructureHandle(zero_curve), d_1)
このフォワード カーブからゼロ レートを計算。
ql.ImpliedTermStructureから ゼロレートを計算
print(fwd_curve.zeroRate(d_2, fwd_curve.dayCounter(), ql.Continuous).rate())
# 0.06022099447513828
これは先ほどのフォワード レートと一致する。