Structure(期間構造)にフォーカスして説明してきました。QuantLibでは、当然ながら、その他の期間構造も取り扱っています。このセクションでは、それらについても簡単に説明したいと思いますが、主に、金利の期間構造と異なっている点、および、それらに特有の機能についてフォーカスしたいと思います。Structureは、金利の期間構造と最も類似性があります。)など、いくつかの表現方法があり、そのいずれからも他の表現方法が導出できます。Structureにおけるゼロ金利と割引率の関係とよく似ています。導出するような仕組みにしていません。)という2種類の抽象メソッドが(純粋仮想関数として)宣言されています。どちらのメソッドをベースにもう一方のメソッドを実装するかは、派生クラスに任されています。)メソッドを使って実装しています(下記例では、レンジのチェックやExtrapolationなどの部分を省略しているので、実際のコードはもっと複雑ですが)。)も同様に、単純にサバイバル確率とデフォールト強度から計算されています。3.14はアダプタークラスの概要を示しています。Structureを、サバイバル確率、デフォールト強度、あるいはハザード発生強度のいずれかひとつの指標を使って(それぞれの派生クラスを)作ります。使って実装されています。probabilityの微分を計算するとだけ記されています)。純粋仮想関数のままで置かれているので、さらに派生するクラスで内容を実装しなければなりません。2番目の派生クラスは、DefaultDensityStructureクラスで、正反対の方法でメソッドを定義しています。)を使って実装されています。残念ながら、いくつかのアダプターメソッドは、計算したい値を導出する為に、数値積分を使う必要があります。Libraryの中のboost::bind)を使っています。皆さん自身で派生クラスを実装する際、積分の解析解が求まるのであれば、それを使ってこのアダプターを書き換えて下さい。金利のTermStructureクラスと同じように、QuantLibではアダプターのインターフェースを実装するために、いくつかのテンプレートクラスを用意しています。default-probabilityのテンプレート、さらに原データを選択する為のTraitsクラスです。Traitsと組み合わせて、これらのテンプレートは次のようなインスタンスの生成ができます。PiecewiseDefaultCurve<DefaultDensity,Linear>実装方法は、すでに金利のPiecewiseYieldCurveクラスの所で説明したものと殆ど同じなので、あえて繰り返しません。Structureは、それだけではBootstrappingは出来ないという事です。そのためには、ディスカウントカーブも必要になります。(イールドカーブについて、Multi-Curve対応をする場合も、同様です。その場合は、商品の価格エンジンで使われるものと同じイールドカーブを使って下さい。Moneyでなくなる(MtMをすると即座に損益が発生する)ことになります。3.2)で議論したのと同じ、“対称性の破れ”に気付かれたと思います。ここでは若干の違いがあります。Structureの表現方法の中で)特別な地位をもっていました。Rate(訳注:デフォールト強度。不当な扱いを受けている義理の妹(シンデレラ)のような役割を負わされています。)メソッドは定義されていません。昔のバージョンのソースコードを見ていただけると分ると思いますが、対称性の為だけに、かつてはそのメソッドを定義していましたが、説明もせずに取り除いてしまいました。その頃は、その方が良いと考えていました。)が使えないので、ハザード発生強度を計算する為に、他のメソッドをぐるぐる巡らないといけません。デフォールト確率の実装を使ってデフォールト強度とサバイバル確率を計算(かつその過程で数値解析法による積分)しなければなりません。)を復活できなくなりました。Structureとはいくつかの点で特徴が異なります。当然ながら、そのような特徴の大部分は、クラスの構造を複雑にしています。Structureを(従って2つの異なったインターフェースを)持っている事です。QuantLibはInflationTermStructureという一種類のベースクラスを用意し、そこでいくつかのインスペクター関数と共通の動作を定義しています。3.15のような継承関係を形作っています。その2種類の派生クラスは、それぞれゼロクーポンレート(のように表現したインフレ率)と、前年比として表示されるインフレ率をオブジェクトモデル化したものです。この2つのインフレ率の表現方法は、お互いに他の表現方法に換算するのが難しく、これまで使った複合的なアダプターパターンを使えませんでした。};このようなプログラムの記述方法は、有利な点と不利な点がありますが、もしかしたら不利な点の方が多いかもしれません。このプログラムだと、一組の重複するサブクラスを生成することになり、これだと明らかにBugの原因になりやすい形です。(注:もっとひどくなるかもしれません。今までのところ、「年率」以外に特定の期間毎のインフレ率を考慮した事はありません。望むらくは、年率インフレ率が一般的な方法になってほしいです。)その一方で、サブクラスの構造を少し単純にできます。Structureは、原データの数値が一種類しかなく、アダプタークラスが必要ありません。その他の相違点は、インフレ率の決め方の特殊性に由来するものです。Dateという2種類の日付を持つ必要があります。Dateとは、直近のインフレ率のFixingの日に対応するものです。Dateより後の日であった場合、その数字はあくまで「予想」なります。Dateを基準にそこからスタートするとは限らないと述べた事を覚えておられるでしょうか?本例がそこで述べた例外的なケースです)。StructureはSeasonalityという多相的なクラスのインスタンスを保持するための仕組みを提供しています(Seasonalityクラスについては話を簡潔にするためここでは説明しません)。そのようなインスタンスが与えられると、Strategicパターンのシンプルなデザインによって、インフレ率の値に季節調整を加える仕組みが導入できます。Structureと異なり、インフレ率クラスのインターフェースは、日付ではなく、年数(Time)を引数で取る仕組みを持ち合わせていません。Dateまでの年数を計算するには日数計算のロジックに依存することになります。年数を受け取ってもそれを正確な日付に変換するロジックを構築する事が困難な為、その機能を持たせないようにしました。Curveを保持する事があります。これを読んでいる人と同じように、私自身も(その必要性を認識した時)顔をしかめました。そのタイミングはVersion1.0のLibraryのリリース直前でした。私の方が読者の方よりよっぽどしかめっ面な顔をしていたと思います。Structureだけ、そうする事にしました。Structureの中では取り入れていません。Curveを使って行えるという利点があります。似たようなカーブについて、すべて同じような構造にしなければならない訳ではありませんので。このまま数年使ってみた後、Version2.0のリリースの際には、より最適なデザインを選択したいと思います。終わり良ければすべて良しですから。少なくとも、私自身は、コードの見直しをもっと頻繁に行う事を肝に銘じました。Bootstrappingなど)は他の種類のカーブの所で説明したのとほぼ同様です。Yearベースで表示されるインフレ率が別々のサブクラスの継承関係を持つことから、2つほど相違点があります。)インターフェースを組みこんだAdapterクラスが存在していない事です。Quantityを選択するためのTraitsを使っていない事です。PiecewiseZeroInflation<Linear>といったようなデザインを自分自身で導入して下さい。Structureは、きわめて多様な構造を持つ為、そのすべてに共通な特徴を探すのは、プログラマーの能力の限界を試されます。3.16のVolatilityTermStructureの定義を参照)、役に立つような抽象化といえるかどうか自信がありません。};このクラスは、ベースクラスであるTermStructureに2つの機能を追加しています。)メソッドで、オプション行使日までの期間から、具体的な行使日を返します。インスタンス(この情報はコンストラクターに渡され、必要なInspectorメソッドで整合性チェックがなされます)を使います。Conventionすなわち営業日に関する取引慣行とは、1カ月とか1年後の期間の応答日が、たまたま休日であった場合、翌営業日と前営業日のどちらにするか決める取引慣行。この行使期間からオプション期日を計算する機能は、ユーティリティークラスにカプセル化し他のクラスでも使えるようにする、という方法もありました。Structureの範囲を決めるための、最低行使価格と最大行使価格の情報を返すものと、一種類のProtectedメソッドで、与えられたストライクがその最大値と最小値の範囲内に入っているかどうかチェックするものです。Structureでは意味を成しません。これらの機能を外してしまうと、さらに派生クラスを作って(おそらくImpliedVolStructureクラスといった名前になるでしょうが)それらの機能を盛り込む必要があるので、このままにしておいても問題ないと思います。Modelで使われている確率変数の対数正規分布を前提にしたボラティリティ)は、下記Listing3.17のように、BlackVolTermStructureクラスでオブジェクトモデル化しています。11に依拠して開発すればコンストラクターの継承機能により(派生クラスでの)定義が不要にできたでしょう)の他に、次のような機能を持つメソッドがオーバーロードされて定義されています。)を呼び出すことによって、実装されます。publicインターフェースは、レンジのチェック機能を提供しており、さらにフォワードボラティリティやフォワード分散の計算では、引数で渡される2つの日付に対応するフォワードの値をスポットの値から計算するロジックを提供しています。本書を書いている時点で、BlackVolTermStructureクラスは、privateで宣言されたstatic-constのメンバー変数dTを持っていますが、盲腸や退化した尾骨のように、実際には使用されていません。読者がこれを読まれている時点までにはそれ(私の盲腸ではなく、そのデータメンバー)を取り除いておきたいと考えています。)メソッドのいずれかを実装する為のアダプタークラスが用意されています。それらは下記のListing3.18を見てください。(いずれかの簡単な例としてLibraryの中にあるConstantBlackVolクラスや、誤解されやすい名前ですがImpliedVolTermStructureクラスを見てみてください。)残念ながらBlackVolatilityTermStructureという名前は、ベースクラスの名前と非常に混同しやすいものにしてしまいました。将来、Libraryをバージョンアップする際、適切なクラス名に変更したいと考えていますので、良いアイデアがあれば教えてください。Volatility行列(Strike軸と行使期間軸の行列)のInterpolationを行います。Structureクラスの例を説明してきたために、読者の方はもう十分だとお思いでしょうから、詳しい説明は行いませんが、2点ほど面白い機能があるので、そこだけ説明します。Structure(のインスタンス)を作成後に変更できるという事です。その為のメソッドは以下のようなものです。}この機能は、他のInterpolationを行ったカーブでは不可能です。本章の中で例を示したPiecewiseYieldCurveクラステンプレートのように、InterpolationのタイプはTemplateの引数となっており、このクラスのインスタンス生成時に固定されてしまうからです。)メソッド以外では、Interpolatorの型の情報を必要としないからです。Structureのレンジの外であった場合に使われるExtrapolationの方法をカスタマイズできるという点です。やり方は、Interpolation法を使って補外するか、またはカーブの端からVolatilityをフラットにして補外するか、選択できます。カーブの両端でそれぞれ別の補外方法も選択できます。Structureでも使えれば便利かもしれません。Extrapolation方法の選択の仕組みを、より一般的な方法で実装するには、次のようにすると良いでしょう。このような仕組みを取り込むためには、Extrapolatorクラスという様なものを定義するのも、ひとつの方法であったかと思います。この方法では、カーブの両端で異なったExtrapolationの方法を使う場合はうまくいきません。Surfaceの場合は、時間軸の他にストライク価格に沿ったカーブを持っており、こういった違いを知る余地がないからです。Extrapolatorを作ったとしても、カーブの両端の情報について区別する事が出来ない為、カーブの両端でどのような処理をするかというインターフェースを設計することが出来ないという事です。従って、上記のような実装方法を必要な場所でいちいち実装する選択肢しか無かったという訳です。プログラムの再利用の仕組みを無理に作るのであれば、多相性のあるExtrapolationクラスを作り、インターフェースの異なる派生クラスを作るという方法がありますが、その場合は、与えられたTermStructureクラスに、必要な数だけExtrapolationインスタンスを保持しておく必要があります。Structureの解説の最後のトピックは金利ボラティリティです。このクラスは3種類の階層構造を持っており、そのいずれもクセがあります。Structureをオブジェクトモデル化したものです。ベースクラスはCapFloorTermVolatilityStructureで、下記Listing3.19に定義を示します。};この定義の仕方は、これまでみてきたデザインパターンをそのまま使っています。一点だけ大きな違いは、ボラティリティは今日をスタートとしてみた行使日に対応するものでは無く、CapletsやFloorletsのシリーズ(すなわちCAP/FLOOR)の満期日に対応するものです。この差異により同じ単語が違う意味を持つことになります。メソッドは、他のボラティリティクラスの中の同じ名前のメソッドと、インターフェースは同じでも異なる意味を持ちます。その結果、インターフェースに2点ほど小さな差異をもたらしています。)メソッドに、引数としてCAP/FLOORの期間に相当する(自然数のデータ型である)Periodを取る、オーバーロードメソッドが追加されています。)メソッドは省かれています。(訳注:CAPのVolatilityは、複数のCapletsのVolatilityの平均のような意味なので、特定のCapletの確率分布を表すパラメータでは無い)2種類目の階層構造は、一本のCapletあるいはFloorletのボラティリティをモデル化したものです。StructureからCapletボラティリティを導出する事は可能ですが、ここではその方法について説明しません。その導出方法について興味があれば。QuantLibの中のOptionletStripperクラスとその派生クラスの中身を見てください。そのベースクラスはOptionletVolatilityStructureクラスで、下記Listing3.20に示しています。)は行使日に対応するVolatilityを返すようになっています。クラスの構造も、本来の形に戻っていますが、特筆すべき追加があります。)メソッドを持っています。Smileの形状をモデル化したSmileSectionオブジェクトを返します。そのベースクラスとなるSmileSectionクラスの定義は下記Listing3.21のとおりです。このクラスのインターフェースはボラティリティクラスのインターフェースに添って定義されており、特に説明はいらないと思います。一点だけ注意して欲しいのは、オプション期間は固定されており、引数として各メソッドに渡される必要はありません。Curveの配列という形で保持するという構成にしています。Structureにも再利用できるようになっています。一方で、完全にこの新しいインターフェースの方法に転換するほど勇気はありませんでした。Smileの集合として保持する方法)がベースクラスのCaplet-Volatilityクラスに依然として残っており、その結果いくつかの不都合な点が発生しています。)を使って下記のように実装できますが、これは最初にスマイルカーブをモデル化した場合にしかうまく行きません。Surfaceをモデル化した場合、この方法は新しいクラスを実装する上で非常に面倒くさい事になります。)を実装するのは簡単ではありません。)を呼び出せる必要があります。Surfaceが持つLifetime(訳注:おそらく各インスタンスのメモリーの割当を解放するタイミングの事)をリンクさせることになり、かえって様々な問題を引き起こしそうです。Surfaceクラスと同じコードを使う事になると思われます。)も一緒に削除する事になるでしょう。)メソッドを雑に実装すると、そのメソッドを呼び出すたびに新しいオブジェクトをメモリー上に生成する事になり、パフォーマンスに悪影響を及ぼします。高度な実装方法は、そのオブジェクトをキャッシュ(一時保存)する必要があるでしょうが、コードが複雑になるでしょう。SmileSectionクラスは興味深いアイデアと思いますが、その価値以上に問題を起こすかもしれません。Smileを直接モデル化するクラスの実装で使うに留めた方がいいかもしれません。OptionletVolatilityStructureクラスについての、最後の注意点です。)メソッドのオーバーロード関数を宣言しています。このメソッドはデフォールトの実装として、引数の日付を‘期間’に変換し、それを使って別のオーバーロード関数を呼び出しています。従って、新たな派生クラスのプログラムを書く際は、その関数をOverride(上書き)する必要はありません。派生クラスがその引数で取った日付を自らのメンバー変数に代入しておけば、正確性が向上します。Structureをモデル化しています。そのベースクラスはSwaptionVolatilityStructureクラスで、下記Listing3.22にその定義を示しています。)メソッド)と、さらにひつつの新しい仕組みを持っています。対象スワップの満期日という新しい次元を追加し、それをサポートする為の(対応する引数のレンジのチェックなどを行う)いくつかのメソッドを追加しています。Structureクラスの説明のすべてです。Libraryの中で、多くのプログラム例がありますので、その内容を理解するためにこの章を利用して下さい。<ライセンス表示>QuantLibのソースコードを使う場合は、ライセンス表示とDisclaimerの表示が義務付けられているので、添付します。