1.  QuantLibを使ってみる

1.2   Example を試す

1.2.11   CDS : Credit Default Swap の価格評価

1.2.11.4   ソースコードの解析
1.2.11.4.1   ローカル関数 example01()

このローカル関数が作成されたのは、クレジットデリバティブズの大がかりな標準化が行われた 2009年の Big-Bang (JSCCが出しているQ&Aの中のBigBang/SmallBangに、詳しい解説が出ています)以前のようです。それは、コード内で使われている取引日が2007年5月である事と、ここで作成されているCDSのスプレッドが150bpになっている事などからも、伺えます(Big-Bang後は、CDSのスプレッドは100bpあるいは500bpが標準になっている)。なので、商品の条件や、クレジットカーブの構築方法や、価格計算方法で、現在の市場慣行と若干ずれている部分もあり、実際に実務で使うには注意が必要です。それを念頭に、コードの解析を進めたいと思います。 

このプロジェクト例もこれまでと同様、商品オブジェクトと価格エンジンオブジェクトを、それぞれ部品から作成し組み立てて行きます。最後に、商品オブジェクトに価格エンジンを設定し、そこからNPV()関数を呼び出して価格計算を行っています。特に、価格エンジンで使う重要な部品として、イールドカーブに加えて、クレジットカーブがあり、その作成にコードの大半を使っています。  

(1)  日付の設定と、イールドカーブの構築

60~65行目で、カレンダー、trade date(取引日)、evaluation date(時価評価基準日)を設定しています。Trade dateとして2007年5月15日が設定されていますが、おそらくこの頃に、このプログラムコードが作成されたと推察します。また、カレンダーとして、TARGET(注)を使っています。カレンダーについては、2009年のBig-Bang以降、大半のCDS契約で使われているのは、WeekendsOnly(土日のみを休日とみなす)となっているので、この点も、コード例が古いと推察する理由です。 

(注 TARGET:欧州中銀がオープンしている日を基準としたカレンダー。Euro通貨の決済日として、€導入国のカレンダーで、どこかの国で営業日となっている日は、すべて営業日として設定) 

次に、68~71行目でイールドカーブを作成しています。ここでは、テスト目的なので、金利が全期間に渡り1%となるフラットなイールドカーブ(FlatForwardクラスのイールドカーブ)を作成しています。 

(2)  クレジットカーブの構築と画面出力

81~128行目でクレジットカーブ(デフォールト確率の期間構造)を作成しています。クレジットカーブは、CDS の市場価格(スプレッド)から、Bootstrapping-Interpolation 法を使って、ハザードレート(デフォールト強度)や、サバイバル確率(survival probability または non-defaulting probability)や、デフォールト確率の期間構造を求めたものです。考え方は、スワップ金利の市場データから、金利の期間構造を求める方法によく似ています。金利の場合、導出されたイールドカーブは、瞬間フォワード金利や、Discount Factorや、Zero Rateの期間構造で表現されます。クレジットカーブでは、ハザードレートやサバイバル確率やデフォールト確率の期間構造で表現されます。それらを導出する為の計算式やアルゴリズムをみると、ハザードレートは、イールドカーブにおける瞬間フォワード金利に相当し、サバイバル確率は、Discount Factorに相当します。従って、クレジットカーブを構築するのに必要なオブジェクトや、アルゴリズムも、イールドカーブのそれに良く似ています。それを念頭に、コードの解析をすすめていきます。  

その前に、82行目でsettlementDaysとして、取引日から決済日までの期間を設定しています。ここでは1日となっています。注意すべきは、CDS取引契約においてSettlement Dateとは、Credit Eventが発生した後、デフォールト損失相当額の現物決済あるいは現金決済における決済日を意味します。ここでは、取引日の1日後なので、実際には(ISDAの定義では)Effective Date、すなわちクレジットプロテクションが有効になる日を意味します。さらに次の行で、recovery_rate(債権回収率)として、50%が設定されています。回収率については、実際には40%を使うケースが多く見られます。 

さてクレジットカーブですが、まず、CDSの市場データを用意します。84~96行目で、期間が3か月、6か月、1年、2年のCDSスプレッドデータを用意しています。ここではいずれも1.5%で設定しています。 

次に、このデータを使って、BootstrapHelper オブジェクト(の配列)を作成しています(98~105行目)。ここでは、BootstrapHelper の派生クラスである、DefaultProbabilityHelper クラス(のさらに派生クラスである SpreadCdsHelper クラス)のオブジェクトが作成されています。イールドカーブ構築の際の BootstrapHelper の役割については、Jissenhen1.2.3.4 の Appendix4で既に解説済みですが、ここで使われている DefaultProbabilityHelper の役割も、ほぼ同じです。すなわち、CDS の商品オブジェクトと価格エンジンを合体したような機能を持ち、期間構造の Pillar を提供すると同時に、Bootstrapping-Interpolation アルゴリズムの中で、Solver に提供される目的関数の一部を担います。 

こうして作成されたBootstrapHelperの配列(変数名instruments)を使って、実際にBootstrapping-Interpolationアルゴリズムを使って、クレジットカーブを生成します。108行目にあるその部分を、下記に抜き出しました。 

	auto	hazardRateStructure= 
	    ext::make_shared<PiecewiseDefaultCurve<HazardRate, BackwardFlat>>(		
		todaysDate, 		:本日の日付
		instruments, 		:BootstrapHelperの配列
		Actual365Fixed()	:日数計算方法
		);						

注目すべきは、PiecewiseDefaultCurve<HazardRate, BackwardFlat>というテンプレートクラスです。テンプレート引数との1番目は、Bootstrapping-Interpolation の対象となるクレジットカーブを指定するもので、ここでは HarzardRate カーブが指定されています。また2番目の引数は、Interpolation の方法を指定するもので、ここでは BackwardFlat が指定されています。さらに、3番目のテンプレート引数があり、そこで Bootstrapping のアルゴリズムを提供するクラスを指定するのですが、デフォールトで、IterativeBootstrap<Curve>クラスが指定済みで、上記のコードには出てきません。このテンプレート引数の設定で構築されるクレジットカーブは、各Pillar間で、hazard rateが一定(piecewise constant)となります。 

このテンプレートクラスの役割は、引数として渡された BootstrapHelper の配列を使って、実際に Bootstrapping-Interpolation のアルゴリズムを走らせ、クレジットカーブのオブジェクトを作成するものです。これは、MulticurveBootstrapping プロジェクトでの解説で紹介した(Jissenhen1.2.3.4  Appendox 5 )、PiecewiseYieldCurv<Discount,Cubic,…>クラスの役割と同じです。なので、詳しくは、そこでの解説をご覧ください。 

最後に、112~128行目で、構築されたクレジットカーブについて2種類の期間構造を画面出力しています。ひとつは、ハザードレート(瞬間デフォールト強度)で、もうひとつは、サバイバル確率(ある時点までデフォールトしない確率)です。具体的な数字は、画面出力の通りです。ちなみに、カーブ構築で使われたCDSスプレッドが1.5%フラットで、デフォールト回収率が50%だったので、ハザードレートは、下記の近似式で求まります。見ての通り、画面出力もほぼその水準になっています。 

\[ hazard rate ≅ \frac{CDS~~spread}{recovery~~factor}= \frac{1.5%}{50%}=3.0% \]

 一方、サバイバル確率は、下記式で求まります。 

\[ survival~~robability(T) = e^{-∫_0^T h(t)dt},~~~~~~ \\ 但し~~~  h(t)~:~t~ 時のハザードレート \]

ここでは、ハザードレートは、既に求めた通り全期間一定の 3%なので、上式の指数関数の肩にある積分はは、-hT と置き換える事ができます。それを当てはめて、1年後までと、2年後までのサバイバル確率を求めると、 

\[ e^{-hT}=e^{-0.03*1}=0.9704, ~~~~~~~ e^{-0.03*2}=0.94176 \]

となり、画面の出力結果とほぼ同じです。 

(3)  価格エンジンオブジェクトとCDSオブジェクトの構築 

まず、132と133行目で価格エンジンオブジェクトを作成しています。その主要部品は、イールドカーブと、クレジットカーブと、デフォールト時の債権回収率です。イールドカーブは既に作成済みのオブジェクト(変数名tsCurve)を使い、クレジットカーブは、デフォールト確率のTermStrucutreオブジェクトを作成し、それを使っています(変数名probability)。 

次に、価格評価の対象となるCDSを4種類作成しています。それぞれ、期間が3か月、6か月、1年、2年となっていますが、他の条件はすべて同じなので、3か月のCDSオブジェクトのコンストラクターで、どのような部品から組み立てているか見てみます。ただその前に、重要な部品のひとつである、キャッシュフローの情報を格納する Schedule オブジェクトを、事前に作成しているので、そちらから見てみます。135~141行目にある Schedule クラスのオブジェクトの生成部分について、下記にコードを抜き出しました。 

	Schedule	   cdsSchedule = MakeSchedule()
		.from(settlementDate
		.to(maturities[0])
		.withFrequency(Quarterly)
		.withCalendar(calendar)
		.withTerminationDateConvention(Unadjusted)
		.withRule(DateGeneration::TwentiethIMM); 						

このコードを見て、デザインパターンに馴染みのある方は、これが Factory Method Pattern である事にすぐ気づくでしょう。Factory Method Pattern は、具体的なオブジェクトを作成する際、そのクラスのコンストラクターの役割を、Factory(組立工場)となるクラスに持たせたものです。ここで作られる Schedule クラスは、キャッシュフロー日付を決定する様々な取引慣行に基づいて、実際のキャッシュフロー日付を特定します。取引慣行によって、必要とする情報が様々で、それらの組み合わせは何十通りにもなります。なので、コンストラクターを定義しようとすると、何十種類も定義する必要がでてきます。そこで、別途 Factory Class (ここでは MakeSchedule クラス)を作成し、そこで、様々な部品のバリエーションに対応した組立工場の役割を負わせています。Factory Method Pattern については、Web で多くの解説が為されているので、そちらを参考にして下さい。 

CDS のキャッシュフロースケジュールは、標準化が進んでおり、プレミアム CF の支払い日は 3,6,9,12月の 20日で、Maturity は、3,6、9、12月のいずれかの月の 20日とするのが大半です(Maturityについては、2015年以降、6月か12月の20日とするのが一般的)。 3,6,9,12月というのは、IMM のユーロドル3か月物の金利先物の最終決済月(限月)と同じです。ただ、ユーロドル先物の決済日は、第3週の月曜日なのに対し(従って、月により 15~21日のいずれかに決まる)、標準化された CDS 取引のプレミアム支払い日は、20日に固定されます。上記の MakeSchedule ファクトリーの最後の行で、DateGeneration::TwentiethIMMとなっているのは、それを意味しています。さらに、その 1行前にある withTerminationDateConvention() で、Unadjusted が指定されているのは、CDS の満期日は、仮にその日が休日であっても動かさないという意味になります。満期日を休日であっても動かさないのは、そもそも credit event(CDSのプロテクションが発動される事象)は、休日でも発生し得る事と、その場合、国によって異なるカレンダーを適用すると、CDS 満期のミスマッチが発生するので、それを避ける為です。 

少し回り道をしましたが、上記で作成したScheduleクラスのオブジェクトを使い、CDSの商品オブジェクトを4種類作成します。その内のひとつのコンストラクターを抜き出して下記します。 

	CreditDefaultSwap  cds_3m(
		Protection::Seller, 		:クレジットプロテクションの売り手
		nominal, 			:みなし元本	
		quoted_spreads[0],		:プレミアムCFのスプレッド
		cdsSchedule, 		:CDSキャッシュフロー日付
		Following, 		:休日の取り扱い(Maturityは除く)
		Actual365Fixed()		:日数計算方法
		); 	

それぞれの引数(部品)は、既に作成済みで、それらをコンストラクターに渡してCDSオブジェクトが組み立てられます。 

(4)   CDSオブジェクトに価格エンジンをセットし、価格計算、画面出力 

以上で、価格エンジンと商品オブジェクトが出来上がったので、後は、その商品に価格エンジンをセットし NPV() を呼び出せば価格計算が出来ます。175~179行目で、4種類の商品それぞれに、価格エンジンをセットしています。 

最後に、それぞれの商品について、fairSpread()、NPB()、defaultLegNPV()、couponLegNPV() を呼び出して、適正スプレッド( NPV=0 になるようなCDSスプレッド)、価格、デフオルト CF の NPV、プレミアム CF の NPV を計算し画面出力しています。計算結果は画面出力を見ての通りです。クレジットカーブを導出する為に使った市場レートが、すべて 1.5%のフラットカーブであったので、そのカーブを使って、スプレッドが 1.5%の CDS の価格を計算すれば、NPV は 0 になり、適正スプレッドは 1.5%になるのは、当然です。NPV が完全に 0 になってないのは、期間を年数換算した時の計算誤差からくるものです。 

1.2.11.4.2   ローカル関数 example02()

このローカル関数は、コード内の日付を見ると、2014年頃に作成されたもののようです。しかし、コードの中で不必要なオブジェクトが作成されていたり、二重バックスラッシュで、コードを無効化している部分があったりして、全体として未完成のように見えます。なので、とりあえず作成された有効な部分で、QuantLibが提供しているCDSの価格評価のツールを中心に解説します。 

まず、このローカル関数の内容を、簡単にまとめます。 

(1) CDSのキャッシュフロー日を生成する、Scheduleオブジェクトの作成と画面出力 

(2) 金利の TermStrucutre オブジェクトを作成し、満期 Pillar ごとの内容を画面出力 

(3) クレジットカーブ(ここでは FlatHazardRate クラス)のオブジェクトを作成 

(4) CreditDefaultSwap オブジェクトを作成し、そこから経過利息を計算し、画面出力 

(5) ISDA Standard Model の価格エンジンを作成し、CDS オブジェクトに設定、NPV() を計算し、画面出力 

(6) クレジットカーブ(ここでは DefaultPrbabilityTermStructure)オブジェクトを作成し、画面出力 

(7) 無効化部分

上記の内、(2)~(5)がメインで、ここではCreditDefaultSwapオブジェクトと、IsdaCDSEngineオブジェクトを組み立て、最後にNPV()で価格を計算しています。(1)と(6)は、それとは全く関係なく、CDSキャッシュフローのスケジュールを作成したり、クレジットカーブを構築して、それらを画面出力したりしているだけです。CDSのスケジュール構築方法は、ISDAにより標準化されており、(1)では、その取引慣行によるスケジュールを作成しています(但し2015年の見直し以前の方法)。またISDAはCDSの価格エンジンで使われるイールドカーブとクレジットカーブの構築方法についても標準化しており、(2)と(6)では、それに従ったカーブが構築され、画面出力されています。(7)の無効化部分はMakeCreditDefaultSwapファクトリークラスを使って、CDSオブジェクトを作成し、(6)で生成したクレジットカーブを使って価格計算をしようとしています。無効化をはずしてビルドしようとしましたが、うまく行きませんでした。 

では、それぞれの項目について、もう少し内容を詳しくみていきます。 

(1) CDSスケジュール 

まず、本日の日付(ここでは2014年9月25日)と、それを基準とした2年後の日付を設定します。(207~210行目) そこから、以下のように、Scheduleオブジェクトを作成します。その際、MakeScheduleのファクトリー・オブジェクトを使って生成します。 

	Schedule cdsSchedule = MakeSchedule()
		.from(todaysDate)
		.to(termDate)
		.withFrequency(Quarterly)
		.withCalendar(WeekendsOnly())
		.withConvention(ModifiedFollowing)
		.withTerminationDateConvention(ModifiedFollowing)
		.withRule(DateGeneration::CDS) ; 

ここで注意すべきは、 

  • カレンダーとして、WeekendsOnly を使っている点。
  • Schedule(キャッシュフロー発生日のスケジュールオブジェクト)生成のルールとして、“CDS”というルールを使っている点

です。いずれも、ISDA より標準化されたルールです。“はじめに”でも簡単に触れたように、CDS の Cash Flowスケジュールと、満期日は、取引の相殺がしやすいように、できるだけ標準化された条件で行われます。カレンダーについては、国によって休日が異なることによってキャッシュフロー日付がずれると困るので、土曜日と日曜日のみを休日とする取り扱いとなっています。また、DateGeneration::CDS というルールは、CDS の満期日とプレミアムキャッシュフローの発生日を3月、6月、9月、12月の 20日に限定するものです。ただ、上記のコードでは、TerminationDateConvention (最終期日が休日であった場合の取り扱い)を Modified Following で設定しています。しかし、ISDA の標準では、Unadjusted(休みであっても、その日を最終期日とする)となっており、必ずしもISDA標準に従っていません。さらに、2015年以降の取引慣行として、ISDA は CDS の満期日については、年4回から、6月と9月の年2回に限定しています。その場合は、DateGeneration::CDS2015 とすれば、そのルールに従って満期日を生成します。 

(注:後で述べますが、QuantLib のアルゴリズムでは、そのロジックがうまく実装されていないように見えます。私自身、コードを深く調べてないので、Bugなのか、使い方が悪いのか、よく分かりません) 

最後に 220~221 行目で、今生成した Scheduleオブジェクトの内容を画面出力しています。見ての通り、取引日が 2014年9月25日で、そこから期間 2年の CDSのキャッシュフロースケジュールを生成すると、満期日は 2年後の 2016年9月25日以降で、最も近い ISDA標準の満期日である、2016年12月20日になります。また、プレミアム CF の日付は、3,6,9,12月の20日で、それらが休日の場合は、Modified Followingのルールが適用されています。 

なお、ここで生成された Schedule オブジェクトは、これ以下のコードで使われていません。なので、コードのこの部分が作成された意図は不明です。 

(2) ISDA標準モデルを使った、イールドカーブの構築(223~331行目) 

次に、ISDA Standard Model を使った、イールドカーブの構築を行っています。後で、このカーブを使って、CDS の価格評価を行います。ISDA Standard Model は、シンプルで標準的な CDS 取引用に、ISDA のバックアップの下、Markit 社が提示している価格評価方法です。具体的には、イールドカーブとクレジットカーブの構築方法、およびデフォールトCFとプレミアム CF の現在価値の期待値を導出するアルゴリズムを、プログラムコードで提供したものになります。ISDA Standard Model については、このサイトで内容を確認して下さい。 

ISDA Standard Modelで使われているイールドカーブの構築方法ですが、 Interpolationは、“Discount Curveの対数”を“線形補間”で行います(ゼロクーポン金利の線形補間と同じ意味)。この方法でのイールドカーブ構築方法については、MulticurveBootstrappingプロジェクトの所で、詳しく解説したので、そちらを参考にして下さい。ここでも、同じように、市場データからBootstrapHelper の配列を生成し、それを使って、Bootstrapping-Interpolation のアルゴリズムを走らせます。下記に、319~321行目にあるその部分を抜き出しました。 

	Handle<YieldTermStructure>  rateTs(
		ext::make_shared<PiecewiseYieldCurve<Discount, LogLinear>>(
		0,
		WeekendsOnly(), 
		isdaRateHelper, 
		Actual365Fixed()
		) 
	);	

(3) クレジットカーブのオブジェクトを作成(334行目) 

ここでは、FlatHazardRate オブジェクトを作成しています。クラス名から分かる通り、hazard rate を全期間一定と仮定してクレジットカーブを構築しています。コンストラクターに渡されているhazard rateは、約 1.674%となっています。 

ISDA Standard Model では、クレジットカーブも Bootstrapping-Interpolation のアルゴリズムで構築しており、その際、Interpolation を、"Survival Probability の対数" を "線形補間" して Interpolation しています。しかし、ここではこの方法を使っていません。しかし、ISDA の標準モデルでは、クレジットカーブは、満期Pillar間で hazard rate が一定になるように構築されるので、結果的には、ISDA Standard Model によるクレジットカーブと同じになります。ちなみに、後程(6)の所で、ISDA Standard Model に従ったクレジットカーブオブジェクトを生成しています。 

(4) CDSオブジェクトの作成(337~347行目) 

ここでは、価格評価対象となる CreditDefaultSwap オブジェクトを、部品となる Scheduleオブジェクトから作成しています。その際、上記(1)で使った MakeScheduleファクトリーを使わず、Schedule クラスのコンストラクターに部品を渡して組み立てています(337行目)。注意すべき点は、引数で渡されている部品の内 

  • 2番目の引数で、CDS の満期日を2019年12月20日で設定
  • 4番目の引数で、カレンダーを WeekendsOnly で設定
  • 6番目の引数で、満期日が休日の場合の設定を Unadjusted にしている
  • 7番目の引数を、DateGeneration::CDSと設定

としている所です。いずれもISDAのCDSの標準形の条件になります。ちなみに、満期日は、無理やり12月20日に設定せず、期間5年としておけば、DateGeneration::CDSの設定により、自動的にそうなります。 

そして、339 行目で CreditDefaultSwap オブジェクトを作成しています。下記にそのコンストラクターを抜き出しました。 

	auto trade = ext::make_shared<CreditDefaultSwap>(	
		Protection::Buyer, 		:Credit ProtectionのBuyerサイド
		100000000.0, 		:看做し元本
		0.01, 			:プレミアムCFのスプレッド
		sched, 			:先ほど作成したScheduleオブジェクト
		Following, 		:CF日付の休日の取り扱い
		Actual360(), 		:プレミアムCFの日数計算方法
		true, 			:経過利息の発生
		true,			:デフォールトの際の支払日
		Date(22,October,2014), 	:プロテクションのスタート日
		ext::shared_ptr(),		:デフォールト時の支払い額
		Actual360(true), 		:最終経過期間の日数計算方法
		True			:デフォールト時までの経過利息支払い
		);						

標準形の CDS であっても、オブジェクト構築に必要な部品は多いので、非常に長い引数のリストになっています。従って、このコンストラクターを使いこなす(CDS オブジェクトを生成する)には、相当程度の商品知識が必要になります。 

最後に、CDS の最初のプレミアム CF 期間と、決済日()に対応する経過利息、を計算し、画面出力しています。一般的な CDS 取引では、Effective Date がプレミアム CF 支払い日でない場合、Protection Buyer が経過利息を支払う必要があります。 

(5) 価格エンジンの作成と価格計算(350~356行目) 

ここでは、ISDA Standard Model のアルゴリズムを使う価格エンジンである IsdaCdsEngine オブジェクトを作成しています。下記に、そのコンストラクターを抜き出しました。 

	auto engine = ext::make_shared<IsdaCdsEngine>(
		Handle<DefaultProbabilityTermStructure>(defaultTs0), :クレジットカーブ
		0.4, 			:債権回収率
		rateTs,			:イールドカーブ
		false,			:CDS価格のDirty Price表示
		IsdaCdsEngine::Taylor,	:ISDA Modelの不安定さの修正方法
		IsdaCdsEngine::NoBias, 	:経過利息のバイアス修正
		IsdaCdsEngine::Piecewise	:
		);	

ISDA Standard Model で使われている CDS の価格エンジンについては、先ほど紹介した、OpenGamma 社が出している文書を参考にして下さい。上記コンストラクターの引数で、特に最後の3つの引数については、内容は難解なので、ここでの説明は省略します。実際に使う場合、デフォールト値での設定をそのまま使えばよく、ユーザーが気にすべき部品は、イールドカーブとクレジットカーブと債権回収率の3種類だけです。 

これで価格エンジンが出来たので、 それをCDSに設定し、NPV()を呼び出して価格計算を行い、画面出力します。 

(6)  ISDA Standard Model によるクレジットカーブの構築(360~380行目) 

ここでは、ISDA Standard Model で使われている、クレジットカーブの構築方法を使って、クレジットカーブを作り、さらにその内容を画面出力しています。このプログラム作成者は、このカーブを使って、CDS の価格評価をするつもりでいたようですが、この後に書かれたその部分のコードは二重バックスラッシュで無効化されており、結局、クレジットカーブを構築するだけで終わっています。 

クレジットカーブの構築は、example01()でも説明した通り、イールドカーブの構築とほぼ同じプロセスです。すなわち、まず市場データから BootstrapHelper(ここではSpreadCdsHelper)オブジェクトの配列を生成し、それを使って、PiecewiseYieldCurve<SurvivalProbability, LogLinear,…> オブジェクトを作成します。このテンプレートクラスは、テンプレート引数である SurvivalProbability のカーブを、LogLinear の方法でInterpolationするアルゴリズムが記述されており、それにより具体的なクレジットカーブオブジェクトが作成されます。このInterpolationの方法が、まさにISDA Standard Modelに該当します。369行目がそれです。ここでは、市場データとして、5年物のCDSのスプレッドのみを使っており、Piecewise constantとは言っても、全期間一定のフラットなhazard rate カーブが作成されます。 

最後に、その内容(Pillarの日付と、その時点までの年数、及び、その時点までのデフォールト確率)を画面出力しています。 

(7)  無効化部分

この部分は、2重バックスラッシュで無効化されており、解説は省略します。それをはずしてビルドしてみましたが、MakeCreditDefaultSwap()のファクトリークラスが、うまくコンパイルされず、ビルドに失敗しました。 

1.2.11.4.3   ローカル関数 example03()

このローカル関数内でも、ISDA Standard Model に従った、イールドカーブとクレジットカーブの構築を行っています。Trade Date の設定が、2011年6月13日になっており、このローカル関数は、この頃に作成されたと推察しますが、example02()と日付は前後します。このパートも、未完成のように見えます。というのは、イールドカーブとクレジットカーブを作成し、それを使ってISDA Standard Model のアルゴリズムを備えた価格エンジンオブジェクトを作成するのですが、それを使う対象となる CDSオブジェクトを作成しておらず、価格エンジンだけ作りっぱなしになっています。その後に、イールドカーブとクレジットカーブの内容を画面出力しますが、そこで終わっています。なので、このローカル関数は、単にISDAモデルに従ったカーブ構築方法をテストしていると看做した方がいいでしょう。 

では、コードの内容を見て行きますが、上記で述べたように、結局イールドカーブオブジェクトとクレジットカーブオブジェクトを作成しているだけなので、example01() や example02() と重複している部分が多く、解説も簡単に済ませます。 

ひとつ、重要な注意点を述べておくと、この example コードで作成されたクレジットカーブの満期 Pillar日付を見ると、満期日が各年の 20日で固定されておらず、Following による休日調整をしているようです(画面出力参照)。ISDA の標準的 CDS の満期日は、仮に休日であっても調整しないので、Schedule オブジェクトの生成アルゴリズムが正しく設計されていないのか、使い方が悪いのか、よく分かりません。なので、実務でこのまま使うのは避けた方がいいと思います。ちなみに、この example コードが真似しようとした、既に紹介した OpenGamma の論文でのクレジットカーブ構築では、満期 Pillar日付がすべて 20日で固定されていました。 

(1) イールドカーブオブジェクト(金利の TermStrucutre オブジェクト)の作成 

まず基準日となる Trade Date と Evaluation Date を設定します。いずれも、2011年9月13日に設定されています。 

あとは、MulticurveBootstrapping プロジェクトで解説したのと、同じ要領で、TermStrucutre オブジェクトを作成します。すなわち、 

  1. 438~455行目で DepositRateHelper オブジェクトを作成
  2. 464~508行目で SwapRateHelper オブジェクトを作成
  3. 510~532行目で、それらを、一本の配列にまとめる(変数名 isdaYieldHelpers)
  4. その配列を使って、PiecewiseYieldCurve<Discount, LogLinear,…>オブジェクトを作成。その時、Bootstrapping-Interpolation のアルゴリズムが走り、具体的なイールドカーブが作成される。その際、テンプレート引数にある通り、"Discount Factor"の "対数を線形補間"する Interpolation 法を使う。
  5. 538 行目で、作成された TermStrucutre オブジェクトから enableExtrapolation()を呼び出し、補外(Extrapolation)を行えるようにする。

(2) クレジットカーブオブジェクトの作成 

次に、クレジットカーブ(具体的には DefaultProbabilityTermStructure クラスのオブジェクト)を作成します。これも、イールドカーブを構築するのと同じように、BootstrapHelper(の派生クラスである SpreadCdsHelper)の配列を作成し、それを使って Bootstrapping-Interpolation のアルゴリズムを走らせます。具体的には 

  1. 541行目で、SpreadCdsHelper で使われる CDS の価格計算方法を設定します。そこにある通り、ISDA という名前の価格エンジンが指定されていますが、これは ISDA Standard Model を指します。ここで設定できる価格エンジンは、ISDA と MidPoint の2通りです。MidPointは、デフォールト時に発生する経過利息の支払い額の期待値の計算を、プレミアムキャッシュフローの支払期間の中間点で近似計算するものです。この設定では、デフォールト値として MidPoint が指定されているので、ISDA モデルを使いたい場合は、このような設定が必要になります。
  2. 542~568行目で、BootstrapHelper(SpreadCdsHelper)オブジェクトを作成。ここでは、6か月、1年、3年、5年、7年、10年の6種類の Pillar で作成。
  3. 567~574行目で、BootstrapHelper の配列を作成する(変数名 IsdaCdsHelpers)。
  4. そのBootstrapHelperの配列を使い、ISDA Standard Modelに則った、具体的なクレジットカーブを作成。ここでは、テンプレートクラスである
    PiecewiseDefaultCurve<SurvivalProbability, LogLinear,…>
    オブジェクトを作成。このカーブはテンプレート引数にある通り、Survival Probabilityの対数を線形補間してカーブを構築。この方法だと、Pillar間のhazard rateが一定になる(Piecewise constant)。

(3) 価格エンジンの構築 

583 行目で価格エンジン(IsdaCdsEngine)オブジェクトを作成。ただし、ここでは価格エンジンを作りっぱなしで終わっています。 

この価格エンジンのアルゴリズムは、ISDA Standard Model に準拠しています。Example02()でも、同様の価格エンジンを作成しましたが、その時は、価格エンジンのコンストラクターの引数を6種類渡していました。その内の3種類は、価格エンジンの設定になります。ただ、それらの設定はデフォールトの設定が為されているので、ここでは、そのデフォールト値を使うため、何の設定もしていません。なので、価格エンジンの最低限必要な部品である、イールドカーブ、クレジットカーブ、及び債権回収率の3種類の引数のみを、コンストラクターに渡しています。 

(4) カーブの画面出力 

(1)と(2)で作成したイールドカーブとクレジットカーブの、各Pillar時点における値を画面出力しています。既に述べた通り、クレジットカーブの Pillar 日付が 20日からずれています。理由はよく分かりませんが、実際に使う際は、注意して下さい。 

1.2.11.4.4 メイン関数 

607~630行目でメイン関数が定義されています。但し、その内容は、上記の3種類のローカル関数を呼び出しているだけです。なので解説は省略します。  

 

<ライセンス表示>

QuantLibのソースコードを使う場合は、ライセンス表示とDisclaimerの表示が義務付けられているので、添付します。   ライセンス

目次

Page Top に戻る

// // //