VBA: функция возвращает # ЗНАЧЕНИЕ - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть саб, который позволяет мне оценивать опцион через определенную модель.Затем я хотел создать функцию, которая точно так же делает то же самое, но я получаю ошибку.Некоторые входные данные могут быть векторными, поэтому я попробовал код с и без скобок.Я также переключил «Worksheet.function» с «Application», ничего из этого не сработало.

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 голосов
/ 08 февраля 2019

Спасибо всем за помощь.Я нашел проблему.Входные данные функции - это диапазон ячеек электронной таблицы Excel.Но VBA не распознал их как массив, поэтому мне пришлось преобразовать диапазон в массиве (rho в коде).Поскольку у меня также есть многомерный массив, я обнаружил, что переменные диапазона хранят значения диапазона в виде одномерной строки по необработанным.Например, у меня матрица 14х14, тогда 17-е значение диапазона соответствует 2-й строке 3-го столбца матрицы.Надеюсь эта информация кому-нибудь пригодится.Так я решил основную проблему

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
0 голосов
/ 06 февраля 2019

Вы пытаетесь использовать некоторые функциональные параметры в качестве массивов, но они не инициализируются как таковые

Например,

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

У вас есть wgt и SOкак

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..., которая в данный момент прокомментирована, как не комментирующую, чтонемедленно перезаписать значения параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...