The code ( takes randomly generated 2d array (R,C)) and breaks results down in 2 arrays for each month (21 days) ( 1 for the average , 1 for the exposure )
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
The Main issue is that it takes to long to process the data ( especially when going for 100k simulations (rows) and above ) and thus it might be faster to do it with excel sheets rather than VBA !!.
i tested it with (R=100k ,c=252) and it takes about 8 mins , is there any way to optimize the code in order of it to run faster ?