Почему возникает ошибка #VALUE в функции VBA при создании ReDim матрицы цен акций из именованного диапазона?

Вопрос или проблема

‘Данный код VBA для биномальных опционов содержит отсутствующий синтаксис, предназначенный для создания матрицы цен на акции размером N на N с использованием входных данных для оценки биномальных деревьев опционов с дискретными дивидендами, сохранёнными как именованный диапазон “Dividends” в MS Excel.

Идея состоит в том, что конечная матрица акций используется для рекурсивного расчёта окончательной стоимости опциона, хотя функция Binomial возвращает #VALUE. Пожалуйста, помогите определить, какие операторы Dim и ReDim и т.д. необходимо добавить в ndivs, divsum и т.д., чтобы создать раздел Первой матрицы акций и Финальной матрицы акций для расчёта оставшихся записей для раздела Опционов на покупку и продажу. Спасибо.’

Function Binomial(Spot, K, T, r, sigma, n, PutCall As String, EuroAmer As String, Dividends) 
    dt = T / n: u = Exp(sigma * (dt ^ 0.5)):
    d=1/u a = Exp(r * dt):
    p = (a - d) / (u - d) ndivs = Application.Count(Dividends) / 3

    Dim ndivs As Double

    ndivs = Application.Count(Dividends) / 3

    ' Дерево для цены акций
    Dim S() As Double
    Dim Tau() As Double
    Dim Div() As Double
    Dim Rate() As Double
    Dim divsum() As Double

    'Создаёт массивы с выплатами дивидендов в массиве Div(), временем
    '  выплат в массиве Tau(), и процентной ставкой, применяемой к каждой выплате дивидендов в массиве 

    divsum = 0
    For i = 1 To ndivs
        Tau(i) = Dividends(i, 1) 
        Div(i) = Dividends(i, 2)
        Rate(i) = Dividends(i, 3)
        divsum = divsum + Div(i) * Exp(-Rate(i) * tau(i))
    Next i 

    'Первая матрица акций temp (i, j) для создания начальных цен на акции
    Dim Temp() As Double
    ReDim Temp(n + 1, n + 1) As Double
    temp(1, 1) = Spot - divsum
    For i = 1 To n + 1
        For j = i To n + 1
            temp(i, j) = temp(1, 1) * u ^ (j - i) * d ^ (i - 1)
        Next j
    Next i

    'Финальная матрица акций S(i, j) для добавления первой матрицы акций с 
    '     дополнительными дисконтированными дивидендами из Div()

    ReDim S(n + 1, n + 1) As Double
    S(1, 1) = temp(1, 1) + divsum
    For j = 2 To n + 1
        For i = 1 To j
            If tau(1) < (j - 1) * dt Then S(i, j) = temp(i, j)
            Else S(i, j) = temp(i, j) + Div(1) * Exp(-Rate(1) * (tau(1) - (j - 1) * dt))
        Next i
    Next j

    For z = 2 To ndivs
        For j = 2 To n + 1
            For i = 1 To j
                If tau(z) < (j - 1) * dt Then S(i, j) = S(i, j)
                Else S(i, j) = S(i, j) + Div(z)* Exp(-Rate(z) * (tau(z) - (j - 1) * dt))
            Next i
        Next j
    Next z
End Function

'Изначально модель содержит выплаты дивидендов в массиве Div(), время выплат в
массиве Tau(), и процентную ставку, применяемую к каждой выплате дивидендов в массиве Rate().

Затем опция создаёт Первую матрицу акций temp (i, j) для создания начальных цен на акции.

Наконец, создаётся Финальная матрица акций, чтобы добавить первую матрицу акций с дополнительными дисконтированными дивидендами для дальнейшего расчёта окончательной стоимости опциона. Спасибо.'

Ответ или решение

Ошибка #VALUE в функции VBA может возникать по нескольким причинам при создании многомерного массива для хранения цен акций из именованного диапазона. Давайте рассмотрим проблемные области вашего кода и предложим соответствующие исправления.

1. Ошибки в объявлениях переменных

В вашем коде существует несколько мест, где объявление и перераспределение массивов (ReDim) могут быть неоптимальными или неправильными. Убедитесь, что все массивы имеют правильные размеры и правильно инициализируются.

2. Неверное использование индексов массива

VBA массивы по умолчанию индексируются с 0, если вы не задаете иное. Если ваши данные в Dividends имеют одну строку на каждый элемент, то вам, возможно, потребуется скорректировать индексацию.

3. Ошибки в расчетах

Проверьте вашу логику расчетов, связанные с временными интервалами (tau) и скидками. Убедитесь, что индексы и показаемая логика корректны.

4. Задание значений Div и других массивов

При определении и заполнении массивов, таких как Div, Tau, и Rate, убедитесь, что вы корректно задаете размерность. Например, вы используете индексы 1 to ndivs, которые не соответствуют размеру массива в VBA без явного указания начального элемента.

Исправленный код

Вот модифицированный фрагмент вашего кода, который устраняет некоторые из вышеупомянутых проблем:

Function Binomial(Spot As Double, K As Double, T As Double, r As Double, sigma As Double, n As Long, PutCall As String, EuroAmer As String, Dividends As Range) 
    Dim dt As Double, u As Double, d As Double, a As Double, p As Double
    Dim ndivs As Long, i As Long, z As Long, j As Long
    Dim divsum As Double
    Dim Tau() As Double, Div() As Double, Rate() As Double
    Dim Temp() As Double, S() As Double

    dt = T / n
    u = Exp(sigma * Sqr(dt))
    d = 1 / u
    a = Exp(r * dt)
    p = (a - d) / (u - d)

    ndivs = Application.Count(Dividends) ' Количество дивидендов

    ReDim Tau(1 To ndivs) As Double
    ReDim Div(1 To ndivs) As Double
    ReDim Rate(1 To ndivs) As Double
    divsum = 0

    ' Заполнение массивов дивидендов
    For i = 1 To ndivs
        Tau(i) = Dividends(i, 1) 
        Div(i) = Dividends(i, 2)
        Rate(i) = Dividends(i, 3)
        divsum = divsum + Div(i) * Exp(-Rate(i) * Tau(i))
    Next i 

    ' Создание матрицы цен акций
    ReDim Temp(1 To n + 1, 1 To n + 1) As Double
    Temp(1, 1) = Spot - divsum
    For i = 1 To n + 1
        For j = i To n + 1
            Temp(i, j) = Temp(1, 1) * u ^ (j - i) * d ^ (i - 1)
        Next j
    Next i

    ' Создание финальной матрицы цен акций
    ReDim S(1 To n + 1, 1 To n + 1) As Double
    S(1, 1) = Temp(1, 1) + divsum
    For j = 2 To n + 1
        For i = 1 To j
            If Tau(1) < (j - 1) * dt Then 
                S(i, j) = Temp(i, j)
            Else 
                S(i, j) = Temp(i, j) + Div(1) * Exp(-Rate(1) * (Tau(1) - (j - 1) * dt))
            End If
        Next i
    Next j

    For z = 2 To ndivs
        For j = 2 To n + 1
            For i = 1 To j
                If Tau(z) < (j - 1) * dt Then 
                    S(i, j) = S(i, j)
                Else 
                    S(i, j) = S(i, j) + Div(z) * Exp(-Rate(z) * (Tau(z) - (j - 1) * dt))
                End If
            Next i
        Next j
    Next z
End Function

Заключение

Проведя изменения, вы сможете избежать ошибки #VALUE и успешно создать матрицы цен акций. Обратите внимание на корректное разделение и инициализацию массивов, а также на правильное использование индексов. Это гарантирует, что ваш код не только компилируется, но и работает правильно.

Оцените материал
Добавить комментарий

Капча загружается...