主要内容

使用GPU ARRAYFUN进行蒙特卡罗模拟

本例显示了如何使用蒙特卡罗方法在GPU上计算金融期权的价格。本例使用了三种简单类型的奇异期权作为示例,但更复杂的期权可以以类似的方式定价。

此示例是一个函数,可以将助手嵌套在其中。

函数paralleldemo_gpu_optionpricing

此示例使用长时间运行的内核,因此如果GPU上的内核执行可能超时,则无法运行。通常,只有当所选GPU也在驱动显示器时,超时才处于活动状态。

dev = gpuDevice ();如果dev.KernelExecutionTimeout错误(“pctexample: gpuoptionpricing: KernelTimeout”,...['如果无法在GPU上执行内核,则无法运行此示例',...“超时”。]);终止

股票价格演变

我们假设价格的演化符合对数正态分布,与无风险利率、股息收益率(如果有的话)和市场波动性相关。假设所有这些数量在选项的生命周期内都是固定的。由此得到价格的随机微分方程如下:

$${\rm d}S=S\times
;\left[
;(r-d){\rm d}t+\sigma\epsilon\sqrt{{\rm d}t}
;\right]$$

哪里年代美元是股价,,r美元为无风险利率,$ d $是股票的年股息率,\σ美元是价格和价格的波动\ε美元表示高斯白噪声过程。假设$(S+\Delta S)/S$为对数正态分布,可离散为:

$$S{t+1}=S{t}\times\exp{
;\left[
;\left(r-d-\frac{1}{2}\sigma^2\right)\Delta t
;+\sigma\epsilon\sqrt{Delta t}
$$

举个例子,我们用100美元的股票每年1%的股息。中央政府利率假定为0.5%。我们检查了一个大致每天采样的两年时间窗口。市场波动性假定为每年20%。

上涨空间= 100;%股票价格100美元起。股息= 0.01;年股息率% 1%。riskFreeRate = 0.005;% 0.5%。timeToExpiry = 2;%期权的有效期(年)。采样器=1/250;%假设每年有250个工作日。波动率= 0.20;% 20%波动。

我们重置随机数生成器以确保结果的可重复性。

种子=1234;rng(种子);%重置CPU随机数生成器。gpurng(种子);%重置GPU随机数生成器。

现在,我们可以循环模拟股票价格的路径:

价格=股票价格;时间=0;持有;time < timeToExpiry time = time + sampleRate;漂移= (riskFreeRate - dividend - volatility*volatility/2)*sampleRate;扰动=波动性*sqrt(sampleRate)*randn();价格=价格*exp(漂移+扰动);情节(时间、价格、'.');终止网格;xlabel(的时间(年)); 伊拉贝尔(的股票价格($));

在GPU上运行

要在GPU上运行股票价格模拟,我们首先需要将模拟循环放入助手函数中:

函数finalStockPrice = simulateStockPrice(S,r,d,v,T,dT)t < t t = t + dT;dr = (r - d - v*v/2)*dT;pert = v*sqrt(dT)*randn();S = S*exp(dr + pert);终止最终股票价格=S;终止

我们可以调用它数千次arrayfun. 为了确保在GPU上进行计算,我们将输入价格作为GPU向量,每个模拟一个元素。为了准确测量GPU上的计算时间,我们使用gputimeit作用

%创建输入数据。N = 1000000;startStockPrices =上涨空间*的(N, 1“gpuArray”);%运行模拟。finalStockPrices=arrayfun(@SimulateStockPrices,...StartStockprice、无风险利率、股息、波动率、,...检验时间,取样器);平均最终价格=平均(最终库存价格);%使用gputimeit度量该功能在GPU上的执行时间。%这要求我们将| arrayfun |调用存储在函数句柄中。functionToTime = @() arrayfun(@ simulatestockprice,)...StartStockprice、无风险利率、股息、波动率、,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('以%1.3f秒计算出的$1.4f的平均价格。\n',...meanFinalPrice timeTaken);clf;hist(最终股票价格,100);包含(的股票价格($)) ylabel (“频率”网格);
0.283秒内计算的平均价格为98.9563美元。

亚洲期权定价

作为一个例子,让我们使用一个基于股票在期权生命期内价格的算术平均数的欧式亚洲期权。我们可以通过在模拟过程中对价格进行累加来计算平均价格。对于看涨期权,如果平均价格高于执行价格,则执行期权,而支付是两者之间的差额:

函数期权价格=亚洲期权(S,r,d,v,x,T,dT)T=0;累积价格=0;t终止numSteps = (T / dT);meanPrice = cumulativePrice / numSteps;用今天的货币表示最后的价格。optionPrice = exp(-r*T) * max(0, meanPrice - x);终止

同样,我们使用GPU运行数千条模拟路径使用arrayfun.每个模拟路径都给出了期权价格的独立估计,因此我们采用平均值作为结果。

罢工= 95;%期权的执行价格($)。optionPrices=arrayfun(@asianCallOption,...startStockPrices, riskFreeRate, dividend, volatility, strike,...平均期权价格=平均(期权价格);%测量GPU上的执行时间并显示结果。functionToTime=@()数组函数(@asianCallOption,...startStockPrices, riskFreeRate, dividend, volatility, strike,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('以%1.3f秒计算出的$1.4f的平均价格。\n',...meanOptionPrice timeTaken);
0.287秒内计算的平均价格为8.7210美元。

为回眸期权定价

对于这个例子,我们使用欧洲风格的回看期权,它的支付是期权生命周期内的最低股票价格和最终股票价格之间的差值。

函数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终止终止用今天的货币表示最后的价格。期权价格=exp(-r*T)*最大值(0,S-最小价格);终止

请注意,在这种情况下,期权的执行价格是最低股价。由于最终股价始终大于或等于最低股价,因此期权始终行使,并非真正的“可选”。

optionPrices = arrayfun(@ eurolookbackcallloption,...StartStockprice、无风险利率、股息、波动率、,...平均期权价格=平均(期权价格);%测量GPU上的执行时间并显示结果。@() arrayfun(@ eurolookbackcallloption,)...StartStockprice、无风险利率、股息、波动率、,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('以%1.3f秒计算出的$1.4f的平均价格。\n',...meanOptionPrice timeTaken);
0.286秒内计算的平均价格为19.2711美元。

障碍期权的定价

最后一个示例使用了一个“向上和向外”的障碍期权,如果股票价格达到障碍水平,该期权将无效。如果股票价格保持在障碍水平以下,则在正常的欧洲看涨期权计算中使用最终股票价格。

函数optionPrice = upAndOutCallOption(S,r,d,v,x,b,T,dT) T = 0;(t终止如果S < b在障碍范围内,所以价格就像欧洲期权一样。期权价格=exp(-r*T)*最大值(0,S-x);其他的%触及障碍,因此期权被撤回。optionPrice = 0;终止终止

请注意,我们现在必须提供期权的执行价格以及期权失效时的障碍价格:

罢工= 95;%期权的执行价格($)。屏障=150;%期权的障碍价格($)。optionPrices=arrayfun(@upAndOutCallOption,...StartStockprice、无风险利率、股息、波动率、,...打击,阻隔,,...平均期权价格=平均(期权价格);%测量GPU上的执行时间并显示结果。@() arrayfun(@ upandoutcallloption,)...StartStockprice、无风险利率、股息、波动率、,...打击,阻隔,,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('以%1.3f秒计算出的$1.4f的平均价格。\n',...meanOptionPrice timeTaken);
在0.289秒内计算出的平均价格为6.8166美元。
终止