はじめにこのExampleでは、一般的な債券の、価格、利回り、経過利息などを計算します。Return)を使うのが一般的です。内部収益率は、金利の期間構造を考慮しませんが、逆に1個の値で利回りを表現できるので、期間の異なる債券の利回りを比較するのには便利です。債券利回りからの価格計算も、市場慣行ではイールドカーブの構築を必要としないので、はるかに簡単です。このExampleでは、債券価格を、イールドカーブを構築して、期間構造も勘案した上で計算しています。そもそも債券では、始めに市場価格ありきで、その市場価格データからイールドカーブを構築するので、前後が逆の様にみえます。デリバティブズが付随した仕組債券などは、イールドカーブと、価格モデルを使って価格計算を行う必要があります。この例を使って、ベンチマーク債券の市場価格からイールドカーブを構築する方法と、一般的な債券オブジェクトの構築方法、さらに価格エンジンを設定して価格計算する方法を見ていきたいと思います。参考の為に、債券の市場価格から、市場慣行による利回り計算や、経過利息計算も行っています。Engine(価格エンジン)を構築し、両者を組みあせて、価格計算を行います。価格計算にイールドカーブを使うので、その構築にテストコード全体の半分以上を費やしています。債券価格の計算に、イールドカーブを使うケースは、債券にデリバティブズが組み込まれた仕組み証券などで想定されます。Engineが必要になります。Factorを導出し、キャッシュフローの現在価値を計算しているだけです。Engineを使った、コールオプション付き債券の価格計算は、次のCallableBondsのExampleで解説します。ソースコードのコンパイルと実行これまでの2例と同様、まずExampleのソースコードをビルドし、実行可能なバイナリーファイルを生成します。QuantLibのインストール方法を解説したセクションですでにビルドしていれば、再ビルドは必要ありません。ビルドが済んでいない場合は、次の手順で、Debugモードでビルドし、試しに実行してみて下さい。ダブルクリックし開ける。起動され、このプロジェクトファイルが開かれます。約590行あるソースコードが開かれます。動作するか、まず確認してみます。メニューバーからビルド→ソリューションのビルドを選択。ビルドが開始されます。ビルド済みであれば、この操作は必要ありません。エラー無くビルドが正常終了すれば、試しにプログラムを走らせてみます。メニューバーのデバック→デバックの開始を選択。Console画面が出力されれば成功です。選択し、「デバックの停止時に自動的にコンソールを閉じる」のチェックボックスをはずします。クーポンレート、次回クーポンレート、最終利回り、を計算し出力しています。最後に変動金利債の価格と利回りを、期間構造を考えない市場慣行に則った方法でも計算しています。>まず、ソースコード全体を俯瞰してみます。Bonds.cppのプログラムコードは、全体で約590行あります。その内、約300行を、イールドカーブの構築に使っています。最初にも述べましたが、一般的な債券の利回り計算は内部収益率を使うので、特にイールドカーブを必要としません。Engineとイールドカーブが必要になります。ここで構築されるイールドカーブは、ベンチマーク債券の価格から構築されるものと、LIBOR-Swapカーブの2種類です。前者は、債券キャッシュフローの現在価値(すなわち債券価格)計算に使われ、後者は変動利付債のクーポン額の予想に使われています。債券は、ゼロクーポン債、固定金利債、および変動利付債の3種類の商品オブジェクトを構築しています。価格エンジンは、債券イールドカーブを引数として、DiscountingBondEngineクラスのインスタンスを生成し、それを3種類の商品オブジェクトに設定しています。後は、価格エンジンを走らせるだけです。前の2つの例(EquityOptionとSwap)と同じように、商品オブジェクトのメソッドであるNPV()を呼び出せば、価格計算が出来ます。債券の商品オブジェクトでは、NPV()以外に、cleanPrice()、dirtyPrice()、accruedAmount()メソッドも用意されており、それぞれ”経過利子を含まない価格”、”経過利子を含む価格”、”経過利息”を計算し出力します。いずれも、債券の額面に対する%表示で返されます。yield()メソッドは、市場価格をもとに、内部収益率を債券のクーポン支払い回数に対応した複利表示返します。>では、プログラムコードを手前から解説していきます。囲んでおり、例外処理が発生した場合の対応をしています。boost::timerのセットこれまでの例と同じです。上のConsole画面出力にある通り、今回のテストプログラムの計算時間は2秒でした。イールドカーブを2種類構築しているので、計算時間の大半はこの部分と推察します。資金グロス決済システムの事で、このシステムがオープンしている日を営業日とするカレンダーです。fixingDays=3、settlementDays=3という変数を設定しています。変動金利の決定日から対象金利期間のスタート日までの日数です。債券の取引日から決済日までの日数です。ここで指定している数字は、実際の取引慣行と異なっていますが、あくまでテストなので気にしないでいいでしょう。債券の価格計算は、実務慣行では通常、決済日を規準にしています。情報から、価格計算基準日を求めます。デリバティブズの価格計算の基準日が、通常"本日"なので、それと異なる日になる事に注意が必要です。イールドカーブの構築90行目から、イールドカーブの構築です。2種類のカーブを構築しています。イールドカーブの構築方法は、既にMulticurveBootstrappingの例で詳しく説明しました。再度簡単に説明すると、まずイールドカーブを構築する部品を生成します。市場データを格納するSimpleQuoteオブジェクトから始まり、それを使ってRateHelperオブジェクトを生成し、さらにその配列を使ってYieldTermStructureオブジェクトを構築します。RateHelperの役割や、市場データの更新に対応するObserverパターンの仕組みについては、MulticurveBootstrappingのセクションで再度確認して下さい。債券の価格評価に使うイールドカーブは、同質の債券のベンチマーク商品から構築する必要があります。この例では、ベンチマーク商品として、短期ゾーンは割引債を使い、中長期ゾーンはクーポン債を使っています。それぞれ商品性が異なるので、それに合わせたRateHelperクラスが使われています。'RateHelper'オブジェクトを生成しています。'SimpleQuote'に格納し、それを使って'DepositRateHelper'オブジェクトを生成してます。次に、131から195行目で、中長期ゾーンの’クーポン債’に合わせたRateHelperオブジェクトを生成しています。債券のベンチマーク商品の市場データは、通常、利回りでは無く、価格で得られます。従って、RateHelperは、それに対応するものでなければなりません。ここでは、FixedRateBondHelperクラスが使われています。このクラスはBondHelperの派生クラスで、さらにBondHelperは、BootstrapHelperの派生クラスです。このように、QuantLibでは、ベンチマーク商品のタイプに合わせたRateHelperが用意されています。イールドカーブを、Bootstrapping+Interpolation法で構築する場合、使われるベンチマーク商品に合わせて、適当なクラスを組み合わせればいいだけです。用意されているこれらのクラスの継承関係の図を添付します。Manualから抜粋しました。)RateHelperクラスは、ベンチマーク商品の価格計算機能を提供しています。従って、その機能に必要な部品を使って組み立てられています。ここでは、FixedRateBondHelperインスタンスを5つ生成していますが、それぞれ市場価格(Quoteオブジェクト)と、対象となる固定金利債の条件(クーポンや償還日など)などを、コンストラクターに取り込んで組み立てています。RateHelperが揃ったところで、それをひとつに纏め、イールドカーブを構築します。配列を生成しています。RateHelperインスタンスを代入しています。使って、'bondDiscountingTermStructure'という名前のイールドカーブを生成しています。いうテンプレートクラスを使って生成されています。例で既に説明しました。Interpolationのアルゴリズムを使って、具体的なイールドカーブインスタンスの構築を、コンストラクターを起動するだけで済ませています。Flowの現在価値を計算する為のイールドカーブが完成しました。Curveの構築242~380行目までは、変動利付債の将来のクーポンキャッシュフローを予測する為に必要なイールドカーブを構築しています。内容は、前のMulticurveBootstrappingの例で説明したのと同じなので、省略します。RelinkableHandleオブジェクトを2つ生成しています。価格エンジンオブジェクトの主要部品であるイールドカーブについて、それが複数ある事を想定し、価格エンジン側で自由に取り換えが出来る様な仕組みを提供しています。部品が揃ったので、価格エンジンと商品オブジェクトが生成できます。行目で、DiscountingBondEngineクラスのインスタンスを生成しています。取りだし、それを使って商品のキャッシュフローを現在価値に換算するだけです。コンストラクターは、イールドカーブオブジェクトを取り込んでいます。これで価格エンジンが完成しました。次に商品オブジェクトを生成し、そこに価格エンジンを設定します。この例では、3種類の債券オブジェクトを生成しています。ゼロクーポン債の生成400行目で、ゼロクーポン債を生成しています。持つ商品なので、部品を事前に作っておく必要がなく、コンストラクターに必要な情報を直接渡して完成です。409行目で、先ほど生成した価格エンジンを設定しています。次に固定金利債を生成しています。固定金利債は、固定金利のクーポンキャッシュフローを持ちます。従って、このオブジェクトを作るには、クーポン支払日の配列から作る必要があります。そこで、412行目でScheduleオブジェクトを生成しています。この部品は、クーポン支払日の配列を、指定された取引慣行に従って、自動的に生成するオブジェクトです。このオブジェクトを生成するコンストラクターを見て下さい。米国国債の取引慣行に従ってScheduleを生成していますが、その為に引数として次の様な情報を指定しています。false);引数を個別に見ていきます。クーポン支払回数については、特に注意する点はありません。カレンダーについては、米国政府債用のカレンダーが指定されています。このカレンダーは、FRBの決済システム(FED-Wire)がオープンしている営業日を指定しています。専用のカレンダーがある意味は、米国政府債が取引できる営業日が、必ずしも米国の株式市場の営業日と一致しない為です。クーポン日と償還日の休日の取扱いは、いずれも’Unadjusted’で指定されています。米国国債のクーポン日や償還日が休日と重なった場合、実際に支払われるのは翌営業日です。その場合でも、遅れた日数分のクーポン額の調整は行われません。これは、償還日を基準に、年2回払いなので、半年毎に遡ってクーポン日を決めていきます。これはクーポン日・償還日が月末の場合、前営業日に戻るのではなく、翌月の最初に営業日になる事を意味します。最後の2つの引数については、デフォールト設定を使っているので、Exampleのコード中のコンストラクターでは省略されています。米国国債の期間が、仮に5年2カ月といった端数年の期間であった場合、最初、あるいは最後のクーポン期間だけ6カ月より長かったり短かったりします。いた場合のクーポン日を指定します。この例は、そういうケースに該当しないのでNull設定になっています。米国債では最近、端数の期間で発行される銘柄を殆ど見ないので、あまり馴染みのない取引慣行かと思います。以上が、Scheduleオブジェクトを生成する為に必要な情報です。これらの情報は、商品や市場によって様々です。金融商品のオブジェクトを生成するには、コンストラクターでこういった取引慣行を設定する必要があり、どの様なバリエーションがあるか理解していなければなりません。そのバリエーションは多様であり、実務で金融商品のトレーディングやリスク管理を行っている者にとって、ひとつの大きなハードルです。オブジェクトと、必要な追加情報をコンストラクターに渡して、固定金利債のオブジェクトを生成しています。部品さえ用意されていれば、商品オブジェクトの生成は、このように簡単です。426行目で、このオブジェクトに価格エンジンを設定しています。この例では、'Schedule'オブジェクトを、ひとつの部品として、事前に作っておいて、後で、'FixedRateBond'オブジェクトのコンストラクターに渡しています。実は、FixedRateBondクラスのコンストラクターには、別の方法も用意されています。コンストラクターに渡して、そのコンストラクターの中で作ってしまうものです。そのコンストラクターのコードを"fixedratebond.cpp"ファイルから抜粋したものを下記します。コンストラクターの中で、Scheduleオブジェクトを生成しているのが、分かると思います。Scheduleオブジェクトを生成するのに必要な情報・部品は、FixedRateBondのコンストラクターの引数や、そのコンストラクターの中で生成される変数を使って用意されています。}さて、せっかく具体的な金融商品オブジェクトのコンストラクターの中身を示したので、その組み立て作業の中で、Schedule以外にもうひとつ重要な部分を説明したいと思います。その金融商品の具体的なキャッシュフローを生成する部分です。基礎編の冒頭で、すべての金融商品はキャッシュフローの集合であると述べました。特定する事と言えます。今説明した、Scheduleオブジェクトは、その'正確な日付'を特定する為の部品です。以下に説明するCouponオブジェクト(と、その配列であるLegオブジェクト)は、キャッシュフローの'正確な額'を計算する為に必要になります。