module Quant.VolSurf (
VolSurf (..)
, FlatSurf (..)
) where
import Quant.YieldCurve
class VolSurf a where
vol :: VolSurf a => a -> Double -> Double -> Double
var :: VolSurf a => a -> Double -> Double -> Double
var vs s t = v*v*t
where v = vol vs s t
localVol :: (VolSurf a, YieldCurve b) => a
-> Double
-> b
-> Double
-> Double
-> Double
localVol v s0 rcurve k t
| w==0.0 || solution<0.0 = sqrt dwdt
| otherwise = sqrt solution
where
dr = disc rcurve t
f = s0/dr
y = log $ k/f
dy = 1.0E-6
[kp, km] = [k*exp dy, k/exp dy]
[w, wp, wm] = map (\x->var v (x/s0) t) [k, kp, km]
dwdy = (wpwm)/2.0/dy
d2wdy2 = (wp2.0*w+wm)/dy/dy
dt = min 0.0001 (t/2.0)
dwdt = let
strikept = k*dr/drpt
strikemt = k*dr/drmt
drpt = disc rcurve $ t+dt
drmt = disc rcurve $ tdt
in case t of
0 -> (var v (strikept/s0) (t+dt) w)/dt
_ -> (var v (strikept/s0) (t+dt)var v (strikemt/s0) (tdt))/2.0/dt
solution = dwdt/(1.0y/w*dwdy+0.25*(0.251.0/w+y*y/w/w)*dwdy*dwdy+0.5*d2wdy2)
data FlatSurf = FlatSurf Double
instance VolSurf FlatSurf where
vol (FlatSurf x) _ _ = x