期权的蒙特卡洛法估值的一般步骤是
1,生成大量标的价格路径,这一步是通用的,对所有的期权都是一样的
2,根据价格路径计算到期日期权的价值,这一步根据期权类型的不同
3,求所有路径下期权价值贴现的期望。这一步也是通用的
numba支持核函数中生成随机数,也支持cuda原子操作,所以在核函数中有可能实现所有步骤,用回望期权测试一下:
import numpy as np
import cupy as cp
from scipy.stats import qmc
from scipy.stats import norm
from numba import cuda
from numba.cuda.random import xoroshiro128p_uniform_float32,create_xoroshiro128p_states
import math@cuda.jit()
def KernelLookBack(mean,payoff,rng_states,S0,K,T,r,q,sigma,steps,N):n = cuda.grid(1)if(n>=N):return dt = T / stepsmaxprice=0S=S0for i in range(0,steps):z=xoroshiro128p_uniform_float32(rng_states, n)S=S*math.exp((r - q - 0.5 * sigma**2) * dt + sigma * math.sqrt(dt) * z)if maxprice < S:maxprice=Spayoff[n]=max(maxprice-K,0)* math.exp(-r * T)cuda.atomic.add(mean,0,payoff[n]/N)S = 100 #stock price
T = 1/2 # time to maturity
r = 0.05 # risk free
q = 0.02 # dividend rate
sigma = 0.25 # volatility
steps = 100 # time steps
N = 100*1000#*1000 # number of trialsthreadsperblock=512
blockspergrid=math.ceil(N/threadsperblock)
payoffs=cp.zeros(N,dtype=cp.float32)
rng_states = create_xoroshiro128p_states(threadsperblock * blockspergrid, seed=1)
mean=cp.zeros(1,dtype=cp.float32)
KernelLookBack[blockspergrid, threadsperblock](mean,payoffs,rng_states,S,K,T,r,q,sigma,steps,N)
option_price=cp.mean(payoffs)
print("LookBack Option Price",option_price,mean[0])
经测试,随着路径增多,atomic.add加出来的结果和cupy.mean有细微的误差