HQu-0.0.0.0: src/Q/Options/BlackScholes.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
module Q.Options.BlackScholes (
BlackScholes(..)
, atmf
, euOption
, eucall
, euput
, module Q.Options
) where
import Control.Monad.State
import Data.Random hiding (Gamma)
import Data.Time
import Numeric.RootFinding
import Q.ContingentClaim.Options
import Q.MonteCarlo
import Q.Options
import Q.Stochastic.Discretize
import Q.Stochastic.Process
import Q.Time
import Q.Types
import Statistics.Distribution (cumulative, density)
import Statistics.Distribution.Normal (standard)
import qualified Q.Options.Black76 as B76
dcf = dcYearFraction ThirtyUSA
-- | Parameters for a simplified black scholes equation.
data BlackScholes = BlackScholes {
bsSpot :: Spot -- ^ The asset's spot on the valuation date.
, bsRate :: Rate -- ^ Risk free rate.
, bsVol :: Vol -- ^ Volatility.
} deriving Show
instance Model BlackScholes Double where
discountFactor BlackScholes{..} t1 t2 = return $ exp (scale dt bsRate)
where dt = t2 - t1
evolve (BlackScholes spot (Rate r) (Vol sigma)) (YearFrac t) = do
(YearFrac t0, s0) <- get
let dt = t - t0
dw <- (lift stdNormal)::StateT (YearFrac, Double) RVar Double
let st = s0 * exp ((r - 0.5 * sigma * sigma) * dt + sigma * dw * sqrt dt)
put (YearFrac t, st)
return st
atmf :: BlackScholes -> YearFrac -> Strike
atmf BlackScholes{..} t = Strike $ s / d where
(Rate d) = exp (scale t (-bsRate))
(Spot s) = bsSpot
-- | European option valuation with black scholes.
euOption :: BlackScholes -> YearFrac -> OptionType -> Strike ->Valuation
euOption bs@BlackScholes{..} t cp k =
let b76 = B76.Black76 {
b76F = forward bs t
, b76DF = Q.Types.discountFactor t bsRate
, b76T = t
, b76Vol = bsVol
}
in B76.euOption b76 cp k
-- | see 'euOption'
euput bs t = euOption bs t Put
-- | see 'euOption'
eucall bs t = euOption bs t Call
forward BlackScholes{..} (YearFrac t) = Forward $ s * exp (r * t)
where (Spot s) = bsSpot
(Rate r) = bsRate
corradoMillerIniitalGuess bs@BlackScholes{..} cp (Strike k) (YearFrac t) (Premium premium) =
(recip $ sqrt t) * ((sqrt (2 * pi)/ (s + discountedStrike)) + (premium - (s - discountedStrike)/2) + sqrt ((premium - (s - discountedStrike)/2)**2 - ((s - discountedStrike)**2/pi))) where
discountedStrike = k * (exp $ (-r) * t)
(Rate r) = bsRate
(Spot s) = bsSpot