为什么我的股票模拟几何布朗运动 (GBM) 函数会产生不同的结果?

问题描述 投票:0回答:1

我使用 GBM 运行了一些股票模拟。我编写了两个函数,一个使用 for 循环,并且计算成本更高。之后,我又写了另一个,它是矢量化的,因此效率更高。然而,在显示结果后,这些函数似乎显示出一些不同的行为。尽管图看起来非常相似,但它们的平均值不同 - 第一个函数的平均值约为 105,另一个函数的平均值约为 102。我确实这样做不要认为这种差异只是由于随机性造成的(尤其是在运行 1,000 次模拟时)

import  numpy as np
import matplotlib.pyplot as plt
import time 
np.random.seed(123)

def MC_gbm1(S0, mu, sigma, T, M, n):
    start_time2 = time.time()
    dt = float(T) / n
    paths = np.zeros((n+1,M), np.float64)
    paths[0] = S0
    for t in range(1, n + 1):
        rand = np.random.normal(0,np.sqrt(dt), M)
        paths[t] = paths[t-1] * np.exp((mu- 0.5 * sigma ** 2) * dt +
                                         sigma * rand)
    comp_time2 = round(time.time() - start_time2,4)
    print("Computation time:", comp_time2)
    return paths

def MC_gbm2(S0, mu, sigma, T, M, n):
    #timesteps = np.linspace(0, T, n+1)[:,None]
    dt = T / n

    dW = np.random.normal(0, np.sqrt(dt), size=(n, M))
    dW_cumsum = np.cumsum(dW, axis=0)

    paths = S0 * np.exp((mu - 0.5 * sigma**2) * dt + sigma * dW_cumsum)
    result = np.concatenate((np.full((1,M), S0), paths), axis=0)
    return result

# Parameters
mu = 0.1
n = 100 # number of steps
T = 1 # time in years
M = 1000 #no of sims
S0 = 100 
sigma = 0.3

# GBM Simulation 1
St = MC_gbm1(S0, mu, sigma, T, M, n)

# GBM Simulation 2
St3 = MC_gbm2(S0, mu, sigma, T, M, n)

# Plot the results
sequence = np.linspace(0, T, n+1)
tt = np.full(shape = (M,n+1), fill_value=sequence).T

plt.plot(tt,St)
plt.title("GBM simulation 1")
plt.ylabel("Stock price")
plt.xlabel("Years")
plt.show()     

plt.plot(tt,St2)
plt.title("GBM simulation 2")
plt.ylabel("Stock price")
plt.xlabel("Years")
plt.show()

enter image description here enter image description here

我尝试了多种方式修改功能,但没有真正改变。理想情况下,我希望看到两个非常均值和图(当然考虑到随机性所带来的轻微随机性)

python simulation finance stock montecarlo
1个回答
0
投票

为了理解差异,请注意重置以下两个操作之间的种子会产生完全相同的噪声矩阵:

n = 10                                                                                                                
M = 1000                                                                                                              
dt = 1 / 10                                                                                                           
                                                                                                                      
rands = np.empty((n, M))                                                                                              
# Operation 1                                                                                                         
np.random.seed(123)                                                                                                   
for i in range(n):                                                                                                    
    rands[i] = np.random.normal(0, np.sqrt(dt), M)                                                                    
                                                                                                                                                                                                                                            
# Operation 2                                                                                                         
np.random.seed(123)                                                                                                   
dW = np.random.normal(0, np.sqrt(dt), size=(n, M))                                                                    
                                                                                                                      
print("Equal matrices?", np.allclose(rands, dW)) # True

所以差异一定来自于每个函数中的操作顺序和数量。事实上,如果你通过这样做关闭每个函数中的随机噪声

paths[t] = paths[t-1] * np.exp((mu- 0.5 * sigma ** 2) * dt + sigma * np.zeros_like(rand))

paths = S0 * np.exp((mu - 0.5 * sigma**2) * dt + sigma * np.zeros_like(dW_cumsum))

两个函数产生不同的矩阵:

# GBM Simulation 1                                                                                                    
np.random.seed(123)                                                                                                   
St = MC_gbm1(S0, mu, sigma, T, M, n)                                                                                  
                                                                                                                      
# GBM Simulation 2                                                                                                    
np.random.seed(123)                                                                                                   
St2 = MC_gbm2(S0, mu, sigma, T, M, n)                                                                                 
                                                                                                                                                                                                                                
print("Equal matrices?", np.allclose(St, St2)) # False

在这种情况下,差异来自于方法 1 中生成

t
迭代的方式:您使用前一个值来计算下一个值。将相应行更改为

paths[t] = S0 * np.exp((mu- 0.5 * sigma ** 2) * dt + sigma * np.zeros_like(rand))

当噪音关闭时,这两个函数将给出相同的结果。

最后,当您打开噪音时,差异的来源是方法 2 中的额外步骤:

cumsum
破坏了结果。如果你只是这样做

paths = S0 * np.exp((mu - 0.5 * sigma**2) * dt + sigma * dW)

除了已经讨论过的

paths[t] = S0 * np.exp((mu- 0.5 * sigma ** 2) * dt + sigma * rand)

您将得到相同的结果:

# GBM Simulation 1                                                                                                    
np.random.seed(123)                                                                                                   
St = MC_gbm1(S0, mu, sigma, T, M, n)                                                                                  

# GBM Simulation 2                                                                                                    
np.random.seed(123)                                                                                                   
St2 = MC_gbm2(S0, mu, sigma, T, M, n)                                                                                 

print("Equal matrices?", np.allclose(St, St2)) # True
© www.soinside.com 2019 - 2024. All rights reserved.