Hi everyone,
I'm quite new to VBA and need to produce a Monte Carlo simulation and then save the results.
Currently, I have several macros that look through cells in loops, do calculations and then print the value to new cells. This is quite time consuming and was wondering if there's a way to make this faster?
Below my macro essentially takes current stock price from a cell (generated by another Sub) and then returns an expected stock price and Heston call price by simulating another number of paths, with time to the end decreasing as it goes along. Is there perhaps a faster way to do this with arrays?
Thanks in advance!
I'm quite new to VBA and need to produce a Monte Carlo simulation and then save the results.
Currently, I have several macros that look through cells in loops, do calculations and then print the value to new cells. This is quite time consuming and was wondering if there's a way to make this faster?
Below my macro essentially takes current stock price from a cell (generated by another Sub) and then returns an expected stock price and Heston call price by simulating another number of paths, with time to the end decreasing as it goes along. Is there perhaps a faster way to do this with arrays?
Thanks in advance!
Code:
Global Const RndHigh = 0.999999999999999
Global Const RndLow = 0.000000000000001
Sub GenExpStockPrices()
Application.ScreenUpdating = False
Dim time As Single
Paths = Sheets("FM408 Q1").Cells(2, 3).Value
Steps = Sheets("FM408 Q1").Cells(3, 3).Value
lambda = Sheets("FM408 Q1").Cells(4, 3).Value
rho = Sheets("FM408 Q1").Cells(5, 3).Value
eta = Sheets("FM408 Q1").Cells(6, 3).Value
Vbar = Sheets("FM408 Q1").Cells(7, 3).Value
v0 = Sheets("FM408 Q1").Cells(8, 3).Value
s0 = Sheets("FM408 Q1").Cells(9, 3).Value
K = Sheets("FM408 Q1").Cells(10, 3).Value
r = Sheets("FM408 Q1").Cells(11, 3).Value
T = Sheets("FM408 Q1").Cells(12, 3).Value
For OldPath = 1 To Paths
StSum = 0
HCallSum = 0
For NewTime = 1 To Steps
StSum = 0
HCallSum = 0
NewSteps = Steps - NewTime
If NewSteps = 0 Then
GoTo Maturity
Else
GoTo NotMaturity
NotMaturity:
Deltat = T / NewSteps
' For time = 1 To NewSteps
For Path = 1 To Paths
St = Sheets("FM408 Q1").Cells((-8 + (10 * Path)), NewTime + 10).Value
xt = Log(St)
Vt = Sheets("FM408 Q1").Cells((-7 + (10 * Path)), NewTime + 10).Value
For Subtime = 1 To NewSteps
Randomize
RndA = Rnd()
If RndA <= 0 Then
RndA = RndLow
ElseIf RndA >= 1 Then
RndA = RndHigh
End If
RndB = Rnd()
If RndB <= 0 Then
RndB = RndLow
ElseIf RndB >= 1 Then
RndB = RndHigh
End If
A = Application.Norm_S_Inv(RndA)
B = Application.Norm_S_Inv(RndB)
C = (rho * A) + (Sqr(1 - ((rho) ^ 2)) * B)
xt = xt + ((r - (Vt / 2)) * Deltat) + (Sqr(Vt * Deltat) * A)
Vt = Vt - lambda * ((Vt - Vbar) * Deltat) + (eta * Sqr(Vt) * Sqr(Deltat) * C) + (((eta ^ 2) / 4) * Deltat * ((C ^ 2) - 1))
Vt = Abs(Vt)
St = Exp(xt)
HCall = Application.Max(0, (St - K))
Next Subtime
StSum = StSum + St
HCallSum = HCallSum + HCall
Next Path
ExpSt = StSum / Paths
Sheets("FM408 Q1").Cells(((10 * OldPath) - 5), (10 + NewTime)).Value = ExpSt
ExpHCall = HCallSum / Paths
Sheets("FM408 Q1").Cells(((10 * OldPath) - 4), (10 + NewTime)).Value = ExpHCall
End If
Next NewTime
Maturity:
Sheets("FM408 Q1").Cells((-4 + (10 * OldPath)), Steps + 10).Value = Application.Max(Sheets("FM408 Q1").Cells((-8 + (10 * OldPath)), Steps + 10).Value - K, 0)
Sheets("FM408 Q1").Cells(((10 * OldPath) - 5), Steps + 10).Value = Sheets("FM408 Q1").Cells((-8 + (10 * OldPath)), Steps + 10).Value
Next OldPath
Call GenExpStockPrices0
End Sub