# How do you check your option calculations?

I'm implementing a bunch of different algorithms to price options/find Greeks: finite difference, Monte Carlo, binomial...

I'm not really sure how to check my calculations. I tried using QuantLib to price things for me, but it seems to use actual dates a lot (whereas I'm just interested in year fractions) and the documentation is lacking.

I implemented a finite difference algorithm as described in Wilmott's "Mathematics of Financial Derivatives" and he has some numbers in his book. But my "implementation" of just the analytical Black-Scholes formula already gives different results than his (not by much though).

Again, I just typed up the down and out call option formula from Zhang's Exotic options. He actually goes through explicit examples for each of his formulas.

But for a down and out call with $S = 100$, $K= 92$, $H = 95$, $r = 0.08$, $q = 0.03$, $\sigma = 0.2$, $\tau = 0.5$ he gets \$6.936 and I get \$6.908.

So my question is, what is your go to reference for option prices for checking your code?

1: Follow the calculations in The Complete Guide to Option Pricing Formulas. The book has many formulas, sample values and outputs. Highly recommended for validating your results. Apparently, this is one of most popular books used by real-world quants (simple and fast).

2: You can still use QuantLib to price with year fractions. I have an example:

DayCounter dc = Actual360();
Date today = Date::todaysDate();
Date exerciseDate = today + 90;
assert(dc.yearFraction(today, exerciseDate) == 0.25);


Here, we make the exercise date exactly 0.25 year fraction away from today (pricing date). Anything from QuantLib using the dates should match your own implementation. You can adjust the exerciseDate, print the yearFraction and use it in your own code.

3: Use fOptions. fOptions and it's related fExoticOptions are R-packages. They implement the most commonly quantitative finance models. For example, I use the following script to validate my Levy Asian options:

LevyAsianApproxOption(TypeFlag='c', S=6.80, X=6.90, SA=6.80, r=0.07, b=-0.02, sigma=0.14, Time=0.50, time=0.50)

4: Use OptionMatrix. OptionMatirx is a finance calculator runs on a desktop computer.

• When you say OptionMatrix, are you referring to OptionMatrix by Anthony Bradford? anthonybradford.com/om/Overview.html#Overview – noob2 Jun 8 '16 at 12:41
• @noob2 Yeah. That's right. – SmallChess Jun 8 '16 at 12:41
• It seems that the formulas in The Complete Guide don't pay dividends – user16469 Jun 9 '16 at 14:03
• @krey They do. It's known as "cost-of-carry". – SmallChess Jun 9 '16 at 14:41
• A note about the haug book - many of the formulae are gross approximations. Many of them involve inserting some single volatility per asset, and leave out the issue of choosing these vols, or that perhaps you should integrate the simple form over a distribution of vols, etc. – will Sep 29 '17 at 14:42

two things I would try...and this is really off the top of my head... is

1). to use put-call parity to check that your work makes financial sense. Call = Spot + Put - (strike price)/(1+risk_free_rate)^Time

2). see if you can recreate anything close to present/past market (Yahoo finance?) data prices, i.e. testing your model against reality.

good luck

I would tend to do the following:

If, under your working modelling assumptions, there exist closed form formulas, then compare your results to them. "The Complete Guide to Option Pricing Formulas" in @Student T is indeed a nice reference for that. Beware of true formulas vs. approximations though.

Now if it's not the case:

• Compare different pricers' implementations versus each other: e.g. Monte-Carlo vs Finite Difference. Usually the Monte-Carlo pricer is easier to develop (except for complex diffusion models requiring custom stepping schemes), so just push the number of simulations to the limits to obtain a "good" reference (again this assumes a reasonable discretisation bias).

• Use your common sense and experience: detect if there is something inherently wrong with what you're doing, of if you're not accounting for a particular aspect of the product you're pricing. In the particular case of continuously-monitored barrier you should bear in mind that, because you discretise time, you'll always miss the probability that the barrier activates/de-activates between 2 time steps, which can bias your results. You can use Brownian interpolation to improve your results.

• Use universal truths (no-arbitrage arguments) : e.g. call-put parity as mentioned in @Sason Torosean answer, but also in-out parity for barrier options for example ($V = V_{in} + V_{out}$), or an Asian option with past fixings can be seen as a new asian option starting today and re-struck at a modified strike etc.

• Validate incrementally by testing your pricer on degenerate situations where you know the price you should get: e.g. no rates nor dividends, knock-out barrier $H=S_0$ etc. Move to more and more complex situations.

• I would be very careful when comparing with third party implementations! For Black-Scholes why not, but as soon as you implement complex models, the tiniest difference in the assumptions can have an enormous impact on the results. So you're always better off validating what you did. That being said, you are rarely the first one to test a model/pricer, so it is highly likely that there exists a decent paper out there with some useful results you can refer to (but be careful!).

For a few standard option types under Black-Scholes you can also cross-check your results using this free option pricing application. It does vanillas, barriers (continuous and discrete monitoring) and Asians (arithmetic, discrete sampling), all with European/Bermudan/American exercise. It has two separate engines, PDE/Finite Differences and Monte Carlo, pseudo & quasi-random (Sobol). It does a few things that QuantLib doesn't, like American Asian options. It allows very high grid resolutions for the FD engine and up to 1 billion MC replications, all very fast (one billion(10^9) MC samples in about 20 secs, or an arithmetic Asian on a 1000 x 1000 x 200 space-time FD grid in less than a sec). It can do benchmark-level accuracy, for example I get 8-9 correct digits for american vanillas, and also get extreme agreement between the FD and MC engines in many cases (up to 8 digits)

• This is really a comment to Quantuple's reply below. Regarding continuously monitored barriers, I would clarify that Brownian interpolation is something one can use in the context of Monte Carlo, but is not applicable to FD/PDE solving for example. The pricer I linked to above does demonstrate the use of Brownian interpolation. – Yian Pap Aug 1 '16 at 16:33