nsamp 個のサンプルを基にヨーロピアン・オプション (コールおよびプット) の価格 (nopt) を計算します。
モンテカルロ・シミュレーションを使用してヨーロピアン・オプションの価格を計算します。コールオプションとプットオプションのペアは、次のように計算します。
初期化します。
オプションの価格を並列に計算します。
コール価格とプット価格のペアの計算をブロックに分割します。
ブロックの計算を実行します。
リソースを解放します。
macOS* でこのソリューションを利用するには、oneMKL 11.2 Update 3 以上が必要です。
ソースコード: サンプル (https://www.intel.com/content/dam/develop/external/us/en/documents/mkl-cookbook-samples-120115.zip (英語)) の mc フォルダーを参照してください。GitHub の monte_carlo_european_opt (英語) も参照してください。
OpenMP* 並列セクションを作成し、MT2203 乱数ジェネレーターを初期化します。
#pragma omp parallel
{
...
VSLStreamStatePtr stream;
j = omp_get_thread_num();
/* RNG を初期化 */
vslNewStream( &stream, VSL_BRNG_MT2203 + j, SEED );
...
}
この初期化モデルは、各スレッドで個別の乱数ストリームを生成します。
利用可能なスレッドにオプションを分配します。
#pragma omp parallel
{
...
/* オプションの価格付け */
#pragma omp for
for(i=0;i<nopt;i++) {
MonteCarloEuroOptKernel( ... );
}
...
}
パスの生成をブロックに分割し、データの局所性を保持してパフォーマンスを最適化します。
const int nbuf = 1024;
nblocks = nsamp/nbuf;
...
/* ブロックの計算 */
for ( i = 0; i < nblocks; i++ ) {
/* 末尾が正しく計算されることを保証 */
int block_size = (i != nblocks-1)?(nbuf):(nsamp - (nblocks-1)*nbuf);
...
}
メインの計算で、乱数を生成し、リダクションを実行します。
/* ブロックの計算 */
for ( i = 0; i < nblocks; i++ ) {
...
/* 乱数のブロックを生成 */
vdRngLognormal( VSL_RNG_METHOD_LOGNORMAL_ICDF, stream, block_size, rn, a, nu, 0.0, 1.0 );
/* リダクション */
#pragma vector aligned
#pragma simd
for ( j=0; j<block_size; j++ ) {
st = s0*rn[j];
vc = MAX( st-x, 0.0 );
vp = MAX( x-st, 0.0 );
sc += vc; sp += vp;
}
}
*vcall = sc/nsamp * exp(-r*t);
*vput = sp/nsamp * exp(-r*t);
RNG ストリームを削除します。
#pragma omp parallel
{
...
VSLStreamStatePtr stream;
...
/* RNG を削除 */
vslDeleteStream( &stream );
}
タスク |
ルーチン |
---|---|
ランダムストリームを作成して初期化する |
vslNewStream |
対数正規型に分布している乱数を生成する |
vdRngLogNormal |
ランダムストリームを削除する |
vslDeleteStream |
モンテカルロ・シミュレーションは、ランダム・サンプリングを繰り返すことでモデルの特性を決定する、広く使用されている手法です。モンテカルロ・シミュレーションによるヨーロピアン・オプションの価格付けは、簡単な金融ベンチマークであり、モンテカルロ・シミュレーションを使用する実際のアプリケーションの取り掛かりとして利用できます。
St は、次の確率過程が適用される t 時点の株価とします。
dSt = μStdt + σStdWt, S0
ここで、μ は ドリフト、σ は ボラティリティー (定数と仮定)、W = (Wt)t≥ 0 は Wiener 過程、dt は時間ステップで、S0 (t = 0 の株価) は X に依存しません。
予想値は、E(St) = S0 exp(rt) で定義され、r はリスク中立レートです。前述の St の定義から E(St) = S0 exp((μ + σ2/2)t)、μ = r - σ2/2 となります。
0 ≤t≤T におけるヨーロピアン・オプションの値 V(t, St) は、株価 St に依存します。オプションは t = 0 に発行され、t = T (満了日) に行使されます。ヨーロピアン・オプション (コールおよびプット) の場合、満了日のオプション価格 V(T, ST) は次のように定義されます。
コールオプション: V(T, ST) = max(ST - X, 0)
プットオプション: V(T, ST) = max(X - ST, 0)
X は権利行使価格です。ここでは、V(0, S0) を評価します。
モンテカルロ法を使用するこの問題の解は、ST の n 個の可能性をシミュレーションし、V(T, ST) の平均を係数 exp(-rt) で割り引いて、オプションの現在の価格 V(0, S0) を取得します。最初の式から ST は対数正規型に分布しています。
ξ は標準正規分布の確率変数です。
oneMKL の基本乱数ジェネレーターは (BRNG) は、さまざまなパラメーター・セット、ブロック分割、リープフロッギングの使用など、多様な並列計算モデルをサポートします。
この例は、6024 種類のパラメーター・セットをサポートする MT2203 BRNG を使用します。ストリームの初期化関数で、j を BRNG 識別子 VSL_BRNG_MT2203 に加えて、パラメーター・セットを選択します。
vslNewStream( &stream, VSL_BRNG_MT2203 + j, SEED );
oneMKL の VS BRNG 実装でサポートされる並列モデルについては、「Intel® MKL Vector Statistics Notes」を参照してください。
計算ブロックのサイズ (この例では 1024 ) は、ブロック内のメモリーアクセス量に依存します。通常、ブロック内のすべてのメモリーアクセスがターゲット・プロセッサーのキャッシュに収まるように計算ブロックのサイズを選択します。