< 目次

モンテカルロ法を使用したヨーロピアン・オプションの価格計算

目的

nsamp 個のサンプルを基にヨーロピアン・オプション (コールおよびプット) の価格 (nopt) を計算します。

解決方法

モンテカルロ・シミュレーションを使用してヨーロピアン・オプションの価格を計算します。コールオプションとプットオプションのペアは、次のように計算します。

  1. 初期化します。

  2. オプションの価格を並列に計算します。

  3. コール価格とプット価格のペアの計算をブロックに分割します。

  4. ブロックの計算を実行します。

  5. リソースを解放します。

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* セクションの初期化

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 0Wiener 過程dt は時間ステップで、S0 (t = 0 の株価) は X に依存しません。

予想値は、E(St) = S0 exp(rt) で定義され、r はリスク中立レートです。前述の St の定義から E(St) = S0 exp((μ + σ2/2)t)、μ = r - σ2/2 となります。

0 tT におけるヨーロピアン・オプションの値 V(t, St) は、株価 St に依存します。オプションは t = 0 に発行され、t = T (満了日) に行使されます。ヨーロピアン・オプション (コールおよびプット) の場合、満了日のオプション価格 V(T, ST) は次のように定義されます。

X権利行使価格です。ここでは、V(0, S0) を評価します。

モンテカルロ法を使用するこの問題の解は、STn 個の可能性をシミュレーションし、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 ) は、ブロック内のメモリーアクセス量に依存します。通常、ブロック内のすべてのメモリーアクセスがターゲット・プロセッサーのキャッシュに収まるように計算ブロックのサイズを選択します。