December 30th, 2004, 9:41 am
Just thought I'd share the benefits of some C++ coding I did with the forum. Before I worked in finance, I worked for a few years in a CFD (computational fluid dynamics) company. I took one of the basic finite difference discretisation schemes (MacCormack scheme) used for around 15 years in CFD and a implemented a numerical solution to Black-Scholes. This scheme is fully explicit so lends itself easily to american style exercise, but is second order accurate in time and space, just like Crank-Nicholson. I used two forms, the non-conservative (NC) form which most people are used to seeing, and the conservative formulation (C), which should help to reduce some of the error due to discretisation in S. For a call option with K = 80.0, sigma = 0.3, r ( risk-free rate ) = 0.07, S = 100 and T = 0.5, I get the following analytic resultAnalyticValue = 23.758, Delta = 0.907077, Gamma = 0.0078387, theta = -8.21389and the following result for the non-conservative formulation. Numerical ( NC ) - dS = 0.1, solution time 103.819sValue = 23.758, Delta = 0.907076, Gamma = 0.00783868, theta = -8.21388Numerical ( NC ) - dS = 1.0, solution time 0.032349sValue = 23.7583, Delta = 0.907054, Gamma = 0.00783643, theta = -8.21291Numerical ( NC ) - dS = 5.0, solution time 0.000827sValue = 23.7357, Delta = 0.906996, Gamma = 0.00777608, theta = -8.19161What can be seen is that the result is pretty much spot on for dS = 0.1, but is also pretty accurate for large time steps such as 1.0, with a solution time sub 1 second, and even dS = 5.0 with a solution time of sub 1-millisecond. The conservative results are shown below:Numerical ( C ) - dS = 0.1, solution time 195.699sValue = 23.758, Delta = 0.907077, Gamma = 0.00783868, theta = -8.21388Numerical ( C ) - dS = 1.0, solution time 0.090287sValue = 23.7582, Delta = 0.907057, Gamma = 0.00783633, theta = -8.2128Numerical ( C ) - dS = 5.0, solution time 0.001376sValue = 23.7343, Delta = 0.907071, Gamma = 0.00777471, theta = -8.18929The results are a little better in most cases, especially in the delta, but it seems that the extra accuracy doesn't warrant the extra solution time. This formulation should however fare alot better over the non-conservative form when there is variable volatility, sigma = f(S). Finally these can be compared to the results I got from my Crank-Nicholson solver:Numerical ( CN ) - dS = 0.1, solution time 14.0876sValue = 23.7546, Delta = 0.907130, Gamma = 0.007839, theta = -8.21444Numerical ( CN ) - dS = 1.0, solution time 1.18434sValue = 24.6647, Delta = 0.914685, Gamma = 0.007283, theta = -8.08372Numerical ( CN ) - dS = 5.0, solution time 0.235688sValue = 28.3642, Delta = 0.939682, Gamma = 0.005295, theta = -7.549203I have attached the C++ code for both schemes and they should compile on either windows or linux. I develop on linux/unix but have attempted to keep the code portable. Simple change the parameters in the sections " Common " and " finite difference " to adjust the option parameters and space discretisation. The time step is automatically calculated. You can also change the option type ( call, put ,etc ) in a section further down. Then simply compile and get the results. The code was pretty much done over two days, so bear in mind it is a bit rough around the edges, but I would interested to see what you think of the scheme and how it fares against some the FD solvers you guys are using. Thanks, Blade