我正在创建N_MC
个模拟股票价格路径S
,每条路径中的n
点,不包括初始点。对于给定路径,这样做的算法是对股票价格的先前值递归的。这就是我现在所拥有的:
import numpy as np
import time
N_MC = 1000
n = 10000
S = np.zeros((N_MC, n+1))
S0 = 1.0
S[:, 0] = S0
start_time_normals = time.clock()
Z = np.exp(np.random.normal(size=(N_MC, n)))
print "generate normals time = ", time.clock() - start_time_normals
start_time_prices = time.clock()
for i in xrange(N_MC):
for j in xrange(1, n+1):
S[i, j] = S[i, j-1]*Z[i, j-1]
print "pices time = ", time.clock() - start_time_prices
时代是:
generate normals time = 1.07
pices time = 9.98
是否有更有效的方法来生成数组S
,也许使用Numpy的例程?如果正常的随机变量Z
也可以更快地生成,那将会很好,但我不是那么有希望。
答案 0 :(得分:4)
没有必要循环“路径”,因为它们彼此独立。因此,您可以移除外部循环for i in xrange(N_MC)
,只需对S
和Z
的整列进行操作。
为了加速递归计算,我们只考虑一条单一路径'。假设z
是包含每个时间步长的随机值的向量(所有已知的提前)。 s
是一个向量,应该包含每个时间步的输出。 s0
是零时的初始输出。 j
是时候了。
您的代码以递归方式定义输出:
s[j] = s[j-1]*z[j-1]
让我们扩展一下:
s[1] = s[0]*z[0]
s[2] = s[1]*z[1]
= s[0]*z[0]*z[1]
s[3] = s[2]*z[2]
= s[0]*z[0]*z[1]*z[2]
s[4] = s[3]*z[3]
= s[0]*z[0]*z[1]*z[2]*z[3]
每个输出s[j]
由s[0]
乘以从0到j-1
的随机值的乘积。您可以使用numpy.cumprod()
计算这样的累积产品,这应该比循环更有效:
s = np.concatenate(([s0], s0 * np.cumprod(z[0:-1])))
您可以使用axis
参数沿矩阵的一个维度进行操作(例如,在'路径'之间并行执行此操作。)