これはこのコードを書いた人が怠慢だった訳ではありません。Schemeクラスのベースクラスを作ってそこから派生させたとします。Strategyパターンのようなテクニックを使って多相性を持たせることになります。ところが、そうすると二律背反が発生します。Schemeインスタンスは価格エンジンの外から引数として渡す事になります。BoundaryConditionのインスタンスが必要ですが、それらは価格エンジンの中で生成されています。ユーザーに、価格エンジンの外でそれらを生成するコードを書かせるのは重複になるからです。すると、やはりSchemeインスタンスは価格エンジンの中で生成せざるを得ません。混乱しそうですね?この問題を解決するのに、2通りの方法が思いつきます。Factoryを使う事です。StepConditionを渡す方法です。(注:Factoryクラス群を作ることも出来たでしょうが、そうすると並行した階層構造が作られ、それは決していい事ではありません。Conditionオブジェクトを持たないようにする方法です。すると過去のバージョンとの互換性の問題から、FiniteDiffereneModelクラスを変更する事は出来ないので、新しいモデルクラスを作り直さなければなりません。いずれの方法も可能です。新しいフレームワークが導入された時に、それをレビューした者は、この問題に気付き、いずれかの対応策を提案すべきでした。そのレビューした者とは私でした。長く生きると、いろいろ学習するものです。FdmBackwardSolverクラスの説明が終われば、いよいよホームストレッチに入ってきます。Layer(訳注:ここでは各種部品を価格エンジンにつなぐ為の介在役のオブジェクトのこと)を加えて、(完成形の)Solverをより便利に使えるようにしています。新しいロジックが沢山加わった訳ではありません。注意深い読者なら、このセクションの説明方法は、新しいフレームワークの説明の最初に述べたトップダウンの方法から離れてしまった事に気づかれたでしょう。(ここではボトムアップの)この方法の方が、より合理的だと思います。FdmSolverDesc構造体は、(完成形の)Solverを初期化するのに必要な部品を一纏めにし、一体として渡せるようにしたものです。Operatorはその部品の中には含まれません。FdmSolverDescインスタンスを渡す事によって、そのSolverを別の商品でも再利用できるようにする為です。Solver回りの配管の面倒を見ます。};このコンストラクターは、引数として、1FdmSolverDescインスタンス、2FdmSchemeDescインスタンス、及び3Operatorインスタンスを取り、一旦メンバー変数に保持し、さらに、計算に使うその他のメンバー変数の値を事前に準備します。)メソッドを使って、初期値用の配列に正しいサイズを割当て、Calculator(オプションの行使価値を計算するオブジェクト)を使ってその値を埋めます。Mesherインスタンスから、指定したグリッド上の対象資産価格を取りだします。)メソッドの中に実装されています。このクラスはLazyObjectから派生してますが、それはおかしいです。(訳注:ここでの動作は、様々なオブジェクトによって、すでに用意されたアルゴリズムが、順番にスムーズに流れていく様にしている意味)。backしていき、4計算結果をメンバー変数に保持し、5それらを線形補間して一本の線に纏めます。Codeでも使えます。Listingには示していませんが。いくつかのインスペクター関数は、線形補間した曲線の1階と2階の微分の値、および時間軸に対する微分の値を取りだせます。LazyObjectの派生クラスにする必要があったのか見出せませんでした。Observerの派生クラス)。solverインスタンスは、通常価格エンジンでの計算の際に生成・使用され、計算が終わると捨てられます。)内の)すべての計算をコンストラクターに纏めてしまう事も出来たし、あるいはこのクラスを関数に置き換えて、線形補間された計算結果を返したり、それに対するインスペクター関数を作ったりして済ます事も出来たはずです。Fdm1DimSolverクラスには、姉妹クラスがあるのを述べておくべきでしょう。線形補間の結果を導出します。インターフェースは、殆ど同じで、次元が高くなっている分だけ違いが発生しています。Solverクラスについて説明します。示す、FdmBlackScholesSolverクラスがそれです。Handleを取ります。Handle(Observableに該当)に自らを(Observerとして)登録します。Solverを消去するより合理的でしょう。1DSolverを生成し、メンバー変数に保持します。Solverが持つ対応するメソッドに動作を委託します。)の計算を内部で行います。それらのインスペクター関数は、インターフェースの中で使われている対象資産の価格と、Processインスタンスの中で使われているその対数値との間で換算の動作も行います。SolverDescインスタンスを取りこむので、このSolverを別の商品の価格エンジンでも使えます。その場合は対象資産の価格が同じ確率過程を取る事が前提になります。Putオプションの価格計算に使われているのが判ります。境界条件を変える事によって、このSolverをバリアオプションでも使用できますし、実際に使われています。初期条件を変える事によって、デジタルオプションやその他の類似の商品でも使う事が出来ます。新しいフレームワークが、継承をベースとする古いフレームワークと比べて、より柔軟なデザインになっている事が判ると思います。少なくとも、柔軟性を持たせる為に、はるかに簡単なデザインになっています。Solverについては、説明を省略しますが、同じ様な動作で機能します。FdmHestonHullWhiteSolverクラスを見てください。諺にもある通り、これらのクラスがどうやってできたのか、もっとたくさんの話題があります。*********************************************************************************Solverの説明が終わったので、(有限差分モデルを使った)価格エンジンを構築するためのすべての部品が揃いました。そこで、このChapterを纏めます。有限差分モデルによる価格エンジンがどのように機能するか理解できるでしょう。Solverを使って(アルゴリズムを順番に走らせ)計算結果を取り出す事ができます。<ライセンス表示>QuantLibのソースコードを使う場合は、ライセンス表示とDisclaimerの表示が義務付けられているので、添付します。