数理最適化セミナーのご案内

2.19 イールドカーブ推定問題

 イールドカーブとは,償還期間の異なる利回りをもつ債券等について,利回りと償還期間の相関を描いた曲線(縦軸:利回り,横軸:償還期間)のことをいいます.ここでは,この利回りがスポットレート(現時点から将来のある時点まで保有される資産にかかる金利のこと)である場合を対象とします.なお,イールドカーブの形状には順イールド(右上がりの曲線)と逆イールド(右下がりの曲線)があり,前者は短期金利よりも長期金利のほうが高くなることを意味し,後者は逆に短期金利よりも長期金利のほうが低くなることを意味しています.

 以下の例題では,現時点での観測価格からスポットレートを推定する問題を考え,イールドカーブの推定を行います.

例題

 期間(償還期間)が1~10期まであり,各々に対するスポットレート$r_{t}$を用いて,償還期間$t$における額面価格100,クーポンレート1%の利付債の理論価格$S(t;r_{1}, \ldots, r_{t})$

\[S(t;r_{1}, \ldots, r_{t}) \equiv \displaystyle \frac{100}{(1 + 0.01 \cdot r_{t})^{t}} + \sum_{k=1}^{t}{\frac{1}{(1 + 0.01 \cdot r_{k})^{k}}} \]

のように定義されているとする.観測結果$(t, S(t))$の組

\[(t_{i}, S_{i}) \quad i \in \{1, \ldots, 60\}\]

が与えられているとき,

\[\sum_{i} \{ S(t_{i}) - S_{i} \}^{2}\]

を最小化するようなスポットレートを推定せよ.

 この問題を定式化すると以下のようになります.

 なお,求めるスポットレートの単位は%(パーセント)とし,非負であるものとします.

集合
$Term$ 期間(償還期間)集合
$Point$ 観測点の集合
 
定数
$tvalue_{i}, i \in Point$ 観測点が何期目か
$Svalue_{i}, i \in Point$ 観測値
 
変数
$r_{t}, t \in Term$ $t$期に対するスポットレート
 
目的関数(最小化)
$\displaystyle \sum_i \{ S(tvalue_i) - Svalue_i \}^2, S(t; r_1, \ldots, r_t) \equiv \frac{100}{(1 + 0.01 \cdot r_{t})^{t}} + \sum_{k=1}^{t}{\frac{1}{(1 + 0.01 \cdot r_{k})^{k}}} $ 理論値と観測値の誤差の二乗和
 
制約条件
$0 \le r_t, \forall t \in Term$ スポットレートの非負条件

 この問題は目的関数が非線形ですので,非線形計画問題になります.

 定式化した結果をC++SIMPLEで記述すると以下のようになります.

// 集合と添字
Set Term(name = "期間"); // 期間集合
Term = "1 .. 10";
Element t(set = Term);
Set Point;
Element i(set = Point);

// パラメータ
Parameter tvalue(name = "tvalue", index = i); // 何期目か
Parameter Svalue(name = "Svalue", index = i); // 観測値(S)

// 変数
Variable r(name = "スポットレート", index = t);

// t 期の価値から現在価値への変換レート
Expression d(index = t);
d[t] = 1 / pow(1 + 0.01 * r[t], t);

// tvalue[i] 期における S の理論値
Expression S(index = i);
S[i] = 100 * d[tvalue[i]] + sum(d[t], (t, t <= tvalue[i]));

// 理論値と観測値の誤差
Expression diff(index = i);
diff[i] = S[i] - Svalue[i];

// 目的関数
Objective err(name = "理論値と観測値の誤差の二乗和", type = minimize);
err = sum(diff[i] * diff[i], i);

// 制約条件
0 <= r[t]; // スポットレートの非負条件

// 求解
solve();

// 結果出力
err.val.print();
r.val.print();

 データファイル(tSvalue.csv)は以下のようになります.

i, tvalue, Svalue
1, 1, 100.39
2, 1, 102.15
3, 1, 99.24
4, 1, 101.32
5, 1, 99.72
6, 1, 101.51
7, 2, 100.62
8, 2, 99.34
9, 2, 98.27
10, 2, 98.31
11, 2, 100.97
12, 2, 101.73
13, 3, 99.78
14, 3, 100.47
15, 3, 98.19
16, 3, 99.55
17, 3, 99.79
18, 3, 98.4
19, 4, 96.6
20, 4, 96.93
21, 4, 96.8
22, 4, 94.91
23, 4, 96.28
24, 4, 95.33
25, 5, 95.13
26, 5, 93.5
27, 5, 93.42
28, 5, 91.56
29, 5, 92.67
30, 5, 96.28
31, 6, 89.66
32, 6, 89.46
33, 6, 91.21
34, 6, 91.42
35, 6, 93.32
36, 6, 89.76
37, 7, 90.18
38, 7, 88.58
39, 7, 87.41
40, 7, 90.33
41, 7, 87.5
42, 7, 87.66
43, 8, 86.06
44, 8, 85.55
45, 8, 84.74
46, 8, 88.78
47, 8, 86.79
48, 8, 88.76
49, 9, 84.95
50, 9, 84.31
51, 9, 87.24
52, 9, 84.73
53, 9, 83.76
54, 9, 84.02
55, 10, 81.75
56, 10, 84.46
57, 10, 82.51
58, 10, 85.42
59, 10, 81.45
60, 10, 85.36

 このモデルを実行すると,以下のような解が得られます.

理論値と観測値の誤差の二乗和 = 97.061
スポットレート[1] = 0.276339
スポットレート[2] = 1.06832
スポットレート[3] = 1.22162
スポットレート[4] = 2.02931
スポットレート[5] = 2.35651
スポットレート[6] = 2.70549
スポットレート[7] = 2.84285
スポットレート[8] = 2.89991
スポットレート[9] = 2.96985
スポットレート[10] = 2.95256

 

 

上に戻る