I am writing a function to price European option using backward induction finite difference method. The function is expected to price a European option taking Stock (stock_), age (time_), volatility (vol_), interest rate (int_), contractual expiry (expn_), type of payoff (payoff_),Strike ( strike_), number of asset steps used for evaluation option (nas_). I am expecting function to return price of the option based stock price and age (if option is bought today age is zero). I need help as I am only few weeks into mathematica programming so might be making basic mistakes. My code is as attached. Can anybody opine where I am going wrong. I have posted same question in Wolfram community too. Sorry for repeating

optionprice[strike1_, nas1_, expn1_, vol1_, int_] := Module[{ds, s, dt, dt1, t, nts, fd, delta, gamma, theta}, ds = 2*strike1/nas1; dt = 0.9/(vol1*vol1*nas1* nas1) ; nts = IntegerPart [expn1 /dt] + 1; dt1 = expn1/nts; s = Table[ids, {i, 0, nas1 + 1}]; t = Table [jdt, {j, 0, nts}]; fd = ConstantArray[1, {nas1 + 1, nts + 1}]; fd = ReplacePart[fd, {i_, nts + 1} :> Max[(s[[i]] - strike1), 0]]; Table[fd[[1, j - 1]] = (1 - int*dt)*fd[[1, j]], {j, nts + 1, 2, -1}]; Do[ Do [ If[i == (nas1 + 1), fd[[i, j]] = 2*fd[[i - 1, j]] - fd[[i - 2, j]], delta = ( fd[[i + 1, j]] - fd[[i - 1, j]])/(2*ds); gamma = ( fd[[i + 1, j]] - 2*fd[[i, j]] + fd[[i - 1, j]])/(ds*ds); theta = - 0.5*vol1*vol1 *s[[i]]*s[[i]]gamma - ints[[i]]delta + intfd[[i, j]]; fd [[i, j - 1]] = fd [[i, j]] - theta *dt], {i, 2, nas1 + 1}] , {j, nts + 1, 2, -1}];

Export["tests1.xls", fd] ]


  • $\begingroup$ Welcome to Mathematica.SE! I suggest that: 1) You take the introductory Tour now! 2) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! 3) As you receive help, try to give it too, by answering questions in your area of expertise. $\endgroup$ – bbgodfrey Apr 19 '15 at 15:46
  • $\begingroup$ Can you clarify what d2 = Table [ if [j = nts, max (q*( d1[i, nts] - strike), 0), 1], {i, 0, nas}, {j, 0, nts}]; does? d1 is a 1D list from your definition, d1[i,nts] does not make sense. And in this line if (stock = d1[i] && nts1 = d3[j], ( euro = d2 [nas1, nts1]), , where do i and j come from? $\endgroup$ – vapor Apr 19 '15 at 16:52
  • $\begingroup$ All built-in Mathematica functions start with an uppercase letter and use square brackets around their arguments. Arrays/lists are indexed using double square brackets ([[...]]). Boolean test on equality is done with == not =. I see you using if ( i=0 violating three syntax rules in one statement. $\endgroup$ – Sjoerd C. de Vries Apr 19 '15 at 17:14

This is not a complete answer, but it is too long to post in a comment. I have made some modifications in your code, but due to insufficient information given, I cannot completely correct it (I don't know economics). I will put the code here and possibly make other's work easier.

boptval[stock_, time_, vol_, int_, expn_, payoff_, strike_, nas_] := 
Module[{ds, dt, dt2, nts, nts1, nas1, q, d1, d2, d3, delta, gamma, 
theta, euro},
ds = 2*strike/nas;
dt = 0.9/(vol*vol*nas*nas);
nts = IntegerPart[expn/dt] + 1;
dt2 = expn/nts;
nts1 = time/dt2;
nas1 = stock/ds;
d1 = Table[i*ds, {i, 0, nas}];
d3 = Table[j*dt2, {j, 0, nts}];
q = 1;
If[payoff == "p", q = -1];
d2 = Table[
If[j == nts, Max[q*(d1[[i]] - strike), 0], 1], {i, 0, 
 nas}, {j, 0, nts}];
Do[If [i == 0, d2[[i, j - 1]] = (i - int*dt2)*d2[[i, j]]]; 
If[i == nas, d2[[i, j]] = 2*d2[[i - 1, j]] - d2[[i - 2, j]]]; 
 delta = (d2[[i + 1, j]] - d2[[i - 1, j]])/(2*ds); 
 gamma = (d2[[i + 1, j]] - 2*d2[[i, j]] + d2[[i - 1, j]])/(ds*ds); 
 theta = -0.5*vol*vol*d1[[i, j]]*d1[[i, j]]*gamma - 
 int*d1[[i, j]]*delta + int*d2[[i, j]]; 
 d2[[i, j - 1]] = d2[[i, j]] - theta*dt2, {i, 0, nas}, {j, nts, 
0, -1}];
If[MemberQ[stock, d1] && MemberQ[nts1, d3], (euro = d2[[nas1, nts1]]), 
euro = (stock*(d2[[IntegerPart[nas1 + 1], IntegerPart[nts1]]] - 
      d2[[IntegerPart[nas1], IntegerPart[nts1]]])/ds) + (0.5*vol*
     int)*(d2[[IntegerPart[nas1 + 1], IntegerPart[nts1]]] - 
      2*d2[[IntegerPart[nas1], IntegerPart[nts1]]] + 
      d2[[IntegerPart[nas1 - 1], IntegerPart[nts1]]])/(ds*
      ds)) + ((1/
     int)*(d2[[IntegerPart[nas1], IntegerPart[nts1]]] - 
      d2[[IntegerPart[nas1], IntegerPart[nts1 + 1]]])/dt2)]]
| improve this answer | |
  • $\begingroup$ Thanks Felix and Sjoerd for your comments. Its very useful. I will work on it and revert. Regarding economics. I am trying to value a european option at certain stock price and and time after option is struck. So if Stock Price (stock_) is greater than Strike (strike_), there will be pay out at expiry (expn_). The value of uption any time before expiry can be found out using black scholes formula. Black sholes formula is PDE. $\endgroup$ – Kausik Apr 20 '15 at 2:55
  • $\begingroup$ I am trying to solve PDE using backward induction finite difference method. Table d2 in the code is designed to store value of option at all the grid points of finite difference grid. Table d1 is used to generate stock price which are used for computation in table d2. Table d3 is used to store time steps. $\endgroup$ – Kausik Apr 20 '15 at 2:56
  • $\begingroup$ European option price is give by euro. euro takes one of the values in table d2 if stock price is exactly same as one of the values in table d1 and timestep is exactly same as one of the values in table d3, otherwise it uses black sholes PDE to generate option price from immediate nodes of table d2. $\endgroup$ – Kausik Apr 20 '15 at 2:56
  • $\begingroup$ I tried to make modifications of the two places with trivial syntax errors, but the code is nor working because you still have two problems, first, d2 now is only a 1D list with two brackets; second, your index of Part is incorrect, note that in MMA, the first element in a list is [[1]], not [[0]], and even correcting this, you still have things like [[j-1]], which could return the head or the elements from right side. $\endgroup$ – vapor Apr 20 '15 at 3:37
  • $\begingroup$ BTW, if you are solving a PDE, why not use DSolve or NDSolve? $\endgroup$ – vapor Apr 20 '15 at 3:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.