几何布朗运动代码返回大量np.complex128(0j)值的问题排查
几何布朗运动代码返回大量np.complex128(0j)值的问题排查
嘿,我来帮你揪出问题所在!你的代码里有两个关键问题导致了大量0值(甚至复数0j)的出现,咱们一步步拆解:
1. 核心逻辑错误:递推公式误用
几何布朗运动(GBM)的核心是每个时刻的价格依赖于前一时刻的价格,正确的递推公式应该是:
$$S_t = S_{t-1} \times \exp\left( \left(\mu - \frac{1}{2}\sigma^2\right)dt + \sigma\sqrt{dt} \times W_{t-1} \right)$$
但你的代码里,每次计算S_temp时都固定用S[0](也就是初始值S0),而不是前一个时刻的S[i-1]。这就意味着你不是在模拟连续的价格路径,而是反复从初始值出发计算独立的“瞬间价格”——当指数项的结果非常小时,多次用初始值乘这个极小的数,很快就会数值下溢到0,甚至因为精度问题变成0j。
2. 初始值获取的小隐患
如果你传入的是pandas Series,data[len(data)-1]可能会出错(比如Series的索引不是连续整数时),换成data.iloc[-1]能兼容Series和numpy array两种数据类型,更稳妥。
修正后的代码
import numpy as np import pandas as pd def geometric_brownian_motion(data): mu = data.mean() sigma = data.std() # 兼容pandas Series和numpy array的初始值获取方式 S0 = data.iloc[-1] if isinstance(data, pd.Series) else data[-1] T = 1 n = len(data) dt = T / n t = np.linspace(0, T, n) W = np.random.standard_normal(size=n) S = [S0] for i in range(1, n): # 用前一时刻的价格S[i-1]代替固定初始值S[0],实现正确递推 S_temp = S[i-1] * np.exp((mu - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * W[i - 1]) S.append(S_temp) S = np.array(S) return S
测试验证
你可以用一组简单数据测试,比如:
test_data = pd.Series([100, 102, 98, 101, 103]) result = geometric_brownian_motion(test_data) print(result)
现在输出应该是一条连续波动的路径,不会再出现批量0值了。
备注:内容来源于stack exchange,提问作者Puhtooie
相关产品推荐
相关产品推荐

