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?

第10回:USD担保 JPYカーブのコード (CSAベース)

0
Last updated at Posted at 2026-05-06

(訂正 2026/5/10: 著者の理解が誤っており、次を訂正)
$\qquad$ (旧)ドル担保にすることは SOFRが「割る資産」
$\qquad$ (新)ドル担保にすることはTONA$\times$為替が「割る資産」

今回は 通貨スワップの準備として、ドル担保(USD collateral)のTONAカーブを作成するコードを紹介する。

「Pythonで学ぶ債券·金利デリバティブ」(以下 テキスト) 第3章で説明したTONAカーブは円担保(JPY collateral)が暗黙裡に仮定されたCSAベースの割引カーブでもある (テキスト p102) 。以下はこの円担保をドル担保にした場合の、TONA割引カーブ構築法の説明となる。

テキスト p102では「マルチカーブ」という名称のみ紹介し、実装用コードを示していない。グローバルなファイナンスではUSDが標準担保通貨であり、ここで紹介するコードは実務上 必須であろう。

10-1. カバード金利平価

担保通貨が変わるだけで、カーブ構築法は 格段に難しくなる。理論的には、担保通貨を変えることは ニューメレールを変えることに等しい。ニューメレールとは テキスト p.189に記したように、マルチンゲールにするための「割る資産」であるが、ドル担保にすることは TONA$\times$為替が「割る資産」になることを意味している。

つまり TONA(円担保)のニューメレールから、TONA$\times$為替(ドル担保)のニューメレールへの測度変換によって、カーブ構築の数式が説明される。ただ、その導出は長くなるので、回を改め、第11回で説明する。ここでは、難しい理論を無視し、算出する数値例を確認するための計算式のみを示しておく。

ドル担保を前提にすると、国内通貨: $D$ (domestic)はドルであり、外国通貨: $F$ (foreign)は円となる。それぞれのディスカウントファクターを $df^D$ , $df^F$ とする。

FXスポット: $X$ から FXフォワード: $F$ を計算する場合、カバード金利平価 (Covered Interest Rate Parity, CIRP)より、次式が成立する。(この導出は次回を予定)

$$
F = X \cdot \frac{df^F}{df^D} \tag{10-1}
$$

この式は4つの変数で構成され、3つの変数 $X$ , $F$ , $df^D$ は市場で観測可能であり、ドル担保の円ディスカウントファクター $df^F$ は 式の変形で簡単に求めることが出来る。

$$
df^F = \frac{F}{X}\cdot df^D \tag{10-2}
$$

つまり、ドル担保 JPYカーブ $df^F$ は ドル円の為替フォワードとスポットの比にSOFRのディスカウントファクターを掛けて算出できる。(注:為替 X, F は逆数の為替。例えば 1円=0.0064ドル)

ではコードと数値例を見て行く。

10-2. カーブ構築に必要なデータ

カーブ用データ-bbg.png
$\qquad\qquad\quad$図10-1:SOFR, TONA, クロスカレンシー データ (2026-01-20 )

式(10-2)にしたがい、割引カーブとなるSOFRデータがまず必要である。フォワードFXを計算させるため、TONAカーブのデータと通貨スワップ市場で建値されているクロスカレンシーのベーシスも必要になる。つまり、図10-1 のように 3種類のカーブデータを用意する。

  • 2行sfSwRTリストはSOFRカーブ用のレート (テキスト p91 の図 3.9と比較)

    • sfSwRTは sofr swap rate の略 (同様にtnSwRTはtona swap rate)

    • テキストと比べ、市場で標準的に建値されている 2w, 3w 等のノードを入れた

    • このSOFRカーブデータは BGN を使用 (BGNはBloomberg Generic価格の略) 。ただし ソース元は何でもよく、例えば、 BlueGamma 等でSOFRカーブは参照可能

  • 11行tnSwRT リストは 第9回:Tonar vs 3mTibor テナースワップtnDATAリストと同じ

  • 20行xcyBSS リストも 市場の標準にしたがい、次の2種類のデータで構成 (xcyBSSは cross currency basisの略で、データは BGN を使用)

    • 'fxsw'タイプ:FXスワップのデータ

      • タプルの中の数字は スポット為替に対して、フォワード為替がどれだけズレるかを表す

        • 例えば、ドル円のスポットが158.00円の場合、1週間先のドル円は -9.43銭なので157.9057円 ( =158.00-0.0943 )
    • 'bss'タイプ:ドル円通貨スワップのベーシス

      • タプルの中の数字は TONA側に加算される数字
        • 例えば、5年のTONAスワップレートは 1.6275% なので、ベーシス (-36.5bp) 加算後は、1.2625% ( =1.6275% - 36.5bp )
        • TONA側への加算なので、このベーシスの日数計算は Act/365 であり、SOFRのAct/360 ではない点に注意 (日数計算の異なる金利の足し算は厳禁)
        • この計算ルールは「第9回:Tonar vs 3mTibor テナースワップ」のベーシスと同じ

満期1年までをFXスワップのデータとしている理由は流動性が高いため。一般のWebにも、FXスワップ のデータは開示されている ( Investing.com )。しかし、通貨スワップのベーシスは見つけることが出来なかったため、BGNを使った。

10-3. ドル担保 JPYカーブ構築のコード

では、ドル担保のJPY(TONA)カーブを構築するが、まず 準備として、SOFRとTONAカーブをシングルカーブとして作成しておく。
singleカーブコード.png
$\qquad\qquad\qquad\qquad$図10-2:シングルカーブ作成 ( SOFR / TONA )

図10-2 で 新しく登場したコードは次の2点のみ。

  • 3行ql.JointCalendar は複数のカレンダーを合成するコンストラクタ

    • 3行目では Fedwire決済用カレンダー calUSf と日本のカレンダー calJP を合成し、calUJ という米国と日本の両方を休日にもつカレンダーオブジェクトを作成
  • 4行adD 関数 はmyABBRモジュールで新しく定義した短縮形で、calUJ.advance(trdDT, Tp2, DD) に同じ
    myABBR-adD関数.png

    • カレンダーオブジェクトのadvanceメソッドは多用するので、短縮形を作成
    • adD は add dayの略。上図のようにadW, adM, adY 等も作成したが... (短縮効果はあまりない)
  • その他は以下で既に説明済み

(注:この記事のデータフレーム画像は不要な行を削除している)

10-3-1. クロスカレンシー ベーシス カーブ

下図10-3 で出力されたデータフレームのzeroRT列DF列が 目標のUSD担保JPYカーブである。まず 出力結果の数値を確認する。

  • 図10-3 index14 5年ノード のzeroRT列 1.257487%

    • 図10-2 出力の最後の行 index22 zeroRT列 1.622316% との差は 0.36483%

    • この差は図10-1の25行目 5年ベーシス -36.5bp にほぼ等しい

  • 有料情報端末が算出したディスカウントファクター(以下 DF)との比較では以下を確認した

    • FXスワップ(fxsw)のノードのDFは完全に一致

    • ベーシス(xcyBSS)で満期が短いノードのDFは ほぼ一致

      • 満期が長くなると 1e-5桁の値が5前後のズレを示した ('1e-5'という表現はテキスト p230 参照)

かつて筆者はドル担保のカーブをエクセルで手計算したが、これほどの精度での再現は出来なかった。このカーブ算出は難解で、いまもトラウマになっている。

ドル担保TONAカーブ.png
$\qquad\qquad\qquad\qquad$図10-3:USD担保 JPYカーブ

では 図10-3 のコードを概説する。使用したヘルパーは異なるが、テキスト p.77 図3.1の2番セルで説明したQuantLibの基本的なカーブ構築法の 以下の2つのステップは同じである。

  • ステップ1: 各ノード情報をヘルパーオブジェクトに変える

    • 5行: forループにより、図10-1 で設定した xcyBSS リストからノード情報を取り出す

    • ただし、図10-3では 新しい 2つのヘルパーを使用。 これらの詳細は次の10-3-2節で説明する

      • 7行: FXスワップ用のFxSwapRateHelper
      • 11行:通貨ベーシス用のMtMCrossCurrencyBasisSwapRateHelper
  • ステップ2PiecewiseLogLinearDiscountでカーブオブジェクトを作成

    • 15行: forループで作成したcHelperを使い、カーブオブジェクトjBsCvOBJを作成
      • この行は テキスト 図3.1の15行目とほぼ同じ

以上の概説から、2つのヘルパー部分を除き、コード構成は理解できるだろう。

10-3-2. クロスカレンシー カーブ用の2つのヘルパー

図10-3 2,3行目 で設定した変数の説明から始める。これらはヘルパーの引数として与えられるので、当初は意味不明でも読み流してよく、ヘルパーの説明と共に参照しよう。

jpySP:2026年1月20日のドル円 スポット為替(T+2) が 158.1528 円/ドル

base...:base から始まる変数を4つ設定したが、base には 担保通貨USDの意味を持たせた。 反対のワードが othr (othr は other の略)

  • baseIX: USDカーブのインデックスsfIXの別名 (sfIXは図10-2の6行目で作成)

  • othrIX:JPYカーブのインデックスtnIXの別名 (tnIXは図10-2の7行目で作成)

    • ヘルパーの引数にsfIXtnIXを直接指定してもよいが、これら別名を与えて、引数の役割を明確にさせた
  • baseCLLT = True: baseであるドルが担保 (CLLTはcollateralの略)

  • baseBSS = False: baseのドル側にベーシスを乗せない

    • 図10-1のxcyBSSは円側に加算するレート
  • baseRST = True: baseのドル側をリセットさせる (RSTはrestの略)

    • 標準的な通貨スワップは利払い毎にドル元本をリセット ( MtM / resettable notional、 MtM は mark to market の略 )

    • リセットに関しては、通貨スワップを説明する記事(第12回を予定)で数値例を紹介する

ではヘルパーの説明に移る。

  • 下のヘルパーのスクショはリファレンスマニュアル (テキスト 1.6節) のものであり、テキスト p.32 下から2行目に記したように、&const は無視しよう
( FxSwapRateHelper )

FxSwapRateHelperClass.png

( 図10-3の 7, 8行目の引数との対応関係 )

fwdPoint spotFx tenor fixingDays calendar convention
sQH(bb/100) sQH(jpySP) pD(tt) Tp2 calUJ mFLLW
endOfMonth isFxBaseCurrencyCollateralCurrency collateralCurve
EoMf baseCLLT = True sfCvHDL
  • この対応表から、各引数の役割は理解しよう

  • sQH関数 : myABBRで新たに定義した短縮形で、テキストのmu.sqHDL関数と同じ

    • mu.sqHDL(...) が長いので、myABBRに移し、より短い関数名とした

    • (補足 1) C++を知っていれば、スクショの第1引数のHandle < Quote > fwdPointから、第1引数はQuote型のハンドルが要求されていることが判るだろう。そのためにsQH関数を使用

    • (補足 2) テキスト p.30 に、著者のブログ "QuantLibソースを読むためのC++基礎" を記したが、現在 Claude Code等が発達し、このブログは見直し中

( MtMCrossCurrencyBasisSwapRateHelper )

MtMCrossCurrencyBasisSwap.png

( 図10-3 12, 13行目の引数との対応関係 )

basis tenor fixingDays calendar convention endOfMonth
sQH(bb*bps) pD(tt) Tp2 calUJ mFLLW EoMf
baseCurrencyIndex quoteCurrencyIndex collateralCurve
baseIX = sfIX othrIX = tnIX clltCv = sfCvHDL
isFxBaseCurrencyCollateralCurrency isBasisOnFxBaseCurrencyLeg
baseCLLT = True baseBSS = False
isFxBaseCurrencyLegResettable paymentFrequency
baseRST = True frqQ
  • 同様にこの対応表から、各引数の役割を推測しよう
  • bb*bpsbb÷10000と同じ。(myABBRで bpsを定義)

10-3-3. 式(10-2)の手計算と精度

hc-clltJPY1Y.png

このセルは最初に示した式(10-2)を使い、ドル担保JPYカーブの1年DFを手計算した。各変数は次の通り。

  • fwd1y:1年FXフォワード = 153.8158
  • sf1yDF:図10-2のSOFR 1年DF = 0.96535756
  • 3行目のjpySP/fwd1y: 式(10-2)と分子分母が逆転している理由は、式(10-2)の為替が逆数為替のため

図10-3 の1年DF=0.99274434 に対し、手計算の0.992577 は 1e-4で2程度 ズレているが、悪くはない。

  • 式(10-2)は近似式としては使えるだろう
  • (ウォールストリートでは最低 1e-6 の一致で正しい計算と見做される)

原稿執筆時点で、ズレの原因は不明。QuantLibのコードを読めば、原因を究明できるだろうが、このテーマは計算が複雑過ぎて トラウマである。

まとめ

  • USD担保 JPYカーブの計算式(10-2)はカバード金利平価から算出 (理論的な導出は第11回を参照)

  • USD担保 JPYカーブを構築する場合の必要なデータを 図10-1 に例示

  • 2つの新しいヘルパーによる USD担保 JPYカーブ 構築のコード例 (図10-3)

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

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?