0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第8回:ツーカーブでの 3mTibor スワップのコードと解釈

0
Last updated at Posted at 2026-02-23

(修正:2026/4/2) showCurveDate関数 という関数を showCvDT(cvOBJ, ixOBJ=None)へ変更

$\quad$
今後しばらく、通貨スワップを含めたスワップ関連の記事を複数回 書く予定。

今回は「3ヶ月Tiborを変動金利とする金利スワップをツーカーブで評価する」という、いたって基本的な内容。拙著「Pythonで学ぶ債券·金利デリバティブ」(以下 テキスト)では 3.4節でこの内容を説明したが、テキスト図3.21 (p.107)はトイモデルで説明したため、この記事で現実のイールドカーブに対するコード例を示す。

ファイナンス実務で「ツーカーブ」は最も基本的な内容であるにも関わらず、多くのファイナンスのテキストではほとんど説明が無い。その理由は複雑な計算のためかと考えるが、QuantLibを使えば、驚くほど簡単に正しい計算が可能となる。

記事を読む注意点を2つ挙げておく。

  • これまでの記事で計算した数値やテキストの数値例は いずれも有料情報端末の計算結果とほぼ一致している (ズレている場合,その旨を記載)

  • 記事中のコードはテキストのサポートページ より、取得可能。(今回のコードはq08-Tibor3mSwap.ipynb)

詳細な説明の前に全体像を示しておく。

  • 8-1節でツーカーブを構築 (基本的にはこの構築が全て)
  • 8-2節は構築したツーカーブでスワップを作成・評価
    • ツーカーブのスワップオブジェクト作成はシングルカーブとほぼ同じ
  • 8-3節はフォワードカーブのディスカウントファクターの意味と利用上の注意点へのメモ

8-1. Tonaカーブ、3ヶ月Tiborカーブの構築

初めにTonaカーブと3ヶ月Tiborカーブをツーカーブとして作成する。つまり、Tonaカーブがディスカウントカーブで、3ヶ月Tiborカーブがフォワードカーブ。(この辺りの用語はテキスト 図3.17(p.103)参照)

8-1-1. ツーカーブのデータ

JSCC20250120editpng

$\qquad\qquad\qquad\qquad\quad$(図8-1:2026-01-20 JSCC Fixingデータ)

図8-1の上段は日本証券クリアリング機構 (以下 JSCC) が発表した2026年1月20日引けのFixingデータであり、下段はそれをQuantLib入力用にしたJupyter notebookのセルで、1行目のtnDATAがTonaカーブ用、10行目のtbDATAが3ヶ月Tiborカーブ用。(tnはTona, tbはTiborの略)

上下を見比べて、どのノードをQuantLib用データとしたかを確認しておく。

  • QuantLib用のデータは7年までのデータとした

  • FRAは9M(6x9)までを使用し、10M, 11Mは未使用

  • もし、これらノードデータへの理解が不足していると思うなら、以下を参照

    • tnDATAはテキスト図3.9 1番セル (p.91)を参照

    • tbDATAは第3回記事 図3-2のコード 3行目 参照

これらのデータ設定が終われば、図8-2のコード 3,4行目のようにmyUTILモジュールで定義したmakeTonaCurve関数、makeTiborCurve関数 を呼び出すことで2つのカーブ構築は完了する。
tnCv,tbCv-2026-01-20.png
$\qquad$( 図8-2:Tonaカーブでディスカウントする3ヶ月Tiborカーブ )

8-1-2. makeTiborCurve関数

この4行目の makeTiborCurve関数 が今回の主役で、この関数がディスカウントカーブをTonaカーブとしたTibor3ヶ月の指標金利オブジェクトtbIXとカーブハンドルtbCvHDLを作成する。

オリジナルの makeTiborCurve関数 はテキスト図2.7 (p.47)でmyUTILモジュールに定義され、第3回記事でFRAを処理できるように修正した。

今回は指標金利のテナーを3ヶ月にし、別のカーブでディスカウントできるよう改良した。そのコードが図8-3となる。
myUtilTiborCRVdualpng
$\qquad\qquad\qquad\quad$( 図8-3:myUTIL.pyのmakeTiborCurve関数 )

  • makeTiborCurve:オリジナル(テキスト図2.7)からの修正点は、引数 ( tbDATA,dCRV=tnCvHDL,iTNR=3 )を3つにしたこと

    • 第1引数 tbDATA:これまでと同様、カーブのノードデータ

    • 第2引数 dCRV=tnCvHDL:ツーカーブ時のディスカウントカーブのハンドルを指定(dCRVはdiscount Curveの略)

    • 第3引数 iTNR=3:指標金利テナーの月数 (この例では3ヶ月) を指定 (iTNRはindex tenorの略)

  • 第2, 第3の引数を使い、図8-3の四角で囲った行で、処理を分岐させた

    • 109行~112行:指標金利indexをiTNRで指定されたテナーで作成

    • 119行~122行:dCRV=tnCvHDLが指定されると、119, 120行目の引数でヘルパーを作成

      • Tiborカーブは120行目の最後の引数dCRVでディスカウントされる
      • このヘルパーの引数の説明はテキスト図3.19の7行目 (p.105)参照
  • 117行:knd=fra は第3回記事 図3-1 で追加したFRAを処理させるヘルパー

8-2. ツーカーブでのTibor3ヶ月 スワップ評価

図8-1では、Tibor3ヶ月の5年金利は2.09% (=1.6275%+46.25bp)となっている。この固定金利 cpnRT=2.09%を払い、図8-2の4行目で作成したTibor3ヶ月tbIXを受ける5年スワップが図8-4。

出力結果のスワップNPVtbSwOBJ.NPVは当然 ゼロとなっていて、正しいスワップ評価がツーカーブで行われている。

tbr3mSwap20260120png

$\qquad\qquad\qquad\quad$( 図8-4:固定2.095 vs Tibor3ヶ月 スワップ )

ここでシングルカーブのTiborスワップを書いたコードテキスト図2.8の17行目 (p.48)とこの図8-4を比較し、次の各点を確認しよう。

  • 両図の最も大きな相違点は9行目のDiscountingSwapEngine(tnCvHDL)でエンジン設定に使われるカーブ、つまりディスカウントカーブ、はTonaカーブハンドルのtnCvHDL

    • シングルカーブのテキスト図2.8 23行目でのディスカウントカーブはTiborカーブtbCrvHDL
  • 次に重要なのが、図8-4の8行目 tbIX。このインデックスは図8-2で作成(makeTiborCurve関数経由)されるているが、ツーカーブで計算されるTibor3ヶ月の指標金利である

    • テキスト図2.8 22行目のインデックスtbrIXは同図9行目でシングルカーブから作成されている
  • マイナーな点として、図8-4の5行目は年2回のpDfrqSA (旧pdFreqSA)、6行目は年4回のpDfrqQ (旧pdFreqQ)が指定され、2つのレグの利払頻度は異なっている

以上、テキストとの図の比較から導かれる結論は、スワップの評価において シングルカーブか、ツーカーブかはディスカウントのエンジン作成部分(9行目)のみとなる。その際、指標金利インデックスの作成がシングルカーブまたはツーカーブで行われたかに注意する。

8-3. フォワードカーブのディスカウントファクターの意味

最後にフォワードカーブのディスカウントファクター(以下 DF)について説明し、利用する際の注意点を記す。

まず、フォワードカーブのDF つまり、図8-2の3mTiborのDF列に表示されているディスカウントファクターの計算法はテキストp.103 (2度目のブートストラップ)節で説明した。その説明を多少 補足しておく。

  • テキストp.103では「2度目のブートストラップとして、$f_{tn}$を算出」と書いた

  • これには続きがあり、「求めた$f_{tn}$を基にフォワードカーブのDFを逆算し」、図8-2の3mTiborのDF列として表示している (この部分は著者の現在の理解となり、C++コードを確認した訳ではない)

  • 有料情報端末が表示する3mTiborのDFもQuantLibとほぼ同じ数値であり、「フォワードカーブのDF」のスタンダードとなっている

以上をまとめると、2度のブートストラップによって、

  • Tonaカーブで1度、Tiborカーブでもう1度ブートストラップが行われ

  • 1度目はディスカウントカーブのDFを計算

  • 2度目は変動金利インデックスと同じテナーのフォワードレートを計算

  • このフォワードレートをディスカウントファクターに換算し、フォワードカーブのDFとして表示

となる。

この節を書いた理由は、「フォワードカーブのDFは何のために存在するのか?」という疑問に答えるため。結論を先に言えば、「市場の習慣として、カーブがあれば、DFを見たくなるのが人情」あたりが答えであろう。

つまり、2度目のブートストラップはフォワードレートの算出が目的であり、このDFは本来不要で、かなり誤解を招くDFとなっている。この点を以下で例示しよう。

tbr3mSwapLeg1CFpng
$\qquad\qquad\qquad\quad$( 図8-5:<上> Tibor3ヶ月スワップの変動レグCF
$\qquad\qquad\qquad\qquad\quad\quad$ <下> フォワードレートの手計算$\qquad$)

図8-5は2つのセルのスクショであり、上セルはswapCashFlow関数からの出力、下セルはフォワードレートを手計算した。

  • 上セルのswapCashFlow関数への説明はテキスト図2.11(p.55)を参照

    • 2つ目のdfDSP(dfL1,5) はswapCashFlow関数で作られた変動レグCFのデータフレームdfL1の頭とシッポを5行で表示する関数
      • 関数のコードは図8-7 下段の40行目 を参照
      • 引数はデータフレーム名dfL1と表示したい行数5
  • まず、DF列に表示されたディスカウントファクターは図8-2で作成されたDFと一致している点を確認しよう

    • 例えば、index20の0.90067906は図8-2のindex13と等しい
  • 次に上セルのrate列に表示されたフォワードレートと、下セルの手計算から出力されたnumpy配列が完全に一致していることを確認しよう

    • 下セルのフォワードレートの計算式はテキストp.65 式(2.6)を参照

    • 2行目 DF.shift(1)はPandasでよく使うテクニックの1つで、1行前のDFの値を参照する

  • この手計算から、先ほど記した「2度目のブートストラップで$f_{tn}$が算出され、フォワードカーブのDFを$f_{tn}$から逆算した」と考えた

筆者のこの考察よりも、上記比較から「フォワードカーブのDFを使うと、フォワードカーブの指標金利と同じテナーのフォワードレートを式(2.6)で計算できる」ことを理解することが重要である。

ただし テキストp106でも指摘したが、フォワードカーブのDFから、異なるテナーのフォワードレートやスワップレートは算出できない。

tbr3mSwapnoSwapRTcalcpng
$\qquad\qquad\qquad\quad$( 図8-6:5年スワップレートの手計算 )

図8-6でスワップレートをテキストp.67 式(2.15)で手計算したが、結果は2.08262%で、本来の2.09%を算出(復元)できていない。フォワードカーブのDFは使わないほう良いだろう。

まとめ

  • ツーカーブで金利スワップを評価する手順

    1. ディスカウントカーブはシングルカーブで作成

    2. フォワードカーブはツーカーブで作成

    3. スワップオブジェクトはシングルカーブのものとほぼ同じ。ただし、割引エンジンにはディスカウントカーブを指定

  • フォワードカーブのDFを使うと、フォワードカーブの指標金利と同じテナーのフォワードレートのみ算出可能

(補足) myABBR, myUTIL 両モジュールへの修正点

ここではmyABBRとmyUTILの両モジュールに、新たに追加した関数や変数名などの修正した部分について、補足しておく。まず テキスト全体の変数名作成のルールを確認する。

  • テキスト p.23 脚注10でメモしたように、変数や関数名で使われる小文字のdfはデータフレームを、大文字のDFはディスカウントファクターを表している

    • このルールにより、変数の内容や関数から戻される値が「データフレーム関連なのか」、「ディスカウントファクター関連なのか」を類推しやすくなる
  • テキスト 1.3.8節 (p.23)に記したように、なるべく短く、小文字から始まるキャメル文字(ラクダ文字)を変数名とした

    • そして、変数名から型が連想できるようにしている
      • IX,OBJ,HDL,RTはインデックス、オブジェクト、ハンドル、レート
      • DTはdateの日付型でtrdDTはtrade dateの略
      • DSはdaysの整数型でstlDSはsettle daysでTp2等の整数

これらのルールに従って、テキストや記事のコードを書いている。

( 図8-2で使用した関数 : dfNodes, dfDSP )

では、図8-2に戻り、使用した関数について説明をする。

  • 1行目 myUTIL:以前はmyUtilであったが、今後 myUTILのように後ろ4文字は大文字を使用

    • 小文字のままではエラーとなる点に注意 (サポートページのコードは大文字に修正済み)
  • 3行目 makeTonaCurve:変更は無く、説明はテキスト図3.1 (p.77)参照

  • 6行目 dfNodes(tnCvOBJ,tnParRT,cmpd=CNT):イールドカーブで計算されるディスカウントファクターをパーレート等と共に表示させるために追加した関数でデータフレームを戻す

    • カーブオブジェクトのnodesメソッドから戻るリストはデータフレームへ変換して表示させることが多かったため、作成 (コードは図8-7 上段 31行目を参照)
    • 6行目ではこの関数によって、データフレームdfTNを作成
    • 関数名dfNodesは「カーブオブジェクトのnodesメソッドをデータフレームdf化させる」から命名
    • この関数は4つの引数(crvOBJ, parRT, isoFG=True, cmpd=CMP)を取る
      • 3番目の引数isoFG=Trueはiso日付用のFlagで、nodesメソッドで戻される日付をISO型に変換するフラグ
      • 4番目の引数 cmpd=CMPはゼロレートの計算法を指定
        • 円スワップはcmpd=CNT、ドルはcmpd=CMPでゼロレートを計算するようだが、定まった慣習はない
  • 6行目の右端にある関数dfDSP(dfTN,5)は 長いデータフレームのdfTNの頭(head)とシッポ(tail)の5行を表示する

    • コードは図8-7 下段 40行目を参照
      • 第3引数 fm=fmS によって、スタイル書式用変数を指定可能
    • 関数名は「データフレームdfをdisplayさせる」から命名
( その他 新しく定義した関数等 : showCvDT, isoDT, qlDT )

この記事用にmyUTIL, myABBRの両モジュールに手を加えた。図8-7が新しく定義した5つの関数のコードと新しい変数名。各関数がどのように書かれているかは、コードを読もう。以下、若干の補足説明をしておく。

  • showCvDT関数:取引日、受渡日、インデックス名をプリントする関数

    • 使用例は図8-2の8行目で、 tradeDT:2026-01-20, ... Tibor3M Actual/365 (Fixed) )を最後の行で出力
    • イールドカーブが正しく計算されているかを確認する際、取引日や受渡日は重要となるので作成した
  • isoDT関数, qlDT関数:データフレームの日付列をISO型、QuantLib日付型へ変換する関数。データフレームの列名が引数となる

    • dfNodes関数 37行目のisoDT(dfCRV.date)が使用例
    • メインのコードで lambda関数を見たくないため 作成
      • lambda関数の書き方もすぐ忘れるので、その備忘録を兼ねている
        makeNodeDF,showCurveDate.png
        $\qquad\qquad\qquad\quad$( 図8-7:新しく定義した5つの関数と変数 )
( 変数名の修正に関して )

本体のコードをより短く記述する為、変数名の一部を修正している。図8-7のmyABBRモジュールでは、スタイル書式用変数名を29行目fmSと34行目fmBに修正した。この変数名はformat Swap, format Bondから命名。(古い名称は37行目にあるfmtSCFとfmtFUT)

  • 使用例は同じ図8-7のdfDSP関数の3番目の引数fm=fmS

  • ただし 37行目から判るように、古い変数名でもエラーは発生しない

myABBRモジュールでは他の変数名にも、同じような修正を行っている。

  • 図8-3の109行~112行で使われた短縮形pDfrqSA等の古い変数名はpdFreqSA
  • 図8-4の7,8行ではswPAY,spdRT0という短縮形を追加
    • この2つの短縮形はql.VanillaSwap.PayerとsprdRT=0.0に相当
( myABBRとmyUTILを分ける基準 )

myABBRとmyUTILを分ける基準は単純か、複雑かであり、複雑な関数はmyUTILモジュールに記述。

  • 複雑とは「QuantLibで作成されたファイナンス関係のオブジェクトが必要となる」ことを意味
( 備忘録 と ハイパーリンクできるエディタ )

両モジュールでは短縮形や特殊な関数を多数設定した。これらの関数等は使わなければ、すぐに忘れてしまう。 そんな時、myABBR.pyとmyUTIL.pyを見返せば、引数の入力法やコーディング例等を簡単に確認できる。

この確認の為、テキストp.7 脚注1に記したようにVS Code等のハイパーリンクできるPythonエディタの利用を強く勧める。

筆者はmyABBR.pyとmyUTIL.pyを備忘録として活用している。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?