1

在我必须编写的插值方案中,我需要一个最小值和最大值函数,因此我快速编写了从我的插值函数中调用的函数 Min 和 Max。它看起来像这样:

Function interpolateVol(Strike As Double, Maturity As Double, coupon As Variant)
Dim i, k, j As Long
Dim timeIndex, strikeIndex As Long
Dim vol_minus1, vol_zero, volmin, volmax, vol As Double
Dim w1, w2 As Double

If coupon = "1M" Then
    j = 3
ElseIf coupon = "3M" Then
    j = 4
ElseIf coupon = "6M" Then
    j = 5
End If

' we set i = 1 as the maturities do not matter for
' picking up the time index
If Maturity <= volatilityCube(1, 1, 2) Then
    timeIndex = 1
ElseIf Maturity > volatilityCube(noMaturities, 1, 2) Then
    timeIndex = noMaturities
Else
    i = 1
    While volatilityCube(i, 1, 2) < Maturity
        i = i + 1
    Wend
    timeIndex = i   ' volatilityCube(timeIndex-1,2) < Maturity <= volatilityCube(timeIndex,2)
End If

' we set k = 1 as the strikes do not matter for
' picking up the strike index
If Strike <= volatilityCube(1, 1, 1) Then
    strikeIndex = 1
ElseIf Strike > volatilityCube(1, noStrikes, 1) Then
    strikeIndex = noStrikes
Else
    k = 1
    While volatilityCube(1, k, 1) < Strike
        k = k + 1
    Wend
    strikeIndex = k  ' volatilityCube(strikeIndex-1,1) < Strike <= volatilityCube(strikeIndex,1)
End If

' first we interpolate on the tenors
' as a result we will have two interpolated values:
' one for timeIndex, another for timeIndex + 1
w1 = (Maturity - volatilityCube(timeIndex - 1, 1, 2)) / _
     (volatilityCube(timeIndex, 1, 2) - volatilityCube(timeIndex - 1, 1, 2))
w2 = (volatilityCube(timeIndex, 1, 2) - Maturity) / _
     (volatilityCube(timeIndex, 1, 2) - volatilityCube(timeIndex - 1, 1, 2))
vol_minus1 = w1 * volatilityCube(timeIndex - 1, strikeIndex - 1, j) + _
            w2 * volatilityCube(timeIndex, strikeIndex - 1, j)

vol_zero = w1 * volatilityCube(timeIndex - 1, strikeIndex, j) + _
            w2 * volatilityCube(timeIndex, strikeIndex, j)

' Now we have two vols interpolated in time, each for another strike.
' These two vols need to be interpolated in strikes:
volmin = Min(vol_minus1, vol_zero)
volmax = Max(vol_minus1, vol_zero)
w1 = (Strike - volatilityCube(1, strikeIndex - 1, 1)) / _
     (volatilityCube(1, strikeIndex, 1) - volatilityCube(1, strikeIndex - 1, 1))
w2 = (volatilityCube(1, strikeIndex, 1) - Strike) / _
     (volatilityCube(1, strikeIndex, 1) - volatilityCube(1, strikeIndex - 1, 1))
vol = w1 * volmin + w2 * volmax

interpolateVol = vol

End Function

Function Min(number1 As Double, number2 As Double) As Double
    Dim var As Double

    If (number1 < number2) Then
        var = number1
    Else
        var = number2
    End If

    Min = var
End Function

Function Max(number1 As Double, number2 As Double) As Double
    Max = number1 + number2 - Min(number1, number2)
End Function

但是,运行代码会提示“byref 参数类型不匹配”错误。事实证明,我必须通过将 ByVal 添加到函数参数来明确我传递值而不是引用:

Function Min(ByVal number1 As Double, ByVal number2 As Double) As Double
        Dim var As Double

        If (number1 < number2) Then
            var = number1
        Else
            var = number2
        End If

        Min = var
    End Function

    Function Max(ByVal number1 As Double, ByVal number2 As Double) As Double
        Max = number1 + number2 - Min(number1, number2)
    End Function

现在我有两个问题:

  • 我惊讶地发现我需要明确按值传递。在 C++ 中,函数变量默认按值传递。我是否应该得出结论,VBA 默认通过引用传递变量?
  • 为什么将 Byval 添加到函数参数中会有所帮助?我没有看到类型之间的关系(因为错误应该是关于)和按值和/或引用传递....

提前谢谢了。

4

2 回答 2

3

尝试更改这部分interpolateVol

Dim vol_minus1, vol_zero, volmin, volmax, vol As Double

对此:

Dim vol_minus1 As Double, vol_zero As Double, volmin As Double, volmax As Double, vol As Double

问题是在原始版本中,仅vol声明为Double因为它就在单词旁边Double。其他四个声明没有Double应用于它们,因此它们被声明为 Excel VBA 默认类型,即Variant. 这可能会令人困惑,因为 VBA 不像您可能习惯使用的其他语言,例如 C,您可以在其中说类似double vol_minus1, vol_zero, volmin, volmax, vol;

于 2014-05-12T15:54:04.167 回答
1

ByRef该错误与or无关ByVal;它只是说明 , 或两者的类型ab正确。例如,如果您这样做:

Public Sub interpolate()
    Dim a As String
    Dim b As String
    a = 1
    b = 2
    x = Min(a, b)
End Sub

你会得到那个错误,但如果你这样做,你不会:

Public Sub interpolate()
    Dim a As Double
    Dim b As Double
    a = 1
    b = 2
    x = Min(a, b)
End Sub

两者之间的区别在于,在第二个中,a并且b具有Min函数期望的类型。

它甚至在该错误中使用该术语的原因是ByRef它只是试图更具体地帮助您找出它所指的参数。这就像说“看看那只黑狗”,而不仅仅是“看看那只狗”。

于 2014-05-12T15:40:55.443 回答