VBA:函数返回#VALUE

时间:2019-02-06 15:58:59

标签: excel vba

我有一个可让我通过某种模型为期权定价的配件。然后,我想构建一个函数,以相同的方式执行完全相同的操作,但出现错误。一些输入可以是向量,因此我尝试了带括号或不带括号的代码。我还用“应用程序”切换了“ Worksheet.function”,但没有一个起作用。

Public Function TaylorPrice1(S0 As Double, sigma As Double, wgt As Double, rho As Double, T As Double, Kappa As Double, r As Double, num As Double) As Double

Dim ModS() As Double
Dim Z As Double
Dim i, j, L, k As Double
Dim Sum1, Sum2, Sum3, Sum4, Sum5 As Double
Dim U1, U2, U20, U2st, U2nd, U2rd, mz, vz As Double
Dim a1, a2, a3, B1, B2, c1, c2, c3, c4, d1, d2, d3, d4, z1, z2, z3, y, y1, y2 As Double
Dim py, pyst, pynd, Ny1, Ny2 As Double
Dim Modrho() As Double

'ReDim S0(num), sigma(num), wgt(num), rho(num, num) As Double
ReDim ModS(num) As Double
ReDim Modrho(num, num) As Double
Z = 1

        Sum1 = 0
        Sum2 = 0
        Sum3 = 0
        Sum4 = 0
        Sum5 = 0
        U1 = 0
        U2 = 0
        U20 = 0
        U2st = 0
        U2nd = 0
        U2rd = 0

        For i = 0 To num - 1
            ModS(i) = wgt(i) * S0(i) * Exp(r * T)
            U1 = U1 + ModS(i)
        Next i

        For i = 0 To num - 1
            For j = 0 To num - 1
                Modrho(i, j) = rho(i, j) * sigma(i) * sigma(j) * T
                U2 = U2 + ModS(i) * ModS(j) * Exp((Z ^ 2) * Modrho(i, j))
            Next j
        Next i

        mz = 2 * Log(U1) - 0.5 * Log(U2)
        vz = Log(U2) - 2 * Log(U1)

        For i = 0 To num - 1
            For j = 0 To num - 1
                U20 = U20 + ModS(i) * ModS(j)
                U2st = U2st + ModS(i) * ModS(j) * Modrho(i, j)
                U2nd = U2nd + ModS(i) * ModS(j) * Modrho(i, j) ^ 2
                U2rd = U2rd + ModS(i) * ModS(j) * Modrho(i, j) ^ 3
            Next j
        Next i

        a1 = -(U2st * Z ^ 2) / (2 * U20)
        a2 = 2 * a1 ^ 2 - ((U2nd * Z ^ 4) / (2 * U20))
        a3 = 6 * a1 * a2 - 4 * a1 ^ 3 - ((U2rd * Z ^ 6) / (2 * U20))

        For k = 0 To num - 1
            For j = 0 To num - 1
                For i = 0 To num - 1
                    Sum1 = Sum1 + 2 * (ModS(i) * ModS(j) * ModS(k) * Modrho(i, k) * Modrho(j, k))
                Next i
            Next j
        Next k

        B1 = (Z ^ 4) / (4 * U1 ^ 3) * Sum1
        B2 = a1 ^ 2 - 0.5 * a2

        For L = 0 To num - 1
            For k = 0 To num - 1
                For j = 0 To num - 1
                    For i = 0 To num - 1
                        Sum2 = Sum2 + 8 * (ModS(i) * ModS(j) * ModS(k) * ModS(L) * Modrho(i, L) * Modrho(j, k) * Modrho(k, L))
                    Next i
                Next j
            Next k
        Next L
        Sum2 = Sum2 + 2 * U2st * U2nd
        For L = 0 To num - 1
            For k = 0 To num - 1
                For j = 0 To num - 1
                    For i = 0 To num - 1
                        Sum3 = Sum3 + 6 * (ModS(i) * ModS(j) * ModS(k) * ModS(L) * Modrho(i, L) * Modrho(j, L) * Modrho(k, L))
                    Next i
                Next j
            Next k
        Next L
        For k = 0 To num - 1
            For j = 0 To num - 1
                For i = 0 To num - 1
                    Sum4 = Sum4 + 6 * (ModS(i) * ModS(j) * ModS(k) * Modrho(i, k) * (Modrho(j, k) ^ 2))
                Next i
            Next j
        Next k

        For k = 0 To num - 1
            For j = 0 To num - 1
                For i = 0 To num - 1
                    Sum5 = Sum5 + 8 * (ModS(i) * ModS(j) * ModS(k) * Modrho(i, j) * Modrho(i, k) * Modrho(j, k))
               Next i
            Next j
        Next k

        c1 = -1 * a1 * B1
        c2 = (Z ^ 6 / (144 * U1 ^ 4)) * (9 * Sum2 + 4 * Sum3)
        c3 = (Z ^ 6 / (48 * U1 ^ 3)) * (4 * Sum4 + Sum5)
        c4 = a1 * a2 - 2 / 3 * a1 ^ 3 - a3 / 6

        d1 = 0.5 * (6 * a1 ^ 2 + a2 - 4 * B1 + 2 * B2) - 1 / 6 * (120 * a1 ^ 3 - a3 + 6 * (24 * c1 - 6 * c2 + 2 * c3 - c4))
        d2 = 0.5 * (10 * a1 ^ 2 + a2 - 6 * B1 + 2 * B2) - (128 * (a1 ^ 3) / 3 - a3 / 6 + 2 * a1 * B1 - a1 * B2 + 50 * c1 - 11 * c2 + 3 * c3 - c4)
        d3 = (2 * a1 ^ 2 - B1) - 1 / 3 * (88 * a1 ^ 3 + 3 * a1 * (5 * B1 - 2 * B2) + 3 * (35 * c1 - 6 * c2 + c3))
        d4 = (-20 * (a1 ^ 3) / 3 + a1 * (-4 * B1 + B2) - 10 * c1 + c2)

        z1 = d2 - d3 + d4
        z2 = d3 - d4
        z3 = d4
        y = Log(Kappa)
        y1 = (mz - y) / (Sqr(vz)) + Sqr(vz)
        y2 = y1 - Sqr(vz)
        Ny1 = Application.Norm_S_Dist(y1, True)
        Ny2 = Application.Norm_S_Dist(y2, True)
        py = (1 / (Sqr(2 * Application.Pi() * vz))) * Exp((-((y - mz) ^ 2) / (2 * vz)))
        pyst = py * 1 / (-vz) * (y - mz)
        pynd = mz / vz * pyst + py * (1 / (-vz)) * (1 + y * (-1 / vz) * (y - mz))
        TaylorPrice1 = (U1 * Exp(-r * T) * Ny1 - Kappa * Exp(-r * T) * Ny2) + (Exp(-r * T) * Kappa * (z1 * py + z2 * pyst + z3 * pynd))

End Function

2 个答案:

答案 0 :(得分:0)

您正在尝试将某些函数参数用作数组,但没有这样初始化它们

例如

ModS(i) = wgt(i) * S0(i) * Exp(r * T)

您有wgtSO作为

Public Function TaylorPrice1(S0 As Double, sigma As Double, wgt As Double, rho As Double, T As Double, Kappa As Double, r As Double, num As Double) As Double

在您的函数参数中。

Modrho(i, j) = rho(i, j) * sigma(i) * sigma(j) * T

您可以从所有可能为数组的函数参数中删除As Double,并删除当前注释的Redim...行,因为取消注释会立即覆盖参数值

答案 1 :(得分:0)

感谢大家的帮助。我发现了问题。该函数的输入实际上是Excel电子表格的单元格范围。但是VBA不能将它们识别为数组,因此我不得不转换数组中的范围(代码中的rho)。由于我也有一个多维数组,因此我发现范围变量将范围的值按原始格式存储为一维行。例如,我有一个14x14的矩阵,则范围的第17个值对应于矩阵的第二行,第三列。我希望这些信息对某人有用。这就是我解决主要问题的方式

Dim i As Double
Dim j As Double
Dim L As Double
Dim k As Double
Dim S0() As Double
Dim sigma() As Double
Dim wgt() As Double
Dim rho() As Double
Dim Modrho() As Double
Dim ModS() As Double
' transofrmo range nei vettori
Dim cell As Range
Dim num1 As Long, num2 As Long
Dim rhodritto() As Double
num1 = 0
For Each cell In S0Input
      num1 = num1 + 1
Next cell
ReDim S0(num1) As Double
ReDim sigma(num1) As Double
ReDim wgt(num1) As Double
ReDim rho(num1, num1) As Double
ReDim Modrho(num1, num1) As Double
ReDim ModS(num1) As Double


i = 1
For Each cell In S0Input
    S0(i) = cell.Value
    i = i + 1
Next cell
i = 1
For Each cell In sigmaInput
    sigma(i) = cell.Value
    i = i + 1
Next cell
i = 1
For Each cell In wgtInput
    wgt(i) = cell.Value
    i = i + 1
Next cell
num2 = 0
For Each cell In rhoInput
   num2 = num2 + 1
Next cell
ReDim rhodritto(num2)
i = 1
For Each cell In rhoInput
    rhodritto(i) = cell.Value
    i = i + 1
Next cell
k = 1
For i = 1 To num1
    For j = 1 To num1
        rho(i, j) = rhodritto(k)
        k = k + 1
    Next j
Next i