Put call parity is an important relationship in options pricing. Let's test our prices to see if they obey this relationship.
To do so I add a simple helper function to payoff.ml to get the npv of some future cash:
(* get the net present value of some amount *)
let npv ~amt ~rate ~time = amt *. exp(-1.0 *. rate *. time);;
...and the tests themselves. Note that the put/call parity relationship for digitals is slightly different:
let assert_nearly ?(tolerance = 0.001) label a b =
Printf.printf "Test %s - a: %f b: %f\n" label a b;
assert( abs_float(a-.b) <tolerance );;
let spot = 1.613 in
let expiry = 0.25 in
let r = 0.055 in
let strike = 1.600 in
let discount x = Payoff.npv ~rate:r ~time:expiry ~amt:x in
let mc payoff =
Mc1c.sim
~payoff:payoff
~expiry:expiry
~spot:spot
~vol:0.35
~r:r
~num_paths:100000 in
let price payoff = mc (payoff ~strike:strike) in
assert_nearly
"Put call parity"
((price Payoff.call) +. (discount strike))
((price Payoff.put) +. spot);
assert_nearly
~tolerance:0.01
"Digital put/digital call parity"
((price Payoff.digital_put) +. (price Payoff.digital_call))
(discount 1.0)
;;
Here's the output:
Test Put call parity - a: 1.707748 b: 1.708199
Test Digital put/digital call parity - a: 0.982665 b: 0.986344
Trebles all round! The prices are ok. It's also interesting that ocaml is actually even faster than I thought. I was running bytecode and if you use ocamlopt to create native code my examples run about five times faster.
permalink Updated: 2007-06-13