我正在编写一个能够为一揽子期权定价的程序。 总结解决问题的关键是绘制许多〜70'000'000的随机变量,并对它们进行某些计算。现在,我将随机样本绘制在尺寸为(10,100000 ),然后重复执行700左右的步骤,以获得一个不错的近似值。总的计算时间约为99秒。
用 cProfile 对代码进行性能分析后,我意识到 51%的计算时间都花在绘制那些随机样本上,这是我使用{{1} } [d = 10,N = 100000]。
np.random.normal
因此,我的问题与询问您是否有一种更有效的方法来抽取我的随机样本。
非常感谢您的帮助:)
附录 (我使用的代码+总体cProfile,可能对感兴趣的读者有帮助):
没有初步定义的代码:
def getZ(h_n):
# Get A Matrix (d,N) consisting of Gaussian N(0,h_n) Variables
return np.random.normal(0, h_n, (d, N))
cProfile输出:
"""Implementation of Approximation"""
"Construct Covariance Matrix and Decomposition"
# Create Matrix Eta which is the matrix of Covariances
Eta = np.eye(d) + rho * (np.ones(d) - np.eye(d))
# Use the Cholesky Decomposition to derive L, which has the value that Eta = L*L'
L = np.linalg.cholesky(Eta)
"Construct price Processes"
# Generate Delta_W trough sqrt(T)*L*Z with Z~N(0,1), Delta_W is a matrix of dim = (d,N)
# For the generation of Z define getZ
def getZ(h_n):
# Get A Matrix (d,N) consisting of Gaussian N(0,h_n) Variables
return np.random.normal(0, h_n, (d, N)) # np.random.normal(loc = 0.0, scale = np.sqrt(delta_t))
"Construct EM Method"
# d relates to the dimension of the problem, therefore, is the no. of assets in the market
Y = S_0*np.ones([d, N]) # initialisiere Y0! und dann überschreibe Y ständig
for i in range(0, (T+1) * n):
# Y = Y + np.diag(mu) @ Y * dt + np.multiply(np.diag(sigma) @ Y, L @ getZ(dt))
Y = Y + mu[:, None] * Y * dt + np.multiply(sigma[:, None] * Y, L @ getZ(dt))
if i % 100 == 0:
print('Progress: ' + str(i) + '/' + str((T+1)*n) + ' of all EM steps, while ' + str(np.round((time.time() - start_time), 2)) + ' secs passed.' )
"Construct Payoff"
Payoff = np.matmul(alpha, Y)-K
Payoff = np.sum(Payoff[(Payoff > 0)])/N # other entries would be 0 anyway, therefore its okay to use Payoff[(Payoff>0)]
V = np.exp(-r*T)*Payoff # Discount Payoff to get the fair price of the Option
"Output"
print('\nIn a market consisting of ' + str(d) + ' stocks, \nwe evaluated a classical basket option, \nusing ' + str(N) + ' MC samples.')
print('The true price of the Option is ' + str(round(V, 5)) + '\nusing the Euler Maruyama Method with ' + str((T+1) * n) + ' steps for approximation')
print("--- %s seconds ---" % np.round((time.time() - start_time), 2))