I am trying to compute price of call option on a stock using the finite difference method. I have a VBA code for it, and I am trying to find out how I can use Mathematica memoization functions and recursive function to code it efficiently.
The VBA code is as below.
optval(vol, intrate, expn, payoff, strike, Etype, NAS)
ReDim S(0 To NAS) ReDim vold(0 To NAS) ReDim Vnew(0 To NAS)
ReDim Dummy(0 To NAS, 1 To 3)
ds = 2 * strike / NAS dt = 0.9 / vol / vol / NAS / NAS
NTS = Int(expn / dt) + 1 dt = expn / NTS
q = 1 If payoff = "p" Then q = -1 For i = 0 To NAS
S(i) = i * ds Dummy(i, 1) = S(i) vold(i) = Application.Max(q * (S(i) - Strike), 0)
Dummy(i, 2) = vold(i) Next i
For k = 1 To NTS For i = 1 To NAS - 1
Delta = (vold(i + 1) - vold(i - 1)) / 2 / ds
Gamma = (vold(i + 1) - 2 * vold(i) + vold(i - 1)) / ds / ds Theta = -0.5 * vol * vol * S(i) * S(i) * Gamma - intrate * S(i) * Delta + intrate * vold(i)
Vnew(i) = vold(i) - Theta * dt
Next i
Vnew(0) = (1 - intrate * dt) * vold(0)
Vnew(NAS) = 2 * vold(NAS - 1) - vold(NAS - 2)
For i = 0 To NAS
vold(i) = Vnew(i)
Next i
If Etype = "Y" Then
For i = 0 To NAS
vold(i) = Application.Max(vold(i), Dummy(i, 2))
Next i
End If
Next k
For i = 0 To NAS
Dummy(i, 3) = vold(i)
Next i
optval = Dummy End Function
The computation method involves creation of array/table which uses three seperate equation. The above VBA code uses three variable dummy[[i+1, 1]]
, dummy[[I+1,2]]
and dummy[[i+3]]
to store final output, and in addition uses vold
and vnew
to compute one node from previous node backwards.
Can we use memoization functions/recursive functions to do this in Mathematica?
I uploaded the excel pictures of 4X4 matrix with expected value of individual element in it to explain the logic of computation. I am using Piecewise
to create a array (table d
using function fd[i,j]
) using four conditions as in the below code to improve implementation the logic. The computation start from step j = ts+1
using step 1 below and recursively computes all the elements of array back to j = 1
using condions in step 2-4 below.
1st equation is when
fd[i,j] = Max[s[[i]] - strike1, 0]
whenj=ts+1
This condition is working in below code.For
( i == 1 && 0 < j < ts + 1)
, the code is expected to use(1 - int)*fd[i, j + 1]
tocompute fd[I,j]
. For example, with respect to uploaded matrix, element of Column 2 and 1st row= (1-int*dt)*element(1,3)
;For
(1 < i < as + 2 && 0 < j, ts + 1)
, the code is expected to usefd[i, j - 1] = del*dt
.For example with respect to uploaded matrix, I am expecting elements of row 2 and 3 and column 1 and 2 to be computed recursively using function
del
for example element of row3 and column2 is derived from elements of row 2,column 3 and row4 column 3 using function del. Hence element of 2nd row and column 1= ((element(3,2)-element(1,2))/ds)*dt
, and element of 3rd row and column 2= ((element(4,3)-element(2,3))/ds)*dt
For
(i = as + 2 && 0 < j < ts + 1)
, the code is expected to use2*fd[i - 1, j] - fd[i - 2, j]
.For example, with respect to uploaded matrix, element of row 4 and column 2
= 2*(elements of row 3 and column 2) -(elements of row2 and column 2)
. Similiarly element of row 4 and column 1= 2*(elements of row 3 and column 1) -(elements of row2 and column 1)
The code can be run using parameter as recursive[4, 3, 3, 0.01, 0.02, 1]
.
The below code computes the 1st condition but gets into problems for rest of conditions.
I also tried to implement logic using a series of Do
loops. Pl
refers to code in my previous question - Matrix iteration failing after second step. There the code was incorrectly computing last row (i.e as+1) from last but one column.
I had a memoization issue in that part of loop which I didn't understand how to solve. Rest of the rows and columns were correctly computed for second iteration (i.e. last but one column). As successive columns always use data from previous column. The computation for successive columns gets incorrect from bottom (i.e. for row as, as-1 etc).
Can anybody help in implementing above logic using memoization or recursive functions like RSolve
/Recurrence Table instead?
recursive[as_, ts_, ds_, dt_, int_, strike1_] :=
Module[{s, d, del}, s = Table[i*ds, {i, 0, as + 1}];
fd[i_, j_] := fd[i, j] = Piecewise[{
{Max[s[[i]] - strike1, 0], j == ts + 1},
{(1 - int)*fd[i, j + 1], i == 1 && 1 < j < ts + 1},
{fd[i, j - 1] = del*dt, 1 < i < as + 2 && 0 < j< ts + 1},
{2*fd[i - 1, j] - fd[i - 2, j], i == as + 2 && 1 < j < ts + 1}
}];
del := ( fd[i + 1, j] - fd[i - 1, j])/ds;
d = Table[fd[i, j], {i, 1, as + 2}, {j, 1, ts + 1}];
Grid[d]
]