主要内容

使用GPUarrayfun的蒙特卡罗模拟

这个例子展示了如何使用蒙特卡罗方法在GPU上计算金融期权的价格。

该示例使用了三种简单类型的奇异期权,但您可以用类似的方式为更复杂的期权定价。在本例中,比较在CPU上运行蒙特卡洛模拟和使用蒙特卡洛模拟所花费的时间arrayfun在GPU上。

股票价格演变

假设价格按照与无风险利率、股息收益率(如果有的话)和市场波动性相关的对数正态分布演化。此外,假设所有这些数量在期权的生命周期内保持固定。这些假设导致了价格的随机微分方程。

d 年代 年代 × r - d d t + σ ϵ d t

在哪里 年代 是股价, r 是无风险利率, d 是股票的年股息收益率, σ 是价格的波动,和 ϵ 表示高斯白噪声过程。假设 年代 + Δ 年代 / 年代 是对数正态分布的,这个微分方程可以离散得到这个方程。

年代 t + 1 年代 t × 经验值 r - d - 1 2 σ 2 Δ t + σ ϵ Δ t

假设持有100美元的股票,用两年的时间窗口来检验一下:

  • 这些股票每年的股息为1%。

  • 无风险政府利率为0.5%。

  • 价格每天抽样,每年250个工作日。

  • 市场波动率为每年20%。

上涨空间= 100;timeToExpiry = 2;股息= 0.01;riskFreeRate = 0.005;sampleRate = 1/250;波动率= 0.20;

为了保证可预测的结果,请设置CPU和GPU随机数生成器的种子。

种子= 1234;rng(种子);gpurng(种子);

模拟股价随时间变化的路径,并绘制结果图。

价格=上涨空间;时间= 0;h = animatedline(标志=“。”);time < timeToExpiry time = time + sampleRate;drift = (riskFreeRate -股息-波动率*波动率/2)*sampleRate;微扰= * sqrt (sampleRate) * randn波动;价格=价格*exp(漂移+扰动);addpoints (h、时间、价格);结束网格包含(“时间(年)”) ylabel (“股票价格(美元)”

图中包含一个axes对象。坐标轴对象包含一个animatedline类型的对象。

时间CPU和GPU的执行时间

simulateStockPrice函数在本例的最后提供,它使用前一节中描述的离散化微分方程模拟股票价格。

准备输入数据,以运行10万个股票价格的蒙特卡罗模拟。

N = 100000;startStockPrices =上涨空间*的(N - 1);

在CPU上进行100,000次模拟。

tic finalStockPricesCPU = 0 (N,1);i = 1:N finalStockPricesCPU(i) = simulatstockprice (startStockPrices(i),...riskFreeRate、股息、波动,...timeToExpiry sampleRate);结束timeCPU = toc;

因为每次模拟都给出了期权价格的独立估计,所以取平均值作为结果。

流(计算CPU上$%1.4f的平均价格在%1.3f秒内。\n...意思是(finalStockPricesCPU) timeCPU);
在2.206秒内计算出CPU的平均价格99.0857美元。

为了在GPU上运行仿真,需要在GPU上准备好输入数据gpuArray对象。

gpuStartStockPrices = gpuArray (startStockPrices);

当你打电话arrayfun使用GPU阵列和函数句柄作为输入,arrayfun将指定的函数应用于数组的每个元素。这种行为意味着没有必要遍历每个起始股价。的arrayfun函数在GPU上将一个基于元素的MATLAB®函数转换为自定义CUDA®内核,这减少了执行操作的开销。

运行simulateStockPrice函数使用arrayfun并在GPU上进行10万次模拟gputimeit

finalStockPricesGPU = arrayfun (@simulateStockPrice,...gpuStartStockPrices riskFreeRate,股息,波动,...timeToExpiry sampleRate);timeGPU = gputimeit(@() arrayfun(@ simulatestockprice,...gpuStartStockPrices riskFreeRate,股息,波动,...timeToExpiry sampleRate));流(计算GPU上$ 1.4f在%1.3f秒内的平均价格。\n...意思是(finalStockPricesGPU) timeGPU);
在0.023秒内计算出GPU上99.0442美元的平均价格。

在图形处理器上用直方图绘制蒙特卡洛模拟的结果。

直方图(finalStockPricesGPU, 100);包含(“股票价格(美元)”) ylabel (“频率”网格)

图中包含一个axes对象。axis对象包含一个直方图类型的对象。

亚洲期权定价

使用基于期权有效期内股价算术平均值的欧亚期权。的asianCallOption函数通过在模拟期间累积价格来计算平均价格。对于看涨期权,如果平均价格高于执行价格,则该函数执行期权。支付是平均价格和执行价格之间的差额。使用asianCallOption,在本例末尾提供,以模拟亚洲看涨期权。

将期权执行价格设为95美元。

罢工= 95;

在CPU和GPU上进行100,000次模拟arrayfun并展示结果。

tic optionPricesCPU = 0 (N,1);i=1:N optionPricesCPU(i) = asianCallOption(startStockPrices(i),...riskFreeRate、股息、波动性,罢工,...timeToExpiry sampleRate);结束timeAsianOptionCPU = toc;流(计算CPU上$%1.4f的平均价格在%1.3f秒内。\n...意思是(optionPricesCPU) timeAsianOptionCPU);
在2.146秒内计算CPU的平均价格为8.6733美元。
optionPricesGPU = arrayfun(@asianCallOption,...gpuStartStockPrices riskFreeRate,股息,波动性,罢工,...timeToExpiry sampleRate);timeAsianOptionGPU = gputimeit(@() arrayfun(@ asiancalloption,...gpuStartStockPrices riskFreeRate,股息,波动性,罢工,...timeToExpiry sampleRate));流(计算GPU上$ 1.4f在%1.3f秒内的平均价格。\n...意思是(optionPricesGPU) timeAsianOptionGPU);
在0.023秒内计算出GPU上8.7448美元的平均价格。

为回溯选项定价

使用欧式回溯期权,其股息为期权存续期内的最低股价与最终股价之差。期权的执行价格是最低股价。因为最终股价总是大于或等于最小值,期权总是被执行,并不是真正的可选。使用lookbackCallOption,在本例末尾提供,用于模拟欧式回看调用选项。

在CPU和GPU上进行100,000次模拟arrayfun并展示结果。

tic optionPricesCPU = 0 (N,1);i=1:N optionPricesCPU(i) = lookbackCallOption(startStockPrices(i),...riskFreeRate、股息、波动,...timeToExpiry sampleRate);结束timeLookbackOptionCPU = toc;流(计算CPU上$%1.4f的平均价格在%1.3f秒内。\n...意思是(optionPricesCPU) timeLookbackOptionCPU);
计算平均价格19.2456美元的CPU在2.201秒。
optionPricesGPU = arrayfun (@lookbackCallOption,...gpuStartStockPrices riskFreeRate,股息,波动,...timeToExpiry sampleRate);timeLookbackOptionGPU = gputimeit(@() arrayfun(@ lookbackcalloption,...gpuStartStockPrices riskFreeRate,股息,波动,...timeToExpiry sampleRate));流(计算GPU上$ 1.4f在%1.3f秒内的平均价格。\n...意思是(optionPricesGPU) timeLookbackOptionGPU);
在0.021秒内计算出GPU上19.3893美元的平均价格。

障碍期权定价

使用涨停障碍期权,如果股价达到障碍水平,该期权将失效。如果股价停留在障碍水平以下,在正常的欧洲看涨期权计算中使用最终股价。使用upAndOutCallOption函数,该函数在本例的末尾提供,用于模拟一个向上和向上的屏障调用选项。

设置期权的执行价格和期权失效的障碍价格。执行价为95美元,障碍价为150美元。

罢工= 95;障碍= 150;

在CPU和GPU上进行100,000次模拟arrayfun并展示结果。

tic optionPricesCPU = 0 (N,1);i=1:N optionPricesCPU(i) = upAndOutCallOption(startStockPrices(i),...riskFreeRate、股息、波动性,罢工,...障碍,timeToExpiry sampleRate);结束timeBarrierOptionCPU = toc;流(计算CPU上$%1.4f的平均价格在%1.3f秒内。\n...意思是(optionPricesCPU) timeBarrierOptionCPU);
在2.074秒内计算出CPU的平均价格6.8327美元。
optionPricesGPU = arrayfun (@upAndOutCallOption,...gpuStartStockPrices riskFreeRate,股息,波动性,罢工,...障碍,timeToExpiry sampleRate);timeBarrierOptionGPU = gputimeit(@() arrayfun(@ upandoutcalloption,...gpuStartStockPrices riskFreeRate,股息,波动性,罢工,...障碍,timeToExpiry sampleRate));流(计算GPU上$ 1.4f在%1.3f秒内的平均价格。\n...意思是(optionPricesGPU) timeBarrierOptionGPU);
在0.021秒内计算出GPU上6.7834美元的平均价格。

比较结果

计算每个模拟的CPU执行时间与GPU执行时间的比值。

ratio = [timcpu /timeGPU timeAsianOptionCPU/timeAsianOptionGPU ....timeLookbackOptionCPU / timeLookbackOptionGPU timeBarrierOptionCPU / timeBarrierOptionGPU]
率=1×494.2557 94.6009 104.1725 97.5490

为了可视化结果,绘制每个模拟的执行时间比率。

栏(分类([“股价”“亚洲看涨期权”“Lookback选项”“障碍选择”]),...比率)ylabel (CPU与GPU执行时间之比

图中包含一个axes对象。axes对象包含一个bar类型的对象。

在本例中,在GPU上运行模拟arrayfun比在CPU上运行模拟要快得多。

当您将本例中描述的技术应用到您自己的代码中时,性能改进将强烈地依赖于您的硬件和您运行的代码。

支持功能

股票价格演化模拟功能

simulateStockPrice函数执行蒙特卡罗模拟,以确定最终股票价格。该计算假设价格按照与无风险利率、股息收益率(如果有的话)和市场波动性相关的对数正态分布演进。

simulateStockPrice函数以初始股价、无风险利率、股息率、市场波动率、总时间窗和样本利率为输入。

函数finalStockPrice = simulatstockprice(价格,riskFreeRate,股息,波动性,T,dT) T = 0;t < t t = t + dT;drift = (riskFreeRate -红利-波动率*波动率/2)*dT;微扰= * sqrt (dT) * randn波动;价格=价格。* exp(漂流+微扰);结束finalStockPrice =价格;结束

亚洲呼叫期权功能

asianCallOption函数进行蒙特卡罗模拟,以确定亚洲看涨期权价格。该计算假设价格按照与无风险利率、股息收益率(如果有的话)和市场波动性相关的对数正态分布演进。该函数通过累积模拟期间的价格来计算平均价格。对于看涨期权,如果平均价格高于执行价格,则该函数执行期权。支付是平均价格和执行价格之间的差额。

asianCallOption函数以初始股价、无风险利率、股息率、市场波动率、执行价格、总时间窗和样本利率为输入。

函数optionPrice = asianCallOption(价格,riskFreeRate,股息,波动率,罢工,T,dT) T = 0;cumulativePrice = 0;t < t t = t + dT;dr = (riskFreeRate -红利-波动率*波动率/2)*dT;pert = * sqrt (dT) * randn波动;价格=价格*exp(dr + pert);cumulativePrice = cumulativePrice +价格;结束numSteps = (T / dT);meanPrice = cumulativePrice / numSteps;以今天的货币表示最终价格。optionPrice = exp(- riskfreerate *T)*max(0,meanPrice - strike);结束

Lookback选项功能

lookbackCallOption函数执行蒙特卡罗模拟,以确定一种欧式回望期权,其股息为期权生命周期内的最低股价与最终股价之差。期权的执行价格是最低股价。因为最终股价总是大于或等于最小值,期权总是被执行,并不是真正的“可选”。

lookbackCallOption函数以初始股价、无风险利率、股息率、市场波动率、总时间窗和样本利率为输入。

函数optionPrice = lookbackCallOption(价格,riskFreeRate,股息,波动率,T,dT) T = 0;minPrice =价格;t < t t = t + dT;dr = (riskFreeRate -红利-波动率*波动率/2)*dT;pert = * sqrt (dT) * randn波动;价格=价格*exp(dr + pert);如果价格< minPrice;结束结束以今天的货币表示最终价格。optionPrice = exp(- riskfreerate *T)*max(0,price - minPrice);结束

障碍选择功能

upAndOutCallOption函数执行蒙特卡罗模拟,以确定一个向上和向上的障碍看涨期权价格。如果股价保持在障碍水平以下,该函数在正常的欧洲看涨期权计算中使用最终股价。

upAndOutCallOption函数以初始股票价格、无风险利率、股息率、市场波动率、执行价格、障碍价格、总时间窗和样本利率为输入。

函数optionPrice = upAndOutCallOption(价格,riskFreeRate,股息,波动性,罢工,障碍,T,dT) T = 0;(t < t) &&(价格<障碍)t = t + dT;dr = (riskFreeRate -红利-波动率*波动率/2)*dT;pert = * sqrt (dT) * randn波动;价格=价格*exp(dr + pert);结束如果价格<障碍%在障碍内,价格与欧洲期权相同optionPrice = exp(- riskfreerate *T)*max(0,价格-执行);其他的击中障碍,因此期权被撤回。optionPrice = 0;结束结束

另请参阅

||

相关的话题

Baidu
map