-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Quant finance library in pure Haskell. -- @package quantfin @version 0.2.0.0 module Quant.VectorOps (.*.) :: (Unbox a, Num a) => Vector a -> Vector a -> Vector a (.*) :: (Unbox a, Num a) => Vector a -> a -> Vector a (*.) :: (Unbox a, Num a) => a -> Vector a -> Vector a (./.) :: (Unbox a, Fractional a) => Vector a -> Vector a -> Vector a (/.) :: (Unbox a, Fractional a) => a -> Vector a -> Vector a (./) :: (Unbox a, Fractional a) => Vector a -> a -> Vector a (.+.) :: (Unbox a, Num a) => Vector a -> Vector a -> Vector a (.+) :: (Unbox a, Num a) => Vector a -> a -> Vector a (+.) :: (Unbox a, Num a) => a -> Vector a -> Vector a (.-.) :: (Unbox a, Num a) => Vector a -> Vector a -> Vector a (.-) :: (Unbox a, Num a) => Vector a -> a -> Vector a (-.) :: (Unbox a, Num a) => a -> Vector a -> Vector a module Quant.RNG.MWC64X data MWC64X MWC64X :: {-# UNPACK #-} !Word64 -> MWC64X randomWord32 :: MWC64X -> (Word32, MWC64X) randomWord64 :: MWC64X -> (Word64, MWC64X) randomInt :: MWC64X -> (Int, MWC64X) randomDouble :: MWC64X -> (Double, MWC64X) randomInt64 :: MWC64X -> (Int64, MWC64X) skip :: MWC64X -> Word64 -> MWC64X instance Eq MWC64X instance Show MWC64X instance RandomGen MWC64X module Quant.Models.Processes data ProcessSpec ProcessSpec :: {-# UNPACK #-} !Double -> !Double -> !Double -> ProcessSpec normal :: ProcessSpec -> Double -> Double -> Double lognormal :: ProcessSpec -> Double -> Double -> Double module Quant.Math.Utilities -- | Tridiagonal matrix solver. Pretty simple. tdmaSolver :: (Fractional a, Ord a) => [a] -> [a] -> [a] -> [a] -> [a] -- | Something similar to cotraverse in the Distributive package, but -- specialized to unboxed vectors, which are not functors. cotraverseVec :: (Unbox b1, Unbox b, Functor f) => (f b1 -> b) -> Int -> f (Vector b1) -> Vector b module Quant.Math.Integration -- | A function, a lower bound, an upper bound and returns the integrated -- value. type Integrator = (Double -> Double) -> Double -> Double -> Double -- | Midpoint integration. midpoint :: Int -> Integrator -- | Trapezoidal integration. trapezoid :: Int -> Integrator -- | Integration using Simpson's rule. simpson :: Int -> Integrator module Quant.Math.Interpolation linearInterpolator :: Interpolator1d logLinearInterpolator :: Interpolator1d linearVarianceInterpolator :: Interpolator1d cSplineInterpolator :: Interpolator1d type Interpolator1d = [Double] -> [Double] -> Double -> Double module Quant.Time data Time Time :: {-# UNPACK #-} !Double -> Time timeDiff :: Time -> Time -> Double timeOffset :: Time -> Double -> Time timeFromZero :: Time -> Double instance Eq Time instance Show Time instance Ord Time module Quant.Types -- | A CashFlow is just a time and an amount. data CashFlow CashFlow :: Time -> Double -> CashFlow cfTime :: CashFlow -> Time cfAmount :: CashFlow -> Double -- | Single-observable container. data Observables1 Observables1 :: {-# UNPACK #-} !Double -> Observables1 -- | Two observable container. data Observables2 Observables2 :: {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> Observables2 -- | Three observable container. data Observables3 Observables3 :: {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> Observables3 -- | Four observable container. data Observables4 Observables4 :: {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> Observables4 -- | Five observable container. data Observables5 Observables5 :: {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> Observables5 -- | Type for Put or Calls data OptionType Put :: OptionType Call :: OptionType class Obs1 a get1 :: Obs1 a => a -> Double class Obs1 a => Obs2 a get2 :: Obs2 a => a -> Double class Obs2 a => Obs3 a get3 :: Obs3 a => a -> Double class Obs3 a => Obs4 a get4 :: Obs4 a => a -> Double class Obs4 a => Obs5 a get5 :: Obs5 a => a -> Double instance Eq OptionType instance Show OptionType instance Obs5 Observables5 instance Obs4 Observables5 instance Obs4 Observables4 instance Obs3 Observables5 instance Obs3 Observables4 instance Obs3 Observables3 instance Obs2 Observables5 instance Obs2 Observables4 instance Obs2 Observables3 instance Obs2 Observables2 instance Obs1 Observables5 instance Obs1 Observables4 instance Obs1 Observables3 instance Obs1 Observables2 instance Obs1 Observables1 module Quant.ContingentClaim -- | Key type for building contingent claims. Monoid instance allows for -- trivial combinations of contingent claims. newtype ContingentClaim a ContingentClaim :: [CCProcessor a] -> ContingentClaim a unCC :: ContingentClaim a -> [CCProcessor a] -- | Contingent claims with one observable. type ContingentClaim1 = forall a. Obs1 a => ContingentClaim a -- | Contingent claims with two observables. type ContingentClaim2 = forall a. Obs2 a => ContingentClaim a -- | Contingent claims with three observables. type ContingentClaim3 = forall a. Obs3 a => ContingentClaim a -- | Contingent claims with four observables. type ContingentClaim4 = forall a. Obs4 a => ContingentClaim a -- | Basic element of a ContingentClaim. Each element contains a -- Time. Each Time, the observables are stored in the map. Also, -- optionally a payout function may be applied at any time step. data CCProcessor a CCProcessor :: Time -> [Map Time a -> CashFlow] -> CCProcessor a monitorTime :: CCProcessor a -> Time payoutFunc :: CCProcessor a -> [Map Time a -> CashFlow] -- | Type for Put or Calls data OptionType Put :: OptionType Call :: OptionType -- | A CashFlow is just a time and an amount. data CashFlow CashFlow :: Time -> Double -> CashFlow cfTime :: CashFlow -> Time cfAmount :: CashFlow -> Double type CCBuilder w r a = WriterT w (Reader r) a -- | Pulls a ContingentClaim out of the CCBuilder monad. specify :: CCBuilder (ContingentClaim a) (Map Time a) CashFlow -> ContingentClaim a -- | monitor gets the value of the first observable at a given time. monitor :: Obs1 a => Time -> CCBuilder (ContingentClaim a) (Map Time a) Double -- | monitor1 gets the value of the first observable at a given -- time. monitor1 :: Obs1 a => Time -> CCBuilder (ContingentClaim a) (Map Time a) Double -- | monitor2 gets the value of the second observable at a given -- time. monitor2 :: Obs2 a => Time -> CCBuilder (ContingentClaim a) (Map Time a) Double -- | monitor3 gets the value of the third observable at a given -- time. monitor3 :: Obs3 a => Time -> CCBuilder (ContingentClaim a) (Map Time a) Double -- | monitor4 gets the value of the fourth observable at a given -- time. monitor4 :: Obs4 a => Time -> CCBuilder (ContingentClaim a) (Map Time a) Double -- | monitor5 gets the value of the fifth observable at a given -- time. monitor5 :: Obs5 a => Time -> CCBuilder (ContingentClaim a) (Map Time a) Double -- | Takes an OptionType, a strike, and a time to maturity and generates a -- vanilla option. vanillaOption :: Obs1 a => OptionType -> Double -> Time -> ContingentClaim a -- | Takes an OptionType, a strike, a payout amount and a time to maturity -- and generates a vanilla option. binaryOption :: Obs1 a => OptionType -> Double -> Double -> Time -> ContingentClaim a -- | A straddle is a put and a call with the same time to maturity / -- strike. straddle :: Obs1 a => Double -> Time -> ContingentClaim a -- | Takes an OptionType, a strike, observation times, time to maturity and -- generates an arithmetic Asian option. arithmeticAsianOption :: Obs1 a => OptionType -> Double -> [Time] -> Time -> ContingentClaim a -- | Takes an OptionType, a strike, observation times, time to maturity and -- generates an arithmetic Asian option. geometricAsianOption :: Obs1 a => OptionType -> Double -> [Time] -> Time -> ContingentClaim a -- | A call spread is a long position in a low-strike call and a short -- position in a high strike call. callSpread :: Obs1 a => Double -> Double -> Time -> ContingentClaim a -- | A put spread is a long position in a high strike put and a short -- position in a low strike put. putSpread :: Obs1 a => Double -> Double -> Time -> ContingentClaim a -- | Takes a time to maturity and generates a forward contract. forwardContract :: Obs1 a => Time -> ContingentClaim a -- | Takes an amount and a time and generates a fixed cash flow. zcb :: Time -> Double -> ContingentClaim a -- | Takes a face value, an interest rate, a payment frequency and makes a -- fixed bond fixedBond :: Double -> Double -> Double -> Int -> ContingentClaim a -- | Scales up a contingent claim by a multiplier. multiplier :: Double -> ContingentClaim a -> ContingentClaim a -- | Flips the signs in a contingent claim to make it a short position. short :: ContingentClaim a -> ContingentClaim a -- | Combines two contingent claims into one. combine :: ContingentClaim a -> ContingentClaim a -> ContingentClaim a -- | Takes a maturity time and a function and generates a ContingentClaim -- dependent only on the terminal value of the observable. terminalOnly :: Obs1 a => Time -> (Double -> Double) -> ContingentClaim a instance Monoid (ContingentClaim a) module Quant.MonteCarlo -- | Wraps the Identity monad in the MonteCarloT transformer. type MonteCarlo s a = MonteCarloT Identity s a -- | A monad transformer for Monte-Carlo calculations. type MonteCarloT m s = StateT s (RVarT m) -- | Runs a MonteCarlo calculation and provides the result of the -- computation. runMC :: MonadRandom (StateT b Identity) => MonteCarlo s c -> b -> s -> c -- | The Discretize class defines those models on which Monte Carlo -- simulations can be performed. -- -- Minimal complete definition: initialize, discounter, -- forwardGen and evolve'. class Discretize a b | a -> b where evolve mdl t2 anti = do { (_, t1) <- get; let ms = maxStep mdl; unless (t2 == t1) $ if timeDiff t1 t2 < ms then evolve' mdl t2 anti else do { evolve' mdl (timeOffset t1 ms) anti; evolve mdl t2 anti } } maxStep _ = 1 / 250 simulateState modl (ContingentClaim ccb) trials anti = avg <$> replicateM trials singleTrial where singleTrial = initialize modl >> process (0 :: Double) empty ccb [] process discCFs obsMap c@(CCProcessor t mf : ccs) allcfs@(CashFlow cft amt : cfs) = if t > cft then do { evolve modl cft anti; d <- discount modl cft; process (discCFs + d * amt) obsMap c cfs } else do { evolve modl t anti; obs <- gets fst; let obsMap' = insert t obs obsMap newCFs = map ($ obsMap') mf insertCFList xs cfList = foldl' (flip insertCF) cfList xs; process discCFs obsMap' ccs (insertCFList newCFs allcfs) } process discCFs obsMap (CCProcessor t mf : ccs) [] = do { evolve modl t anti; obs <- gets fst; let obsMap' = insert t obs obsMap newCFs = map ($ obsMap') mf insertCFList xs cfList = foldl' (flip insertCF) cfList xs; process discCFs obsMap' ccs (insertCFList newCFs []) } process discCFs obsMap [] (cf : cfs) = do { evolve modl (cfTime cf) anti; d <- discount modl $ cfTime cf; process (discCFs + d * cfAmount cf) obsMap [] cfs } process discCFs _ _ _ = return $! discCFs insertCF (CashFlow t amt) (CashFlow t' amt' : cfs) | t > t' = CashFlow t' amt' : insertCF (CashFlow t amt) cfs | otherwise = CashFlow t amt : CashFlow t' amt' : cfs insertCF cf [] = [cf] avg v = sum v / fromIntegral trials initialize :: (Discretize a b, Discretize a b) => a -> MonteCarlo (b, Time) () evolve :: (Discretize a b, Discretize a b) => a -> Time -> Bool -> MonteCarlo (b, Time) () discount :: (Discretize a b, Discretize a b) => a -> Time -> MonteCarlo (b, Time) Double forwardGen :: (Discretize a b, Discretize a b) => a -> Time -> MonteCarlo (b, Time) Double evolve' :: (Discretize a b, Discretize a b) => a -> Time -> Bool -> MonteCarlo (b, Time) () maxStep :: (Discretize a b, Discretize a b) => a -> Double simulateState :: (Discretize a b, Discretize a b) => a -> ContingentClaim b -> Int -> Bool -> MonteCarlo (b, Time) Double -- | Type for Put or Calls data OptionType Put :: OptionType Call :: OptionType -- | Runs a simulation for a ContingentClaim. runSimulation :: (Discretize a b, MonadRandom (StateT c Identity)) => a -> ContingentClaim b -> c -> Int -> Bool -> Double -- | Like runSimulation, but splits the trials in two and does -- antithetic variates. runSimulationAnti :: (Discretize a b, MonadRandom (StateT c Identity)) => a -> ContingentClaim b -> c -> Int -> Double -- | runSimulation with a default random number generator. quickSim :: Discretize a b => a -> ContingentClaim b -> Int -> Double -- | runSimulationAnti with a default random number generator. quickSimAnti :: Discretize a b => a -> ContingentClaim b -> Int -> Double module Quant.YieldCurve -- | The YieldCurve class defines the basic operations of a yield -- curve. -- -- Minimal complete definition: disc. class YieldCurve a where forward yc t1 t2 = (/ (timeFromZero t2 - timeFromZero t1)) $ log $ disc yc t1 / disc yc t2 spot yc t = forward yc (Time 0) t disc :: (YieldCurve a, YieldCurve a) => a -> Time -> Double forward :: (YieldCurve a, YieldCurve a) => a -> Time -> Time -> Double spot :: (YieldCurve a, YieldCurve a) => a -> Time -> Double -- | A flat curve is just a flat curve with one continuously compounded -- rate at all points on the curve. data FlatCurve FlatCurve :: {-# UNPACK #-} !Double -> FlatCurve -- | YieldCurve that represents the difference between two -- YieldCurves. data NetYC a NetYC :: a -> a -> NetYC a instance YieldCurve a => YieldCurve (NetYC a) instance YieldCurve FlatCurve module Quant.VolSurf -- | The VolSurf class defines the basic operations of a volatility -- surface. -- -- Minimal complete definition: vol. class VolSurf a where var vs s t = v * v * t' where v = vol vs s t t' = timeFromZero t 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 = k * exp dy km = k / exp dy [w, wp, wm] = map (\ x -> var v (x / s0) t) [k, kp, km] dwdy = (wp - wm) / 2.0 / dy d2wdy2 = (wp - 2.0 * w + wm) / dy / dy dt = min 0.0001 (timeFromZero t / 2.0) dwdt = let strikept = k * dr / drpt strikemt = k * dr / drmt drpt = disc rcurve $ timeOffset t dt drmt = disc rcurve $ timeOffset t (- dt) in case timeFromZero t of { 0 -> (var v (strikept / s0) (timeOffset t dt) - w) / dt _ -> (var v (strikept / s0) (timeOffset t dt) - var v (strikemt / s0) (timeOffset t (- dt))) / 2.0 / dt } solution = dwdt / (1.0 - y / w * dwdy + 0.25 * (- 0.25 - 1.0 / w + y * y / w / w) * dwdy * dwdy + 0.5 * d2wdy2) vol :: (VolSurf a, VolSurf a) => a -> Double -> Time -> Double var :: (VolSurf a, VolSurf a) => a -> Double -> Time -> Double localVol :: (VolSurf a, VolSurf a, YieldCurve b) => a -> Double -> b -> Double -> Time -> Double -- | A flat surface has one volatility at all times/maturities. data FlatSurf FlatSurf :: {-# UNPACK #-} !Double -> FlatSurf data GridSurf GridSurf :: [Double] -> [Time] -> Map (Double, Time) Double -> Interpolator1d -> Interpolator1d -> GridSurf gridStrikes :: GridSurf -> [Double] gridMaturities :: GridSurf -> [Time] gridQuotes :: GridSurf -> Map (Double, Time) Double gridStrikeInterpolator :: GridSurf -> Interpolator1d gridTimeInterpolator :: GridSurf -> Interpolator1d instance VolSurf GridSurf instance VolSurf FlatSurf module Quant.Models.Black -- | Black represents a Black-Scholes model. data Black -- | YieldCurve to handle discounting Black :: Double -> Double -> a -> b -> Black -- | Initial asset level. blackInit :: Black -> Double -- | Volatility. blackVol :: Black -> Double -- | YieldCurve to generate forwards blackForwardGen :: Black -> a blackYieldCurve :: Black -> b instance Discretize Black Observables1 module Quant.Models.Merton -- | Merton represents a Merton model (Black-Scholes w/ jumps). data Merton -- | YieldCurve to generate discount rates Merton :: Double -> Double -> Double -> Double -> Double -> a -> b -> Merton -- | Initial asset level mertonInitial :: Merton -> Double -- | Asset volatility mertonVol :: Merton -> Double -- | Intensity of Poisson process mertonIntensity :: Merton -> Double -- | Average size of jump mertonJumpMean :: Merton -> Double -- | Volatility of jumps mertonJumpVol :: Merton -> Double -- | YieldCurve to generate forwards mertonForwardGen :: Merton -> a mertonDiscounter :: Merton -> b instance Discretize Merton Observables1 module Quant.Models.Dupire -- | Dupire represents a Dupire-style local vol model. data Dupire -- | YieldCurve to generate discount rates Dupire :: Double -> (Time -> Double -> Double) -> a -> b -> Dupire -- | Initial asset level dupireInitial :: Dupire -> Double -- | Local vol function taking a time to maturity and a level dupireFunc :: Dupire -> Time -> Double -> Double -- | YieldCurve to generate forwards mertonForwardGen :: Dupire -> a mertonDiscounter :: Dupire -> b instance Discretize Dupire Observables1 module Quant.Models.Heston -- | Heston represents a Heston model (i.e. stochastic volatility). data Heston -- | YieldCurve to generate discounts Heston :: Double -> Double -> Double -> Double -> Double -> Double -> a -> b -> Heston -- | Initial asset level. hestonInit :: Heston -> Double -- | Initial variance hestonV0 :: Heston -> Double -- | Mean-reversion variance hestonVF :: Heston -> Double -- | Vol-vol hestonLambda :: Heston -> Double -- | Correlation between processes hestonCorrel :: Heston -> Double -- | Mean reversion speed hestonMeanRev :: Heston -> Double -- | YieldCurve to generate forwards hestonForwardGen :: Heston -> a hestonDisc :: Heston -> b instance Discretize Heston Observables2