モンテカルロシミュレ,ションでのGPU arrayfunの使用
この例では,金融オプションの価格をモンテカルロ法を使用してgpuで計算する方法を示します。エキゾチックオプションの3つの単純なタイプを例として使用しますが,同様の方法でもっと複雑なオプションの価格を設定できます。
この例は関数であるため,補助関数をその内部に入れ子にすることができます。
函数paralleldemo_gpu_optionpricing
この例では実行に長時間かかるカーネルを使用するため,GPUでのカーネル実行がタイムアウト可能な場合は実行できません。タイムアウトが有効なのは,通常は,選択されたGPUがディスプレイの駆動も行っている場合に限られます。
dev = gpuDevice();如果dev.KernelExecutionTimeout错误(“pctexample: gpuoptionpricing: KernelTimeout”,...[如果GPU上的内核执行可以运行,则此示例无法运行,...“超时”。]);结束
株価の変化
ここでは,無リスク金利,配当利回り(該当する場合),市場の予想変動率に関連した対数正規分布に従って価格が変化するものと仮定します。こうした量はすべて,オプションの有効期間中は固定されていると仮定します。これによって,価格に関する次のような確率微分方程式が与えられます。
ここで,は株価,は無リスク金利,は株の年間配当利回り,は価格のボラティリティ,はガウスのホワ▪▪トノ▪▪ズ過程です。が対数正規分布であると仮定すると,これは次のように離散化できます。
例として,毎年1%の配当を生む$100の株を使用します。政府の基準貸し付け利率が0.5%であるとします。ほぼ毎日サンプリングした2年間の時間ウィンドウを調べます。市場の変動は,毎年20%であると仮定します。
股票价格= 100;股票价格从100美元开始。红利= 0.01;1%的年股息收益率。riskFreeRate = 0.005;% 0.5%。timeToExpiry = 2;%期权的生命周期,以年为单位。sampleRate = 1/250;假设每年250个工作日。波动率= 0.20;20%波动率。
乱数発生器をリセットして,結果が必ず繰り返されるようにします。
种子= 1234;Rng(种子);重置CPU随机数发生器。Gpurng(种子);重置GPU随机数发生器。
これで,長期にわたるル,プにより株価の変動経路をシミュレ,トできます。
价格=股票价格;时间= 0;持有在;而time < timetoexpiration time = time + sampleRate;漂移= (riskFreeRate -红利-波动率*波动率/2)*抽样率;扰动=波动率*平方根(sampleRate)*randn();价格=价格*exp(漂移+扰动);Plot(时间,价格,“。”);结束轴紧;网格在;包含(的时间(年));ylabel (“股价(美元)”);
Gpuでの実行
株価シミュレーションをGPUで実行するには,まずシミュレーションのループを補助関数内に配置する必要があります。
函数(S,r,d,v,T,dT) T = 0;而t < t t = t + dT;dr = (r - d - v*v/2)*dT;pert = v*sqrt(dT)*randn();S = S*exp(dr + pert);结束final股票价格= S;结束
これにより,arrayfun
を使用してこれを何千回も呼び出すことができます。計算がGPUで行われるように,入力価格は,シミュレーションごとに1つの要素をもつGPUベクトルにします。Gpuでの計算時間を正確に測定するために,関数gputimeit
を使用します。
创建输入数据。N = 1000000;startStockPrices = stockPrice*ones(N,1,“gpuArray”);运行模拟。finalStockPrices = arrayfun(@ simulatstockprice,...startStockPrices, riskFreeRate,股息,波动性,...timeToExpiry, sampleRate);meanFinalPrice = mean(finalStockPrices);%使用gputimeit测量函数在GPU上的执行时间。这要求我们将|arrayfun|调用存储在函数句柄中。functionToTime = @() arrayfun(@ simulatestockprice...startStockPrices, riskFreeRate,股息,波动性,...timeToExpiry, sampleRate);timeTaken = gputimeit(函数totime);流('在%1.3f秒内计算$%1.4f的平均价格。\n',...meanFinalPrice, timeTaken);clf;hist(finalStockPrices, 100);包含(“股价(美元)”) ylabel (“频率”网格)在;
计算平均价格98.9563美元,用时0.283秒。
アジアンオプションの価格
例として,オプションの有効期間における株価の算術平均を基に,ヨーロピアンタイプのアジアンオプションを使用します。シミュレ,ション中に価格を累積することで,平均価格を計算できます。コールオプションの場合,平均価格が行使価格を超えている場合にオプションが行使され,支払いは2つの価格間の差額となります。
函数optionPrice = asianCallOption(S,r,d,v,x,T,dT) T = 0;accumulativeprice = 0;而t < t t = t + dT;dr = (r - d - v*v/2)*dT;pert = v*sqrt(dT)*randn();S = S*exp(dr + pert);累计价格=累计价格+ S;结束numSteps = (T/dT);meanPrice = cumulativePrice / numSteps;以今天的货币表示最终价格。。optionPrice = exp(-r*T) * max(0, meanPrice - x);结束
ここでもgpuを使用して,arrayfun
により何千ものシミュレ,ションパスを実行します。各シミュレ,ションパスはオプション価格の独立した見積もりを与えるため,平均値を結果と見なします。
罢工= 95;%期权执行价格($)。optionPrices = arrayfun(@asianCallOption,...startStockPrices, riskFreeRate,股息,波动性,罢工,...timeToExpiry, sampleRate);meanOptionPrice = mean(optionPrices);测量GPU上的执行时间,并显示结果。functionToTime = @() arrayfun(@ asiancalloption,...startStockPrices, riskFreeRate,股息,波动性,罢工,...timeToExpiry, sampleRate);timeTaken = gputimeit(函数totime);流('在%1.3f秒内计算$%1.4f的平均价格。\n',...meanOptionPrice, timeTaken);
计算平均价格8.7210美元在0.287秒。
ルックバックオプションの価格
この例ではヨロピアンスタルのルックバックオプションを使用します。その支払いは,オプションの有効期間における最低株価と最終株価の差額になります。
函数optionPrice = euroLookbackCallOption(S,r,d,v,T,dT) T = 0;minPrice = S;而t < t t = t + dT;dr = (r - d - v*v/2)*dT;pert = v*sqrt(dT)*randn();S = S*exp(dr + pert);如果S结束结束以今天的货币表示最终价格。。optionPrice = exp(-r*T) * max(0, S - minPrice);结束
この場合,オプションの行使価格は最低株価であることに注意してください。最終株価は必ず最低株価以上となるため,オプションは常に行使され,本来の意味で”オプション”とは言えません。
optionPrices = arrayfun(@euroLookbackCallOption,...startStockPrices, riskFreeRate,股息,波动性,...timeToExpiry, sampleRate);meanOptionPrice = mean(optionPrices);测量GPU上的执行时间,并显示结果。functionToTime = @() arrayfun(@ eurolookbackcalloption,...startStockPrices, riskFreeRate,股息,波动性,...timeToExpiry, sampleRate);timeTaken = gputimeit(函数totime);流('在%1.3f秒内计算$%1.4f的平均价格。\n',...meanOptionPrice, timeTaken);
计算平均价格19.2711美元在0.286秒。
バリアオプションの価格
この最後の例では,株価がバリアレベルに到達すると無効になる”アップアンドアウト”バリアオプションを使用します。株価がバリアレベル未満に留まる場合は,最終株価が通常のヨーロピアンコールオプションの計算に使用されます。
函数optionPrice = upAndOutCallOption(S,r,d,v,x,b,T,dT) T = 0;而(t < t) && (S < b) t = t + dT;dr = (r - d - v*v/2)*dT;pert = v*sqrt(dT)*randn();S = S*exp(dr + pert);结束如果S < b在障碍之内,价格与欧式期权相同。。optionPrice = exp(-r*T) * max(0, S - x);其他的%达到障碍,期权被撤回。optionPrice = 0;结束结束
ここでは,オプションの行使価格とそれが無効となるバリア価格の両方を提供しなければならないことに注意してください。
罢工= 95;%期权执行价格($)。屏障= 150;%期权的障碍价格($)。optionPrices = arrayfun(@upAndOutCallOption,...startStockPrices, riskFreeRate,股息,波动性,...罢工,障碍,...timeToExpiry, sampleRate);meanOptionPrice = mean(optionPrices);测量GPU上的执行时间,并显示结果。functionToTime = @() arrayfun(@ upandoutcalloption,...startStockPrices, riskFreeRate,股息,波动性,...罢工,障碍,...timeToExpiry, sampleRate);timeTaken = gputimeit(函数totime);流('在%1.3f秒内计算$%1.4f的平均价格。\n',...meanOptionPrice, timeTaken);
计算平均价格$6.8166在0.289秒。
结束