{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes            #-}
{-# LANGUAGE RecordWildCards       #-}
{-# LANGUAGE ScopedTypeVariables   #-}
module Q.Options.ImpliedVol.Surface
  (
    Surface(..)
  , totalVarKT
  , fwdTotalVarKT
  , volKT)

where

import qualified Data.Map                                 as M
import qualified Data.Map.Strict                          as M
import           Data.Maybe                               (fromJust)
import           Numeric.LinearAlgebra                    hiding (maxElement,
                                                           minElement)
import qualified Q.Options.Bachelier                      as Bacherlier
import qualified Q.Options.Black76                        as B76
import           Q.Options.ImpliedVol
import           Q.Options.ImpliedVol.InterpolatingSmile
import           Q.Options.ImpliedVol.StrikeInterpolation
import           Q.Options.ImpliedVol.TimeInterpolation
import           Q.Options.ImpliedVol.TimeSlice
import           Q.SortedVector
import           Q.Types

-- | Implied volatility surface where the strikes are in the space of 'k' and
-- implied volatility time slice is 'v'.
data Surface v k = Surface
  {
    Surface v k -> Spot
surfaceSpot              :: Spot                   -- ^ Spot.
  , Surface v k -> SortedVector YearFrac
surfaceTenors            :: SortedVector YearFrac  -- ^ Ordered list of tenors.
  , Surface v k -> YearFrac -> Forward
surfaceForwardCurve      :: YearFrac -> Forward    -- ^ The forward curve.
  , Surface v k -> YearFrac -> DF
surfaceDiscountCurve     :: YearFrac -> DF         -- ^ The discount curve.
  , Surface v k -> YearFrac -> TotalVar
surfaceAtmTotalVar       :: YearFrac -> TotalVar   -- ^ A spline of the at the money total variance.
  , Surface v k -> Map YearFrac v
surfaceVols              :: M.Map YearFrac v       -- ^ Map from tenor to 'TimeSlice'
  , Surface v k -> TimeInterpolation
surfaceTimeInterpolation :: TimeInterpolation      -- ^ Method of interpolation between tenors.
  , Surface v k -> VolType
surfaceType              :: VolType                -- ^ The type of surface.
  }

totalVarKT :: (StrikeSpace k, TimeSlice v k) => Surface v k -> Strike -> YearFrac -> TotalVar
totalVarKT :: Surface v k -> Strike -> YearFrac -> TotalVar
totalVarKT surface :: Surface v k
surface@Surface{Map YearFrac v
Spot
SortedVector YearFrac
VolType
TimeInterpolation
YearFrac -> TotalVar
YearFrac -> DF
YearFrac -> Forward
surfaceType :: VolType
surfaceTimeInterpolation :: TimeInterpolation
surfaceVols :: Map YearFrac v
surfaceAtmTotalVar :: YearFrac -> TotalVar
surfaceDiscountCurve :: YearFrac -> DF
surfaceForwardCurve :: YearFrac -> Forward
surfaceTenors :: SortedVector YearFrac
surfaceSpot :: Spot
surfaceType :: forall v k. Surface v k -> VolType
surfaceTimeInterpolation :: forall v k. Surface v k -> TimeInterpolation
surfaceVols :: forall v k. Surface v k -> Map YearFrac v
surfaceAtmTotalVar :: forall v k. Surface v k -> YearFrac -> TotalVar
surfaceDiscountCurve :: forall v k. Surface v k -> YearFrac -> DF
surfaceForwardCurve :: forall v k. Surface v k -> YearFrac -> Forward
surfaceTenors :: forall v k. Surface v k -> SortedVector YearFrac
surfaceSpot :: forall v k. Surface v k -> Spot
..} Strike
k YearFrac
t | YearFrac
t YearFrac -> YearFrac -> Bool
forall a. Ord a => a -> a -> Bool
<= SortedVector YearFrac -> YearFrac
forall a. Storable a => SortedVector a -> a
minElement SortedVector YearFrac
surfaceTenors =
                                       YearFrac -> Surface v k -> Strike -> YearFrac -> TotalVar
forall v k.
(StrikeSpace k, TimeSlice v k) =>
YearFrac -> Surface v k -> Strike -> YearFrac -> TotalVar
extrapolateTotalVarFrom (SortedVector YearFrac -> YearFrac
forall a. Storable a => SortedVector a -> a
minElement SortedVector YearFrac
surfaceTenors) Surface v k
surface Strike
k YearFrac
t
                                   | YearFrac
t YearFrac -> YearFrac -> Bool
forall a. Ord a => a -> a -> Bool
>= SortedVector YearFrac -> YearFrac
forall a. Storable a => SortedVector a -> a
maxElement SortedVector YearFrac
surfaceTenors =
                                       YearFrac -> Surface v k -> Strike -> YearFrac -> TotalVar
forall v k.
(StrikeSpace k, TimeSlice v k) =>
YearFrac -> Surface v k -> Strike -> YearFrac -> TotalVar
extrapolateTotalVarFrom (SortedVector YearFrac -> YearFrac
forall a. Storable a => SortedVector a -> a
maxElement SortedVector YearFrac
surfaceTenors) Surface v k
surface Strike
k YearFrac
t
                                   | Bool
otherwise =
                                       TimeInterpolation -> Surface v k -> Strike -> YearFrac -> TotalVar
forall v k.
(StrikeSpace k, TimeSlice v k) =>
TimeInterpolation -> Surface v k -> Strike -> YearFrac -> TotalVar
timeInterpolate TimeInterpolation
surfaceTimeInterpolation Surface v k
surface Strike
k YearFrac
t


volKT :: (StrikeSpace k, TimeSlice v k) => Surface v k -> Strike -> YearFrac ->  Vol
volKT :: Surface v k -> Strike -> YearFrac -> Vol
volKT Surface v k
surface Strike
k YearFrac
t = TotalVar -> YearFrac -> Vol
totalVarToVol (Surface v k -> Strike -> YearFrac -> TotalVar
forall k v.
(StrikeSpace k, TimeSlice v k) =>
Surface v k -> Strike -> YearFrac -> TotalVar
totalVarKT Surface v k
surface Strike
k YearFrac
t) YearFrac
t

fwdTotalVarKT :: ( StrikeSpace k, TimeSlice v k) => Surface v k -> Strike -> YearFrac -> Strike -> YearFrac -> TotalVar
fwdTotalVarKT :: Surface v k -> Strike -> YearFrac -> Strike -> YearFrac -> TotalVar
fwdTotalVarKT surface :: Surface v k
surface@Surface{Map YearFrac v
Spot
SortedVector YearFrac
VolType
TimeInterpolation
YearFrac -> TotalVar
YearFrac -> DF
YearFrac -> Forward
surfaceType :: VolType
surfaceTimeInterpolation :: TimeInterpolation
surfaceVols :: Map YearFrac v
surfaceAtmTotalVar :: YearFrac -> TotalVar
surfaceDiscountCurve :: YearFrac -> DF
surfaceForwardCurve :: YearFrac -> Forward
surfaceTenors :: SortedVector YearFrac
surfaceSpot :: Spot
surfaceType :: forall v k. Surface v k -> VolType
surfaceTimeInterpolation :: forall v k. Surface v k -> TimeInterpolation
surfaceVols :: forall v k. Surface v k -> Map YearFrac v
surfaceAtmTotalVar :: forall v k. Surface v k -> YearFrac -> TotalVar
surfaceDiscountCurve :: forall v k. Surface v k -> YearFrac -> DF
surfaceForwardCurve :: forall v k. Surface v k -> YearFrac -> Forward
surfaceTenors :: forall v k. Surface v k -> SortedVector YearFrac
surfaceSpot :: forall v k. Surface v k -> Spot
..} Strike
k1 YearFrac
t1 Strike
k2 YearFrac
t2 = Double -> TotalVar
TotalVar (Double -> TotalVar) -> Double -> TotalVar
forall a b. (a -> b) -> a -> b
$ (Double
totalVarKT2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
totalVarKT1) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (YearFrac -> Double
unYearFrac YearFrac
t2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- YearFrac -> Double
unYearFrac YearFrac
t1)
  where (TotalVar Double
totalVarKT1) = Surface v k -> Strike -> YearFrac -> TotalVar
forall k v.
(StrikeSpace k, TimeSlice v k) =>
Surface v k -> Strike -> YearFrac -> TotalVar
totalVarKT Surface v k
surface Strike
k1 YearFrac
t1
        (TotalVar Double
totalVarKT2) = Surface v k -> Strike -> YearFrac -> TotalVar
forall k v.
(StrikeSpace k, TimeSlice v k) =>
Surface v k -> Strike -> YearFrac -> TotalVar
totalVarKT Surface v k
surface Strike
k2 YearFrac
t2


class StrikeSpace k where
  strikeSpaceToCash :: k -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
  cashToStrikeSpace :: Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k

instance StrikeSpace Strike where
  strikeSpaceToCash :: Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash Strike
x YearFrac
_ Spot
_ Forward
_ Vol
_ VolShift
_ = Strike
x
  cashToStrikeSpace :: Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
cashToStrikeSpace Strike
k YearFrac
_ Spot
_ Forward
_ Vol
_ VolShift
_ = Strike
k


instance StrikeSpace AbsRelStrike where
  strikeSpaceToCash :: AbsRelStrike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash (AbsRel Double
x) YearFrac
_ Spot
_ (Forward Double
f) Vol
_ VolShift
_ = Double -> Strike
Strike (Double -> Strike) -> Double -> Strike
forall a b. (a -> b) -> a -> b
$ Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
f
  cashToStrikeSpace :: Strike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> AbsRelStrike
cashToStrikeSpace (Strike Double
k) YearFrac
_ Spot
_ (Forward Double
f) Vol
_ VolShift
_ = Double -> AbsRelStrike
AbsRel (Double -> AbsRelStrike) -> Double -> AbsRelStrike
forall a b. (a -> b) -> a -> b
$ Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
f

instance StrikeSpace LogRelStrike where
  strikeSpaceToCash :: LogRelStrike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash (LogRel Double
x) YearFrac
_ Spot
_ (Forward Double
f) Vol
_ VolShift
_ = Double -> Strike
Strike (Double -> Strike) -> Double -> Strike
forall a b. (a -> b) -> a -> b
$ Double
f Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
exp Double
x
  cashToStrikeSpace :: Strike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> LogRelStrike
cashToStrikeSpace (Strike Double
k) YearFrac
_ Spot
_ (Forward Double
f) Vol
_ VolShift
_ = Double -> LogRelStrike
LogRel (Double -> LogRelStrike) -> Double -> LogRelStrike
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Floating a => a -> a
log (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
f

instance StrikeSpace MoneynessForwardStrike  where
  strikeSpaceToCash :: MoneynessForwardStrike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash (MoneynessForward Double
x) (YearFrac Double
t) Spot
_ (Forward Double
f) (Vol Double
atmVol) VolShift
_ =
    Double -> Strike
Strike (Double -> Strike) -> Double -> Strike
forall a b. (a -> b) -> a -> b
$ Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sqrt Double
t Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
atmVol Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
f

  cashToStrikeSpace :: Strike
-> YearFrac
-> Spot
-> Forward
-> Vol
-> VolShift
-> MoneynessForwardStrike
cashToStrikeSpace (Strike Double
k) (YearFrac Double
t) Spot
_ (Forward Double
f) (Vol Double
atmVol) VolShift
_ =
    Double -> MoneynessForwardStrike
MoneynessForward (Double -> MoneynessForwardStrike)
-> Double -> MoneynessForwardStrike
forall a b. (a -> b) -> a -> b
$ (Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
f) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
atmVol Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sqrt Double
t)

instance StrikeSpace LogMoneynessForwardStrike  where
  strikeSpaceToCash :: LogMoneynessForwardStrike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash (LogMoneynessForward Double
x) (YearFrac Double
t) Spot
_ (Forward Double
f) (Vol Double
atmVol) (VolShift Double
slnShift) =
    Double -> Strike
Strike (Double -> Strike) -> Double -> Strike
forall a b. (a -> b) -> a -> b
$ (Double
f Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
slnShift) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
exp (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sqrt Double
t) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
atmVol) Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
slnShift

  cashToStrikeSpace :: Strike
-> YearFrac
-> Spot
-> Forward
-> Vol
-> VolShift
-> LogMoneynessForwardStrike
cashToStrikeSpace (Strike Double
k) (YearFrac Double
t)  Spot
_ (Forward Double
f) (Vol Double
atmVol) (VolShift Double
slnShift) =
    Double -> LogMoneynessForwardStrike
LogMoneynessForward (Double -> LogMoneynessForwardStrike)
-> Double -> LogMoneynessForwardStrike
forall a b. (a -> b) -> a -> b
$ (Double -> Double
forall a. Floating a => a -> a
log ((Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
slnShift) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
f Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
slnShift))) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
atmVol Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sqrt Double
t)

instance StrikeSpace LogMoneynessSpotStrike  where
  strikeSpaceToCash :: LogMoneynessSpotStrike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash (LogMoneynessSpot Double
x) (YearFrac Double
t) (Spot Double
s) Forward
_ (Vol Double
atmVol) (VolShift Double
slnShift) =
    Double -> Strike
Strike (Double -> Strike) -> Double -> Strike
forall a b. (a -> b) -> a -> b
$ (Double
s Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
slnShift) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
exp (Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sqrt Double
t) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
atmVol) Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
slnShift

  cashToStrikeSpace :: Strike
-> YearFrac
-> Spot
-> Forward
-> Vol
-> VolShift
-> LogMoneynessSpotStrike
cashToStrikeSpace (Strike Double
k) (YearFrac Double
t)  (Spot Double
s) Forward
_ (Vol Double
atmVol) (VolShift Double
slnShift) =
    Double -> LogMoneynessSpotStrike
LogMoneynessSpot (Double -> LogMoneynessSpotStrike)
-> Double -> LogMoneynessSpotStrike
forall a b. (a -> b) -> a -> b
$ (Double -> Double
forall a. Floating a => a -> a
log ((Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
slnShift) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
s Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
slnShift))) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
atmVol Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sqrt Double
t)

instance StrikeSpace MoneynessSpotStrike  where
  strikeSpaceToCash :: MoneynessSpotStrike
-> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash (MoneynessSpot Double
x) (YearFrac Double
t) (Spot Double
s) Forward
_ (Vol Double
atmVol) VolShift
_ =
    Double -> Strike
Strike (Double -> Strike) -> Double -> Strike
forall a b. (a -> b) -> a -> b
$ Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sqrt Double
t) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
atmVol Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
s

  cashToStrikeSpace :: Strike
-> YearFrac
-> Spot
-> Forward
-> Vol
-> VolShift
-> MoneynessSpotStrike
cashToStrikeSpace (Strike Double
k) (YearFrac Double
t) (Spot Double
s) Forward
_ (Vol Double
atmVol) VolShift
_ =
    Double -> MoneynessSpotStrike
MoneynessSpot (Double -> MoneynessSpotStrike) -> Double -> MoneynessSpotStrike
forall a b. (a -> b) -> a -> b
$ (Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
s) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
atmVol Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Floating a => a -> a
sqrt Double
t)


slnShift :: Surface v k -> VolShift
slnShift Surface{Map YearFrac v
Spot
SortedVector YearFrac
VolType
TimeInterpolation
YearFrac -> TotalVar
YearFrac -> DF
YearFrac -> Forward
surfaceType :: VolType
surfaceTimeInterpolation :: TimeInterpolation
surfaceVols :: Map YearFrac v
surfaceAtmTotalVar :: YearFrac -> TotalVar
surfaceDiscountCurve :: YearFrac -> DF
surfaceForwardCurve :: YearFrac -> Forward
surfaceTenors :: SortedVector YearFrac
surfaceSpot :: Spot
surfaceType :: forall v k. Surface v k -> VolType
surfaceTimeInterpolation :: forall v k. Surface v k -> TimeInterpolation
surfaceVols :: forall v k. Surface v k -> Map YearFrac v
surfaceAtmTotalVar :: forall v k. Surface v k -> YearFrac -> TotalVar
surfaceDiscountCurve :: forall v k. Surface v k -> YearFrac -> DF
surfaceForwardCurve :: forall v k. Surface v k -> YearFrac -> Forward
surfaceTenors :: forall v k. Surface v k -> SortedVector YearFrac
surfaceSpot :: forall v k. Surface v k -> Spot
..} = case VolType
surfaceType of
  (ShiftedLogNormal VolShift
shift) -> VolShift
shift
  VolType
_                        -> Double -> VolShift
VolShift Double
0
extrapolateTotalVarFrom :: forall v k. (StrikeSpace k, TimeSlice v k) => YearFrac -> Surface v k -> Strike -> YearFrac -> TotalVar
extrapolateTotalVarFrom :: YearFrac -> Surface v k -> Strike -> YearFrac -> TotalVar
extrapolateTotalVarFrom YearFrac
t0 surface :: Surface v k
surface@Surface{Map YearFrac v
Spot
SortedVector YearFrac
VolType
TimeInterpolation
YearFrac -> TotalVar
YearFrac -> DF
YearFrac -> Forward
surfaceType :: VolType
surfaceTimeInterpolation :: TimeInterpolation
surfaceVols :: Map YearFrac v
surfaceAtmTotalVar :: YearFrac -> TotalVar
surfaceDiscountCurve :: YearFrac -> DF
surfaceForwardCurve :: YearFrac -> Forward
surfaceTenors :: SortedVector YearFrac
surfaceSpot :: Spot
surfaceType :: forall v k. Surface v k -> VolType
surfaceTimeInterpolation :: forall v k. Surface v k -> TimeInterpolation
surfaceVols :: forall v k. Surface v k -> Map YearFrac v
surfaceAtmTotalVar :: forall v k. Surface v k -> YearFrac -> TotalVar
surfaceDiscountCurve :: forall v k. Surface v k -> YearFrac -> DF
surfaceForwardCurve :: forall v k. Surface v k -> YearFrac -> Forward
surfaceTenors :: forall v k. Surface v k -> SortedVector YearFrac
surfaceSpot :: forall v k. Surface v k -> Spot
..} Strike
k YearFrac
t = let
  f0 :: Forward
f0          = YearFrac -> Forward
surfaceForwardCurve YearFrac
t0
  atmVol0 :: Vol
atmVol0     = TotalVar -> YearFrac -> Vol
totalVarToVol (YearFrac -> TotalVar
surfaceAtmTotalVar YearFrac
t0) YearFrac
t0
  f :: Forward
f           = YearFrac -> Forward
surfaceForwardCurve YearFrac
t
  spot :: Spot
spot        = Spot
surfaceSpot
  atmTotalVar :: TotalVar
atmTotalVar = YearFrac -> TotalVar
surfaceAtmTotalVar YearFrac
t
  atmVol :: Vol
atmVol      = TotalVar -> YearFrac -> Vol
totalVarToVol TotalVar
atmTotalVar YearFrac
t
  x :: k
x           = Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
forall k.
StrikeSpace k =>
Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
cashToStrikeSpace Strike
k YearFrac
t Spot
spot Forward
f Vol
atmVol (Surface v k -> VolShift
forall v k. Surface v k -> VolShift
slnShift Surface v k
surface)::k
  k' :: Strike
k'          = k -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
forall k.
StrikeSpace k =>
k -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> Strike
strikeSpaceToCash k
x YearFrac
t0 Spot
spot Forward
f0 Vol
atmVol0 (Surface v k -> VolShift
forall v k. Surface v k -> VolShift
slnShift Surface v k
surface)
  x' :: k
x'          = Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
forall k.
StrikeSpace k =>
Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
cashToStrikeSpace Strike
k' YearFrac
t0 Spot
spot Forward
f0 Vol
atmVol (Surface v k -> VolShift
forall v k. Surface v k -> VolShift
slnShift Surface v k
surface)::k
  in v -> k -> TotalVar
forall v k. TimeSlice v k => v -> k -> TotalVar
totalVar (Map YearFrac v
surfaceVols Map YearFrac v -> YearFrac -> v
forall k a. Ord k => Map k a -> k -> a
M.! YearFrac
t0) k
x'


timeInterpolate :: forall v k. (StrikeSpace k, TimeSlice v k) => TimeInterpolation -> Surface v k -> Strike -> YearFrac -> TotalVar
timeInterpolate :: TimeInterpolation -> Surface v k -> Strike -> YearFrac -> TotalVar
timeInterpolate TimeInterpolation
Gatheral surface :: Surface v k
surface@Surface{Map YearFrac v
Spot
SortedVector YearFrac
VolType
TimeInterpolation
YearFrac -> TotalVar
YearFrac -> DF
YearFrac -> Forward
surfaceType :: VolType
surfaceTimeInterpolation :: TimeInterpolation
surfaceVols :: Map YearFrac v
surfaceAtmTotalVar :: YearFrac -> TotalVar
surfaceDiscountCurve :: YearFrac -> DF
surfaceForwardCurve :: YearFrac -> Forward
surfaceTenors :: SortedVector YearFrac
surfaceSpot :: Spot
surfaceType :: forall v k. Surface v k -> VolType
surfaceTimeInterpolation :: forall v k. Surface v k -> TimeInterpolation
surfaceVols :: forall v k. Surface v k -> Map YearFrac v
surfaceAtmTotalVar :: forall v k. Surface v k -> YearFrac -> TotalVar
surfaceDiscountCurve :: forall v k. Surface v k -> YearFrac -> DF
surfaceForwardCurve :: forall v k. Surface v k -> YearFrac -> Forward
surfaceTenors :: forall v k. Surface v k -> SortedVector YearFrac
surfaceSpot :: forall v k. Surface v k -> Spot
..} Strike
k11 YearFrac
t =
  let (YearFrac
t1, v
smile1) = Maybe (YearFrac, v) -> (YearFrac, v)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (YearFrac, v) -> (YearFrac, v))
-> Maybe (YearFrac, v) -> (YearFrac, v)
forall a b. (a -> b) -> a -> b
$ YearFrac -> Map YearFrac v -> Maybe (YearFrac, v)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupLE YearFrac
t Map YearFrac v
surfaceVols
      (YearFrac
t2, v
smile2) = Maybe (YearFrac, v) -> (YearFrac, v)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (YearFrac, v) -> (YearFrac, v))
-> Maybe (YearFrac, v) -> (YearFrac, v)
forall a b. (a -> b) -> a -> b
$ YearFrac -> Map YearFrac v -> Maybe (YearFrac, v)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupGE YearFrac
t Map YearFrac v
surfaceVols
      (TotalVar Double
thetaT)  = YearFrac -> TotalVar
surfaceAtmTotalVar YearFrac
t
      (TotalVar Double
thetaT1) = YearFrac -> TotalVar
surfaceAtmTotalVar YearFrac
t1
      (TotalVar Double
thetaT2) = YearFrac -> TotalVar
surfaceAtmTotalVar YearFrac
t2
      alphaT :: Double
alphaT  = (Double -> Double
forall a. Floating a => a -> a
sqrt Double
thetaT2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double -> Double
forall a. Floating a => a -> a
sqrt Double
thetaT1 ) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double -> Double
forall a. Floating a => a -> a
sqrt Double
thetaT1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double -> Double
forall a. Floating a => a -> a
sqrt Double
thetaT)
      atmVol :: Vol
atmVol  = TotalVar -> YearFrac -> Vol
totalVarToVol (Double -> TotalVar
TotalVar Double
thetaT) YearFrac
t
      (Forward Double
f)  = YearFrac -> Forward
surfaceForwardCurve YearFrac
t
      (Forward Double
f1) = YearFrac -> Forward
surfaceForwardCurve YearFrac
t1
      (Forward Double
f2) = YearFrac -> Forward
surfaceForwardCurve YearFrac
t2
      df :: DF
df  = YearFrac -> DF
surfaceDiscountCurve YearFrac
t
      df1 :: DF
df1 = YearFrac -> DF
surfaceDiscountCurve YearFrac
t1
      df2 :: DF
df2 = YearFrac -> DF
surfaceDiscountCurve YearFrac
t2
      k1 :: Strike
k1      = Strike
k11 Strike -> Double -> Strike
forall a b. (Coercible a Double, Coercible b Double) => a -> b -> a
$*$ (Double
f1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
f)
      k2 :: Strike
k2      = Strike
k11 Strike -> Double -> Strike
forall a b. (Coercible a Double, Coercible b Double) => a -> b -> a
$*$ (Double
f2 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
f)
      x1 :: k
x1      = Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
forall k.
StrikeSpace k =>
Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
cashToStrikeSpace Strike
k1 YearFrac
t1 Spot
surfaceSpot (Double -> Forward
Forward Double
f1) Vol
atmVol (Surface v k -> VolShift
forall v k. Surface v k -> VolShift
slnShift Surface v k
surface)::k
      x2 :: k
x2      = Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
forall k.
StrikeSpace k =>
Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
cashToStrikeSpace Strike
k2 YearFrac
t2 Spot
surfaceSpot (Double -> Forward
Forward Double
f2) Vol
atmVol (Surface v k -> VolShift
forall v k. Surface v k -> VolShift
slnShift Surface v k
surface)::k
      vol1 :: Vol
vol1 = TotalVar -> YearFrac -> Vol
totalVarToVol (v -> k -> TotalVar
forall v k. TimeSlice v k => v -> k -> TotalVar
totalVar v
smile1 k
x1) YearFrac
t1
      vol2 :: Vol
vol2 = TotalVar -> YearFrac -> Vol
totalVarToVol (v -> k -> TotalVar
forall v k. TimeSlice v k => v -> k -> TotalVar
totalVar v
smile2  k
x2) YearFrac
t2
      (Premium Double
premium1) = Valuation -> Premium
vPremium (Valuation -> Premium) -> Valuation -> Premium
forall a b. (a -> b) -> a -> b
$ VolType -> Strike -> Double -> DF -> YearFrac -> Vol -> Valuation
euOption VolType
surfaceType Strike
k1 Double
f1 DF
df1 YearFrac
t1 Vol
vol1
      (Premium Double
premium2) = Valuation -> Premium
vPremium (Valuation -> Premium) -> Valuation -> Premium
forall a b. (a -> b) -> a -> b
$ VolType -> Strike -> Double -> DF -> YearFrac -> Vol -> Valuation
euOption VolType
surfaceType Strike
k1 Double
f2 DF
df2 YearFrac
t1 Vol
vol1
      premiumT :: Premium
premiumT  = Double -> Premium
Premium (Double -> Premium) -> Double -> Premium
forall a b. (a -> b) -> a -> b
$ (Double
alphaT Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
premium1 Double -> Strike -> Double
forall a b. (Coercible a Double, Coercible b Double) => a -> b -> a
$/$ Strike
k1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (Double
1Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
alphaT)Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
premium2 Double -> Strike -> Double
forall a b. (Coercible a Double, Coercible b Double) => a -> b -> a
$/$ Strike
k2) Double -> Strike -> Double
forall a b. (Coercible a Double, Coercible b Double) => a -> b -> a
$*$ Strike
k11
      x1 :: k
      x2 :: k
  in if VolType
surfaceType VolType -> VolType -> Bool
forall a. Eq a => a -> a -> Bool
== VolType
Normal then
       Vol -> YearFrac -> TotalVar
volToTotalVar (VolType
-> OptionType
-> Forward
-> Strike
-> YearFrac
-> DF
-> Premium
-> Vol
euImpliedVol VolType
Normal OptionType
Call (Double -> Forward
Forward Double
f) Strike
k11 YearFrac
t DF
df Premium
premiumT) YearFrac
t
     else
       Vol -> YearFrac -> TotalVar
volToTotalVar (VolType
-> OptionType
-> Forward
-> Strike
-> YearFrac
-> DF
-> Premium
-> Vol
euImpliedVol VolType
LogNormal OptionType
Call (Double -> Forward
Forward Double
f) Strike
k11 YearFrac
t DF
df Premium
premiumT) YearFrac
t

timeInterpolate TimeInterpolation
LinearInVol surface :: Surface v k
surface@Surface{Map YearFrac v
Spot
SortedVector YearFrac
VolType
TimeInterpolation
YearFrac -> TotalVar
YearFrac -> DF
YearFrac -> Forward
surfaceType :: VolType
surfaceTimeInterpolation :: TimeInterpolation
surfaceVols :: Map YearFrac v
surfaceAtmTotalVar :: YearFrac -> TotalVar
surfaceDiscountCurve :: YearFrac -> DF
surfaceForwardCurve :: YearFrac -> Forward
surfaceTenors :: SortedVector YearFrac
surfaceSpot :: Spot
surfaceType :: forall v k. Surface v k -> VolType
surfaceTimeInterpolation :: forall v k. Surface v k -> TimeInterpolation
surfaceVols :: forall v k. Surface v k -> Map YearFrac v
surfaceAtmTotalVar :: forall v k. Surface v k -> YearFrac -> TotalVar
surfaceDiscountCurve :: forall v k. Surface v k -> YearFrac -> DF
surfaceForwardCurve :: forall v k. Surface v k -> YearFrac -> Forward
surfaceTenors :: forall v k. Surface v k -> SortedVector YearFrac
surfaceSpot :: forall v k. Surface v k -> Spot
..} Strike
k YearFrac
t =
  let f :: Forward
f = YearFrac -> Forward
surfaceForwardCurve YearFrac
t
      atmVol :: Vol
atmVol = TotalVar -> YearFrac -> Vol
totalVarToVol (YearFrac -> TotalVar
surfaceAtmTotalVar YearFrac
t) YearFrac
t
      x :: k
x      = Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
forall k.
StrikeSpace k =>
Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
cashToStrikeSpace Strike
k YearFrac
t Spot
surfaceSpot Forward
f Vol
atmVol (Surface v k -> VolShift
forall v k. Surface v k -> VolShift
slnShift Surface v k
surface)::k
      (YearFrac
t1, v
smile1) = Maybe (YearFrac, v) -> (YearFrac, v)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (YearFrac, v) -> (YearFrac, v))
-> Maybe (YearFrac, v) -> (YearFrac, v)
forall a b. (a -> b) -> a -> b
$ YearFrac -> Map YearFrac v -> Maybe (YearFrac, v)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupLE YearFrac
t Map YearFrac v
surfaceVols
      (YearFrac
t2, v
smile2) = Maybe (YearFrac, v) -> (YearFrac, v)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (YearFrac, v) -> (YearFrac, v))
-> Maybe (YearFrac, v) -> (YearFrac, v)
forall a b. (a -> b) -> a -> b
$ YearFrac -> Map YearFrac v -> Maybe (YearFrac, v)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupGE YearFrac
t Map YearFrac v
surfaceVols
      (Vol Double
vol1)         = TotalVar -> YearFrac -> Vol
totalVarToVol (v -> k -> TotalVar
forall v k. TimeSlice v k => v -> k -> TotalVar
totalVar v
smile1 k
x) YearFrac
t1
      (Vol Double
vol2)         = TotalVar -> YearFrac -> Vol
totalVarToVol (v -> k -> TotalVar
forall v k. TimeSlice v k => v -> k -> TotalVar
totalVar v
smile2 k
x) YearFrac
t2
  in Vol -> YearFrac -> TotalVar
volToTotalVar (Double -> Vol
Vol (Double -> Vol) -> Double -> Vol
forall a b. (a -> b) -> a -> b
$ (YearFrac, Double) -> (YearFrac, Double) -> YearFrac -> Double
linearInterpolate (YearFrac
t1, Double
vol1) (YearFrac
t2, Double
vol2) YearFrac
t) YearFrac
t

timeInterpolate TimeInterpolation
LinearInTotalVar surface :: Surface v k
surface@Surface{Map YearFrac v
Spot
SortedVector YearFrac
VolType
TimeInterpolation
YearFrac -> TotalVar
YearFrac -> DF
YearFrac -> Forward
surfaceType :: VolType
surfaceTimeInterpolation :: TimeInterpolation
surfaceVols :: Map YearFrac v
surfaceAtmTotalVar :: YearFrac -> TotalVar
surfaceDiscountCurve :: YearFrac -> DF
surfaceForwardCurve :: YearFrac -> Forward
surfaceTenors :: SortedVector YearFrac
surfaceSpot :: Spot
surfaceType :: forall v k. Surface v k -> VolType
surfaceTimeInterpolation :: forall v k. Surface v k -> TimeInterpolation
surfaceVols :: forall v k. Surface v k -> Map YearFrac v
surfaceAtmTotalVar :: forall v k. Surface v k -> YearFrac -> TotalVar
surfaceDiscountCurve :: forall v k. Surface v k -> YearFrac -> DF
surfaceForwardCurve :: forall v k. Surface v k -> YearFrac -> Forward
surfaceTenors :: forall v k. Surface v k -> SortedVector YearFrac
surfaceSpot :: forall v k. Surface v k -> Spot
..} Strike
k YearFrac
t =
  let f :: Forward
f = YearFrac -> Forward
surfaceForwardCurve YearFrac
t
      atmVol :: Vol
atmVol = TotalVar -> YearFrac -> Vol
totalVarToVol (YearFrac -> TotalVar
surfaceAtmTotalVar YearFrac
t) YearFrac
t
      x :: k
x      = Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
forall k.
StrikeSpace k =>
Strike -> YearFrac -> Spot -> Forward -> Vol -> VolShift -> k
cashToStrikeSpace Strike
k YearFrac
t Spot
surfaceSpot Forward
f Vol
atmVol (Surface v k -> VolShift
forall v k. Surface v k -> VolShift
slnShift Surface v k
surface)::k
      (YearFrac
t1, v
smile1) = Maybe (YearFrac, v) -> (YearFrac, v)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (YearFrac, v) -> (YearFrac, v))
-> Maybe (YearFrac, v) -> (YearFrac, v)
forall a b. (a -> b) -> a -> b
$ YearFrac -> Map YearFrac v -> Maybe (YearFrac, v)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupLE YearFrac
t Map YearFrac v
surfaceVols
      (YearFrac
t2, v
smile2) = Maybe (YearFrac, v) -> (YearFrac, v)
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (YearFrac, v) -> (YearFrac, v))
-> Maybe (YearFrac, v) -> (YearFrac, v)
forall a b. (a -> b) -> a -> b
$ YearFrac -> Map YearFrac v -> Maybe (YearFrac, v)
forall k v. Ord k => k -> Map k v -> Maybe (k, v)
M.lookupGE YearFrac
t Map YearFrac v
surfaceVols
      (TotalVar Double
tv1)         = v -> k -> TotalVar
forall v k. TimeSlice v k => v -> k -> TotalVar
totalVar v
smile1 k
x
      (TotalVar Double
tv2)         = v -> k -> TotalVar
forall v k. TimeSlice v k => v -> k -> TotalVar
totalVar v
smile2 k
x
  in Double -> TotalVar
TotalVar (Double -> TotalVar) -> Double -> TotalVar
forall a b. (a -> b) -> a -> b
$ (YearFrac, Double) -> (YearFrac, Double) -> YearFrac -> Double
linearInterpolate (YearFrac
t1, Double
tv1) (YearFrac
t2, Double
tv2) YearFrac
t

euOption :: VolType -> Strike -> Double -> DF -> YearFrac -> Vol -> Valuation
euOption VolType
Normal Strike
k Double
f (DF Double
df) (YearFrac Double
t) Vol
vol =
  let r :: Rate
r = Double -> Rate
Rate (Double -> Rate) -> Double -> Rate
forall a b. (a -> b) -> a -> b
$ -(Double -> Double
forall a. Floating a => a -> a
log Double
df) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
t
      bacherlier :: Bachelier
bacherlier = Forward -> Rate -> Vol -> Bachelier
Bacherlier.Bachelier (Double -> Forward
Forward Double
f) Rate
r Vol
vol
  in Bachelier -> YearFrac -> Strike -> Valuation
Bacherlier.eucall Bachelier
bacherlier (Double -> YearFrac
YearFrac Double
t) Strike
k

euOption VolType
_ Strike
k Double
f DF
df YearFrac
t Vol
vol =
  let b76 :: Black76
b76 = Forward -> DF -> YearFrac -> Vol -> Black76
B76.Black76 (Double -> Forward
Forward Double
f) DF
df YearFrac
t Vol
vol
  in Black76 -> Strike -> Valuation
B76.eucall Black76
b76 Strike
k

linearInterpolate :: (YearFrac, Double) -> (YearFrac, Double) -> YearFrac -> Double
linearInterpolate (YearFrac Double
t1, Double
v1) (YearFrac Double
t2, Double
v2) (YearFrac Double
t) =
  Double
v1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (Double
v2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
v1)Double -> Double -> Double
forall a. Num a => a -> a -> a
*(Double
t Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t1) Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Double
t2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t1)