0. JGBの"めちゃくちゃ"な市場慣行
- 10月末に「Pythonで学ぶ債券·金利デリバティブ(共立出版)」というQuantLib-Pythonの入門書
(以下、"テキスト")を出版しました。このテキストにはJGB (日本国債の略称)のオブジェクト作成例を載せていません。(米国国債やユーロ債のオブジェクト作成法はテキスト4章と5章で詳細に説明)
- その理由はJGBの計算が以下の3点より、入門書向きではないため。
- 1 : 利回り計算は閏年を無視し、経過利息は閏年を考慮
- もし、このルールを知っていたら、あなたは"JGBオタク"ですね
- 2 : 単利で建値し、売買代金を計算
- ここで閏年のある経過利息が必要
- QuantLibは単利を非サポート
- 3 : 内部収益率(IRR計算)を無視した日本式複利を使用
テキスト110ページ、脚注1参照
- 1 : 利回り計算は閏年を無視し、経過利息は閏年を考慮
-
ただ、読者から「日本が金利のある世界に戻ったので、JGBオブジェクトの例は必要」と指摘があり、この場を借りて、JGBオブジェクトの作成例を示します。
-
以下で紹介するコード
(ファイル名 JL101-1.ipynb)はテキストのサポートページ https://github.com/retrieveram/Python-Bond-Derivatives より、ダウンロード可能。- 計算結果は情報端末と1e-6~-7程度の精度でほぼ一致
- 以下ではQuantLib-PythonをQuantLibと参照
1. 利回りと経過利息の相違への対処法
(1.1) dcA365nの作成 (テキスト25ページ、図1-19と比較)
- 閏年を無視する日数計算オブジェクトdcA365n = ql.Actual365Fixed (ql.Actual365Fixed.NoLeap)をmyABBRモジュールに追加し、下図11,12行目のようにJGBオブジェクトを2つ作成
(myABBRモジュールはテキスト24ページ参照) - dcA365とdcA365nの違い:後者は分子でも閏年を無視する
(dcA365の説明はテキスト8ページ、図1-8 参照)
(1.2) 2つのJGBオブジェクトの作成 (テキスト113ページ、図4-2と比較)
- 11行目のjgbOBJオブジェクトは利回り計算用で、dcA365nを使用
- 15行目で複利利回りを計算する場合等で使用
- 12行目のjgbOBaは経過利息用で、dcA365を使用
(aはaccruedの略)- 下図 7行目 accruedAmountメソッドはjgbOBaオブジェクトを使用
- 経過利息関連を計算する場合のみ、この補助用のjgbOBaを使用
- このようにjgbOBJとjgbOBaを利回り/ 経過利息のそれぞれの局面で使い分けて対処する。
(1.3) 経過日数、経過利息の計算例 (テキスト115ページ、図4-3と比較)
- 4行目のdayCountメソッドはdcA365を使用
(dcA365nではない)
(1.4) デュレーション等の計算例 (テキスト117ページ、図4-4と比較)
- 3行目のInterestRateクラス
(テキスト27ページ参照)は利回り計算であり、dcA365nを使用 - リスク指標は利回りから算出するので、jgbOBJを使用
(1.5) キャッシュフロー用の3番目のオブジェクト (テキスト121ページ、図4-6と比較)
- 通常の固定利付債(s.a.)の利払額はクーポンの半分となるが、dcA365やdcA365nではそのキャッシュフローが作れない
- Actual365Fixedクラスには債券用がなく、便宜的に米国国債のdcAAb
(テキスト144ページ参照)を使い、3つ目のJGBオブジェクトjgbOBcを用意し、キャッシュフロー表に使用 - 下図 amount列が2.4%の半分を表示
- キャッシュフロー表は単なる確認画面であり、dcAAbを使っても問題はない。
(コード4行目でdirty price(hc)と表示した利含み価格を手計算したが、A3節の利含み価格とは若干のズレ) - 上のセルのコードに関しては
テキスト131ページ、図4-15を参照- 3行目のpandasスタイル書式用変数fmtFUTは
テキスト149ページと388ページを参照
- 3行目のpandasスタイル書式用変数fmtFUTは
2. 単利への対処法
-
QuantLibのFixedRateBondクラスを継承し、単利計算のメソッドの追加で対処可能。
-
単利の正確な計算式は一般的には公表がなく、次式によって、日本証券業協会(JSDA)は計算していると思われる。
$$
\small
\text{クリーン価格} =
\frac{365 + クーポン \times 残存日数 }
{365 + 単利 \times 残存日数}\times 100 \
$$ -
上図1行~12行はFixedRateBondを継承し、単利計算メソッド(SimplePriceとSimpleYield)を追加したJGBクラスのコード。
-
テキストではQuantLibクラスの継承例を載せていないが、クラス作成法は
テキスト249ページ、7.5.3節を参照。- 5行目のsuper().__init__(...)部分が親クラスのコンストラクタを呼び出すコード
- 親クラス(FixedRateBond)のコンストラクタの仕様は
テキスト図1.7で例示したように、QuantLib.pyファイルを参照しよう。 - 14行でJL101オブジェクトを作成し、15,16行で単利及び単価を算出 ("JL101"はBloombergのティッカーを借用)
-
(1.2)節で作った2つのオブジェクト(jgbOBJ、jgbOBa)をこのJGBクラスから作れば、単利と欧米式複利の両方の計算に対応可能。(第2回記事のコードを参照)
3. 日本式複利は無視すべき?
- JSDAは単利と共に複利の値を発表しているが、欧米式複利の計算と若干異なる程度。
(第2回記事で数値例を紹介) - 日本の市場慣行では、複利から売買代金を計算しないので
(ゼロクーポン債を除く)、QuantLibが複利ベースで計算するリスク関連のメソッド(上の1.4節で説明した各数値)は十分実務に耐えるだろう。
$$
{\small
\text{クリーン価格} \times (1 + y/2)^{\text{残存年数} \times 2} = (\text{クーポン}/2) \times \frac{(1 + y/2)^{\text{残存年数} \times 2} - 1}{y/2}+ 100
}
$$
- 日本式複利は「百害あって一利なし」であり、無視してもよい。
- その理由を説明すると、上が日本式複利の計算式となるが、主に左辺のクリーン価格が問題。
- 本来、
テキスト112ページの複利式(4.6)のように複利計算はダーティー価格利含み価格 - 右辺も欧米の複利式とは若干異なる
(この辺りは第2回記事で説明) - つまり、日本式複利は正確ではない投資利回り(IRR)を計算する式
- 本来、
- ただ この記事を読んだ読者より「"一利"としては見慣れていること」と指摘があった
- 低金利下ではクリーン/ダーティーの違いは大きなズレを生まないため、我慢して使うことにした
- 第2回の記事で日本式複利を実装する
まとめ
- 日本国債を処理するには利回り計算用と経過利息用の2つのオブジェクトが必要。
- 単利を処理する場合、FixedRateBondクラスを継承し、単利メソッドを追加すれば済む。 (単利式は市場慣行の正確な式が必要)
- キャッシュフロー表が必要な場合、債券用DayCounter
dcAAbで作成された3つ目のJGBオブジェクトでキャッシュフローを作成。 - 日本式複利を我慢して使う
(当初記事の"無視"から継続使用へ修正) - 上記コードはテキストのサポートページ https://github.com/retrieveram/Python-Bond-Derivatives より、取得可能。
(ファイル名はJL101-1.ipynb)






