Saturday 29 November 2008

Computing confidence intervals

The function simulPayoffs of our first program generates a list of n simulated payoffs for a given option. Then, to estimate the price of the option, we compute its mean using the following function:

//Compute the mean of a list
let mean list = Seq.fold (+) 0.0 list / float (Seq.length list)

In order to estimate the statistical error of this result, we define a function which computes the standard deviation of a list:

//Compute the estimated standard deviation of a list
let standardDeviation list =
let m = mean list
Seq.sumByFloat(fun x -> (x - m)**2.0) list
/ float (Seq.length list - 1)

And using the central limit theorem we can also define function which computes a confidence interval for our price estimation:

//Compute a 1-p confidence interval for p in (0,1)
let confidenceInterval list p =
let m = mean list
let sigma = standardDeviation list
let quantile = 1.0-(p/2.0) |> NormalCDFInverse
let n = Seq.length list
let size = quantile*sigma/Math.Sqrt(float n)
(m - size, m + size)

Let's test these functions on a simple European option:

let T = 0.3 //maturity
let strike = 102.5 //strike
let S0 = 100.0 //current underlying price
let r = 0.06 //risk free rate
let sigma = 0.19 //volatility
let n = 100000 //number of simulations

let call = SimpleOption(Call, strike, T)

let simul = simulPayoffs call S0 r T sigma n //simulated payoffs

let price = mean simul // estimated price
let sd = standardDeviation simul // standard deviation
let ic95 = confidenceInterval simul 0.05 // 95% CI
let ic99 = confidenceInterval simul 0.01 // 99% CI


Console.WriteLine ("price: " + price.ToString())
Console.WriteLine ("standard deviation: " + sd.ToString())
Console.Write "95% confidence interval: "
print_any ic95
Console.Write "\n99% confidence interval: "
print_any ic99


Output:
price: 3.86677460654713
standard deviation: 39.7853613645219
95% confidence interval: (3.620132697, 4.113416516)
99% confidence interval: (3.542652267, 4.190896946)

Sunday 2 November 2008

Adding a new option type

Adding a new option type to this Monte Carlo pricer is very easy: For example, let's suppose that we want to price an option with two barriers which pays one if the price of the underlying is between these barriers, zero otherwise. We just need to add one line to option.fs to define a new type for two barriers options, and add a new case to our payoff function in payoff.fs:

//option.fs file
#light

type optionType = Call | Put

//oneBarrierOption: (call or put, strike, expiry)
type oneBarrierOption = optionType * float * float

//twoBarriersOption:
// (call or put, lowerBarrier, upperBarrier, expiry)

type twoBarriersOption = optionType * float * float * float

type EuropeanOption = SimpleOption of oneBarrierOption
| DigitalOption of oneBarrierOption
| TwoBarriersDigitalOption of twoBarriersOption


//payoffs.fs file
#light
open System
open Options

let payoff myOption spot =
match myOption with

| SimpleOption (payoffType, strike, _) -> match payoffType with
| Call -> max(spot - strike) 0.0
| Put -> max(strike - spot) 0.0

| DigitalOption (payoffType, strike, _) -> match payoffType with
| Call -> if(spot > strike) then 1.0 else 0.0
| Put -> if(spot < strike) then 1.0 else 0.0

| TwoBarriersDigitalOption (_, lower, upper, _) ->
if(spot > lower && spot < upper)
then 1.0
else 0.0


We can now price this kind of option:


//main.fs file
#light

open System
open Options
open Payoffs
open Montecarlo

let T = 0.3 //maturity
let strikeInf = 99.5 //lower barrier
let strikeSup = 102.5 //upper barrier
let S0 = 100.0 //current underlying price
let r = 0.06 //risk free rate
let sigma = 0.19 //volatility
let n = 100000 //number of simulations

let myOption
= TwoBarriersDigitalOption(Call, strikeInf, strikeSup, T)

let price = mean (simulPayoffs myOption S0 r T sigma n)

print_any price

output:
0.1111708073