代码(采用随机生成的2d数组(R,C)),每个月(21天)将结果分成两个数组(平均值为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分钟,是否有任何方法可以优化代码以使其运行得更快?
答案 0 :(得分:1)
尽量不要使用Variant类型,并使用
Application.ScreenUpdating = False
在代码的早期和
Application.ScreenUpdating = True
...代码末尾。
另一个提示是用“\”除法替换“/”除法(返回单个值)(返回一个整数值)。特别是在一个循环中,这可以提高他的表现。