该代码(采用随机生成的二维数组(R,C))并将结果分解为每个月(21 天)的 2 个数组(1 个表示平均值,1 个表示曝光)
Public R As Double
Public C As Integer
Public Strike,Spot,Ton As Double
Public Ton As Double
Public AVG(), EXP(), w() As Variant
''''''''''''''
Sub Start()
sss = SetParmeters()
MonteCarlo (Copy2Array())
i = calcW()
cpSheet (True)
End Sub
'''''''''''''''
Function SetParmeters() As Boolean
Dim w As Worksheet
Set w = Worksheets("Copper daily moves")
R = w.Range("cc")
C = w.Range("row")
Strike = w.Range("strike")
Spot = w.Range("spot")
Ton = w.Range("ton")
End Function
'''''''''''''''''''
Function Copy2Array() As Variant
Dim w As Worksheet
Set w = Worksheets("Copper daily moves")
Copy2Array = w.Range("price")
End Function
''''''''''''''''''''
Function MonteCarlo(p As Variant)
ReDim w(R, C)
For i = 0 To R
s = Spot
For j = 0 To C
w(i, j) = s * (1 + p(Application.WorksheetFunction.RandBetween(1, 1275), 1))
s = w(i, j)
Next j
Next i
End Function
''''''''''''''''
Function calcW() As Boolean
ReDim AVG(R, (C / 21) - 1)
ReDim EXP(R, (C / 21) - 1)
Count21 = 0
countW = 0
For i = 0 To R
Sum = 0
countW = 0
Count21 = 21
For j = 0 To C
Sum = Sum + w(i, j)
If Count21 = j Then
AVG(i, countW) = Sum / 21
If Strike > AVG(i, countW) Then
EXP(i, countW) = (Strike - AVG(i, countW)) * ((C / 21) - countW) * Ton
Else
EXP(i, countW) = 0
End If
countW = countW + 1
Count21 = Count21 + 21
Sum = 0
End If
Next j
Next i
End Function
''''''''''''''
Sub cpSheet(flag)
Addr = "$A$1"
Addr = Addr & ":" & Range(Addr).Cells(UBound(AVG), _
UBound(AVG, 2) + 1).Address
Worksheets("AVG").Range(Addr).Value = AVG
Worksheets("EXP").Range(Addr).Value = EXP
End Sub
主要问题是处理数据需要很长时间(尤其是在进行 100k 模拟(行)及以上时),因此使用 excel 表格而不是 VBA 可能会更快!
我用 (R=100k ,c=252) 对其进行了测试,大约需要 8 分钟,有没有办法优化代码以使其运行得更快?