文档

使用GPU ARRAYFUN的蒙特卡罗模拟

这个例子说明了如何对金融期权价格可以使用蒙特卡洛方法GPU进行计算。三个简单的类型奇异期权被用作例子,但更复杂的选项可以以类似的方式来定价。

这个例子是一个函数,这样的帮手可以被嵌套在它里面。

函数paralleldemo_gpu_optionpricing

本例使用长时间运行的内核,所以不能运行,如果在GPU上可以超时内核执行。超时通常只有有源如果所选择的GPU也驱动显示器。

dev = gpuDevice ();如果dev.KernelExecutionTimeout错误(“pctexample: gpuoptionpricing: KernelTimeout”...[“这个例子不能运行,如果在GPU上的CAN内核执行”...'超时。']);结束

股票价格演变

我们假设价格按照与无风险利率、股息率(如果有的话)和市场波动性相关的对数正态分布发展。假设所有这些数量在期权的有效期内都是固定的。由此得到价格的随机微分方程:

哪里是股票价格,为无风险利率,为股票的年股息率,是价格的波动和表示高斯白噪声过程。假如说是数正态分布,这可以离散化:

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

上涨空间= 100;%股票价格起价100美元。红利= 0.01;% 1%的年股息收益率。riskFreeRate = 0.005;% 0.5%。timeToExpiry = 2;在多年的选项%寿命。采样率= 1/250;假设%,每年250个工作日。波动率= 0.20;% 20%波动。

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

种子= 1234;RNG(种子);%重置CPU随机数生成器。parallel.gpu。RNG(种子);%重置GPU随机数发生器。

现在,我们可以循环一段时间来模拟股票价格的路径:

价格= stockPrice;时间= 0;保持;时间< timeToExpiry时间=时间+取样量;漂移=(风险-红利-波动率*波动率/2)*样本;扰动=波动性*sqrt(采样)*randn();价格=价格*exp(漂移+扰动);情节(时间、价格、'');结束;格;xlabel(的时间(年));ylabel(的股票价格($));

在GPU上运行

要在GPU上运行的股价模拟,我们首先需要把仿真循环辅助函数里面:

函数(S,r,d,v,T,dT)t < t = t + dT;dr = (r - d - v*v/2)*dT;pert = v*sqrt(dT)*randn();S = S * EXP(DR + PERT);结束finalStockPrice = S;结束

我们可以称之为数千次使用arrayfun。为了确保计算发生在我们所做的投入价格每仿真一个元素的GPU向量的GPU。为了准确地衡量我们使用GPU的计算时间gputimeit功能。

%创建输入数据。N = 1000000;startStockPrices =上涨空间*的(N, 1“gpuArray”);%运行模拟。finalStockPrices = arrayfun(@simulateStockPrice,...startStockPrices,riskFreeRate,红利,波动性,...timeToExpiry sampleRate);meanFinalPrice =平均(finalStockPrices);%测量使用gputimeit GPU上的功能的执行时间。%这就要求我们存储| arrayfun |调用一个函数句柄。arrayfun(@ simulatestockprice,...startStockPrices,riskFreeRate,红利,波动性,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('平均价格为$%1.4F在%1.3F秒计算的。\ n'...meanFinalPrice timeTaken);clf;hist(finalStockPrices, 100);xlabel(的股票价格($)) ylabel (“频率”网格);
计算$ 98.9563均价0.283秒。

定价的亚式期权

举个例子,我们使用一种基于期权期内股票价格的算术平均值的欧亚期权。在模拟过程中,我们可以通过累计价格来计算平均价格。对于看涨期权,如果平均价格高于执行价,期权就会被执行,而支付金额是两者之间的差额:

函数期权价格= asianCallOption(S,R,d,V,X,T,dT)的t = 0时;cumulativePrice = 0;t < t = t + dT;dr = (r - d - v*v/2)*dT;pert = v*sqrt(dT)*randn();S = S * EXP(DR + PERT);cumulativePrice = cumulativePrice + S;结束numSteps = (T / dT);meanPrice =累计价格/ numSteps;用今天的货币表示最后的价格。optionPrice = exp(-r*T) * max(0, meanPrice - x);结束

我们再次使用GPU来运行数千条模拟路径arrayfun。每个模拟路径给出了期权价格的一个独立的估计,因此我们取均值作为我们的结果。

罢工= 95;%行使价为选项($)。optionPrices = arrayfun(@asianCallOption,...股票价格,风险自由,股息,波动率,罢工,...timeToExpiry sampleRate);meanOptionPrice =平均(optionPrices);%测量在GPU上的执行时间,并显示结果。functionToTime = @()arrayfun(@asianCallOption,...股票价格,风险自由,股息,波动率,罢工,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('平均价格为$%1.4F在%1.3F秒计算的。\ n'...meanOptionPrice timeTaken);
计算平均价格8.7210美元在0.287秒。

为回溯期权定价

在这个例子中,我们使用欧式的回溯期权,它的支付是期权生命期内最低股票价格和最终股票价格的差值。

函数期权价格= euroLookbackCallOption(S,R,d,V,T,dT)的t = 0时;minPrice = S;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)* MAX(0,S  -  minPrice);结束

请注意,在这种情况下,执行价期权的最低股价。因为最终的股票价格总是大于或等于最小,该选项总是行使,是不是真正的“可选”。

optionPrices = arrayfun(@euroLookbackCallOption,...startStockPrices,riskFreeRate,红利,波动性,...timeToExpiry sampleRate);meanOptionPrice =平均(optionPrices);%测量在GPU上的执行时间,并显示结果。functionToTime = @ arrayfun(@ eurolookbackcalloption)...startStockPrices,riskFreeRate,红利,波动性,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('平均价格为$%1.4F在%1.3F秒计算的。\ n'...meanOptionPrice timeTaken);
计算平均价格$19.2711在0.286秒。

为障碍期权定价

最后一个例子使用,如果股票价格没有到达屏障水平,这是无效的“起来了”障碍期权。如果股票价格保持低于势垒高度则最终股价在正常的欧式看涨期权计算中使用。

函数期权价格= upAndOutCallOption(S,R,d,V,X,B,T,dT)的t = 0时;(T 结束如果S < b%在障碍内,因此价格为欧洲期权。期权价格= EXP(-r * T)* MAX(0,S  -  x)的;其他的%遇到障碍,因此期权被撤回。optionPrice = 0;结束结束

请注意,我们现在必须为选项,并在其成为无效的屏障价格同时提供一个行使价:

罢工= 95;%行使价为选项($)。屏障= 150;%的关口价位的选项($)。optionPrices = arrayfun(@upAndOutCallOption,...startStockPrices,riskFreeRate,红利,波动性,...罢工,屏障,...timeToExpiry sampleRate);meanOptionPrice =平均(optionPrices);%测量在GPU上的执行时间,并显示结果。functionToTime = @ arrayfun(@ upandoutcalloption,...startStockPrices,riskFreeRate,红利,波动性,...罢工,屏障,...timeToExpiry sampleRate);timeTaken = gputimeit (functionToTime);流('平均价格为$%1.4F在%1.3F秒计算的。\ n'...meanOptionPrice timeTaken);
计算$ 6.8166均价0.289秒。
结束
这个话题有用吗?