使用GPUarrayfun
用于蒙特卡罗模拟
这个例子展示了如何使用蒙特卡罗方法在GPU上计算金融期权的价格。
这个例子使用了三种简单类型的奇异期权,但你可以用类似的方式为更复杂的期权定价。在本例中,您将比较在CPU上运行蒙特卡罗模拟和使用的时间arrayfun
GPU。
股价演变
假设价格按照与无风险利率、股息收益率(如果有的话)和市场波动率相关的对数正态分布演变。此外,假设所有这些数量在期权的生命周期内保持固定。这些假设导致了价格的随机微分方程。
,
在哪里 股票价格, 为无风险利率, 是股票的年股息率, 是价格的波动,和 表示高斯白噪声过程。假设 是对数正态分布的,这个微分方程可以离散得到这个方程。
.
用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 < timetoexpiration time = time + sampleRate;漂移= (riskFreeRate -红利-波动率*波动率/2)*抽样率;扰动=波动率*平方根(sampleRate)*randn;价格=价格*exp(漂移+扰动);addpoints (h、时间、价格);结束网格在轴紧包含(“时间(年)”) ylabel (“股价(元)”)
CPU和GPU的时间执行
的simulateStockPrice
函数,在本例的末尾提供,它使用前一节中描述的离散微分方程模拟股票价格。
准备输入数据,以运行100,000个股票价格的蒙特卡罗模拟。
N = 100000;startStockPrices = stockPrice*ones(N,1);
在CPU上计时100,000次模拟。
if = 0 (N,1);为i = 1:N finalStockPricesCPU(i) = simulatstockprice (startStockPrices(i),...riskFreeRate、股息、波动,...timeToExpiry sampleRate);结束timeCPU = toc;
因为每个模拟给出了一个独立的期权价格估计,所以取平均值作为结果。
流(计算CPU上$%1.4f的平均价格在%1.3f秒内。\n,...意思是(finalStockPricesCPU) timeCPU);
计算CPU的平均价格为99.0857美元,用时2.206秒。
为了在GPU上运行模拟,在GPU上准备输入数据gpuArray
对象。
gpuStartStockPrices = gpuArray(startStockPrices);
当你打电话时arrayfun
以GPU数组和函数句柄作为输入,arrayfun
将指定的函数应用于数组的每个元素。这种行为意味着循环遍历每个起始股票价格是不必要的。的arrayfun
函数将一个基于元素的MATLAB®函数转换为自定义CUDA®内核,从而减少了执行操作的开销。
运行simulateStockPrice
函数使用arrayfun
并在GPU上进行100,000次模拟gputimeit
.
finalStockPricesGPU = arrayfun(@ simulatstockprice,...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美元。
将GPU上的蒙特卡罗模拟结果绘制成直方图。
直方图(finalStockPricesGPU, 100);包含(“股价(元)”) ylabel (“频率”网格)在
亚洲期权定价
使用基于期权有效期内股票价格的算术平均值的欧亚期权。的asianCallOption
函数通过在模拟过程中累积价格来计算平均价格。对于看涨期权,如果平均价格高于执行价格,函数就执行期权。支付就是平均价格和执行价格之间的差额。使用asianCallOption
,在本例末尾提供,以模拟亚洲看涨期权。
将期权的执行价格设定为95美元。
罢工= 95;
在CPU和GPU上进行100,000次模拟arrayfun
并展示结果。
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);
计算CPU的平均价格为8.6733美元,用时2.146秒。
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
并展示结果。
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);
计算CPU的平均价格为19.2456美元,用时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
并展示结果。
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 = [timeCPU/timeGPU timeAsianOptionCPU/timeAsianOptionGPU ....timeLookbackOptionCPU / timeLookbackOptionGPU timeBarrierOptionCPU / timeBarrierOptionGPU]
率=1×494.2557 94.6009 104.1725 97.5490
要使结果可视化,请绘制每个模拟的执行时间之比。
栏(分类([“股价”“亚洲看涨期权”“Lookback选项”“障碍选择”]),...比率)ylabel (CPU与GPU执行时间之比)
在本例中,在GPU上运行模拟arrayfun
比在CPU上运行模拟要快得多。
当您将本例中描述的技术应用于您自己的代码时,性能改进将很大程度上依赖于您的硬件和所运行的代码。
万博1manbetx支持功能
股票价格演化模拟函数
的simulateStockPrice
函数执行蒙特卡罗模拟来确定最终的股票价格。计算假设价格按照与无风险利率、股息收益率(如果有的话)和市场波动率相关的对数正态分布演变。
的simulateStockPrice
函数以初始股票价格、无风险利率、股息率、市场波动率、总时间窗口和样本率作为输入。
函数finalStockPrice = simulateStockPrice(价格,riskFreeRate,股息,波动性,T,dT) T = 0;而t < t t = t + dT;漂移= (riskFreeRate -红利-波动率*波动率/2)*dT;扰动=波动率*根号(dT)*randn;价格=价格。*exp(漂移+扰动);结束finalStockPrice =价格;结束
亚洲看涨期权功能
的asianCallOption
函数执行蒙特卡罗模拟来确定亚洲看涨期权价格。计算假设价格按照与无风险利率、股息收益率(如果有的话)和市场波动率相关的对数正态分布演变。该函数通过在模拟过程中累积价格来计算平均价格。对于看涨期权,如果平均价格高于执行价格,函数就执行期权。支付就是平均价格和执行价格之间的差额。
的asianCallOption
函数以初始股票价格、无风险利率、股息率、市场波动率、执行价格、总时间窗口和样本率作为输入。
函数optionPrice = asianCallOption(价格,风险自由率,股息,波动性,罢工,T,dT) T = 0;accumulativeprice = 0;而t < t t = t + dT;dr = (riskFreeRate -股息-波动率*波动率/2)*dT;pert =波动率*√(dT)*randn;价格=价格*exp(dr + pert);cumulativePrice = cumativeprice +价格;结束numSteps = (T/dT);meanPrice = cumulativePrice/numSteps;以今天的货币表示最终价格。optionPrice = exp(- riskfreerate *T)*max(0,meanPrice - strike);结束
回看选项命令功能
的lookbackCallOption
函数执行蒙特卡罗模拟来确定欧式回溯期权,其支付是期权生命周期内最低股价与最终股价之间的差值。期权的执行价格是股票的最低价格。因为最终股票价格总是大于或等于最小值,期权总是被行权,并不是真正的“可选”。
的lookbackCallOption
函数以初始股票价格、无风险利率、股息率、市场波动率、总时间窗口和样本率作为输入。
函数optionPrice = lookbackCallOption(价格,riskFreeRate,股息,波动性,T,dT) T = 0;minPrice =价格;而t < t t = t + dT;dr = (riskFreeRate -股息-波动率*波动率/2)*dT;pert =波动率*√(dT)*randn;价格=价格*exp(dr + pert);如果minPrice =价格;结束结束以今天的货币表示最终价格。optionPrice = exp(- riskfreerate *T)*max(0,price - minPrice);结束
Barrier Option函数
的upAndOutCallOption
函数执行蒙特卡罗模拟来确定一个向上和向上的障碍看涨期权价格。如果股票价格低于障碍水平,该函数在正常的欧洲看涨期权计算中使用最终股票价格。
的upAndOutCallOption
函数以初始股票价格、无风险利率、股息率、市场波动率、执行价格、障碍价格、总时间窗口和样本率作为输入。
函数optionPrice = upAndOutCallOption(价格,风险freerate,股息,波动率,罢工,障碍,T,dT) T = 0;而(t < t) &&(价格<障碍)t = t + dT;dr = (riskFreeRate -股息-波动率*波动率/2)*dT;pert =波动率*√(dT)*randn;价格=价格*exp(dr + pert);结束如果价格<障碍在障碍之内,价格与欧式期权相同。optionPrice = exp(- riskfreerate *T)*max(0,价格-执行);其他的%达到障碍,期权被撤回optionPrice = 0;结束结束
另请参阅
相关的话题
- 测量和改进GPU性能
- 使用arrayfun提高基于元素的MATLAB函数在GPU上的性能
- 定价欧美价差期权(金融工具工具箱)
- 亚洲期权定价(金融工具工具箱)
- 使用不同股权模型定价欧洲看涨期权(金融工具工具箱)
- 万博1manbetx支持的权益导数函数(金融工具工具箱)