VBA几何布朗运动(GBM)模拟函数返回#VALUE!错误调试求助
GBM模拟VBA函数#VALUE!错误排查与修复
错误根源分析
原函数返回#VALUE!及逻辑错误的核心原因如下:
- 参数类型不匹配:
mu和sigma被声明为Double类型,但代码中尝试调用mu.Cells(1,j),说明实际传入的是单元格区域(Range)。Double类型无Cells属性,直接触发类型错误。 - 二维数组索引错误:
Stocks_t是二维数组(1 To noSteps, 1 To noPaths),但代码中使用Stocks_t(i)单索引访问,同时i=1时Stocks_t(i-1)会访问越界的0索引。 - GBM公式逻辑错误:原代码错误拆分了GBM的指数项,把随机项从指数外单独相加,不符合几何布朗运动的迭代公式。
- 初始价格未初始化:未给模拟的初始价格赋值
S0,导致第一步计算使用未初始化的数组默认值(0)。
修正后的代码
Function GBM_sim(S0 As Double, mu As Range, sigma As Range, TTM As Double, d_t As Double, Epsilons As Range) As Variant Dim noSteps As Integer Dim noPaths As Integer Dim i As Integer, j As Integer Dim mu_j As Double Dim sigma_j As Double Dim Stocks_t() As Double noSteps = Round(TTM / d_t) noPaths = Epsilons.Columns.Count ' 校验输入数组行数与模拟步数是否匹配,提前拦截错误 If Epsilons.Rows.Count <> noSteps Then GBM_sim = "Epsilons行数与模拟步数不匹配" Exit Function End If ReDim Stocks_t(1 To noSteps, 1 To noPaths) For j = 1 To noPaths ' 从对应区域读取单路径的mu和sigma值 mu_j = mu.Cells(1, j).Value sigma_j = sigma.Cells(1, j).Value ' 设置初始价格S0 Stocks_t(1, j) = S0 ' 从第2步开始迭代模拟 For i = 2 To noSteps ' 标准GBM迭代公式 Stocks_t(i, j) = Stocks_t(i - 1, j) * Exp((mu_j - (sigma_j ^ 2) / 2) * d_t + sigma_j * Sqr(d_t) * Epsilons.Cells(i, j).Value) Next i Next j GBM_sim = Stocks_t End Function
关键修正说明
- 参数类型调整:将
mu和sigma的类型改为Range,匹配实际传入的单元格区域。 - 数组索引修正:使用二维数组索引
Stocks_t(i,j)访问元素,同时从i=2开始循环,避免越界访问。 - 公式逻辑修复:将随机项纳入指数运算,还原GBM的正确迭代逻辑。
- 输入校验:添加Epsilons行数与模拟步数的校验,提前返回错误提示。
- 可读性优化:用
Sqr(d_t)替代d_t^0.5,明确使用.Value读取单元格值,避免隐式转换问题。
内容的提问来源于stack exchange,提问作者Cathy lee
相关产品推荐
相关产品推荐

