-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Quant finance library in pure Haskell. -- @package quantfin @version 0.1.0.2 module Quant.Models.Processes data ProcessSpec ProcessSpec :: Double -> Double -> Double -> ProcessSpec procInit :: ProcessSpec -> Double procGrowth :: ProcessSpec -> Double procElapsed :: ProcessSpec -> Double lognormal :: ProcessSpec -> Double -> Double -> Double module Quant.Math.Utilities tdmaSolver :: (Fractional a, Ord a) => [a] -> [a] -> [a] -> [a] -> [a] 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 :: 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 data CashFlow CashFlow :: Time -> Double -> CashFlow cfTime :: CashFlow -> Time cfAmount :: CashFlow -> Double -- | Observables are the observables available in a Monte Carlo simulation. -- Most basic MCs will have one observables (Black-Scholes) whereas more -- complex ones will have multiple (i.e. Heston-Hull-White). data Observables a Observables :: [a] -> Observables a obsGet :: Observables a -> [a] type MCObservables = Observables Double -- | Type for Put or Calls data OptionType Put :: OptionType Call :: OptionType instance Show a => Show (Observables a) instance Eq OptionType instance Show OptionType module Quant.ContingentClaim newtype ContingentClaim ContingentClaim :: [CCProcessor] -> ContingentClaim unCC :: ContingentClaim -> [CCProcessor] data CCProcessor CCProcessor :: Time -> Maybe [PayoffFunc CashFlow] -> CCProcessor monitorTime :: CCProcessor -> Time payoutFunc :: CCProcessor -> Maybe [PayoffFunc CashFlow] -- | Observables are the observables available in a Monte Carlo simulation. -- Most basic MCs will have one observables (Black-Scholes) whereas more -- complex ones will have multiple (i.e. Heston-Hull-White). data Observables a Observables :: [a] -> Observables a obsGet :: Observables a -> [a] type MCObservables = Observables Double -- | Type for Put or Calls data OptionType Put :: OptionType Call :: OptionType data CashFlow CashFlow :: Time -> Double -> CashFlow cfTime :: CashFlow -> Time cfAmount :: CashFlow -> Double type CCBuilder w r a = WriterT w (Reader r) a specify :: CCBuilder ContingentClaim MCMap CashFlow -> ContingentClaim monitor :: Time -> CCBuilder ContingentClaim MCMap Double monitorByNum :: Int -> Time -> CCBuilder ContingentClaim MCMap Double -- | Takes an OptionType, a strike, and a time to maturity and generates a -- vanilla option. vanillaOption :: OptionType -> Double -> Time -> ContingentClaim -- | Takes an OptionType, a strike, a payout amount and a time to maturity -- and generates a vanilla option. binaryOption :: OptionType -> Double -> Double -> Time -> ContingentClaim -- | A straddle is a put and a call with the same time to maturity / -- strike. straddle :: Double -> Time -> ContingentClaim -- | Takes an OptionType, a strike, observation times, time to maturity and -- generates an arithmetic Asian option. arithmeticAsianOption :: OptionType -> Double -> [Time] -> Time -> ContingentClaim -- | Takes an OptionType, a strike, observation times, time to maturity and -- generates an arithmetic Asian option. geometricAsianOption :: OptionType -> Double -> [Time] -> Time -> ContingentClaim -- | A call spread is a long position in a low-strike call and a short -- position in a high strike call. callSpread :: Double -> Double -> Time -> ContingentClaim -- | A put spread is a long position in a high strike put and a short -- position in a low strike put. putSpread :: Double -> Double -> Time -> ContingentClaim -- | Takes a time to maturity and generates a forward contract. forwardContract :: Time -> ContingentClaim -- | Takes an amount and a time and generates a fixed cash flow. zcb :: Time -> Double -> ContingentClaim -- | Takes a face value, an interest rate, a payment frequency and makes a -- fixed bond fixedBond :: Double -> Double -> Double -> Int -> ContingentClaim -- | Scales up a contingent claim by a multiplier. multiplier :: Double -> ContingentClaim -> ContingentClaim -- | Flips the signs in a contingent claim to make it a short position. short :: ContingentClaim -> ContingentClaim -- | Combines two contingent claims into one. combine :: ContingentClaim -> ContingentClaim -> ContingentClaim -- | Takes a maturity time and a function and generates a ContingentClaim -- dependent only on the terminal value of the observable. terminalOnly :: Time -> (Double -> Double) -> ContingentClaim instance Monoid ContingentClaim 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 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 } } discountState m t = return $ discount m t 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 <- discountState modl cft; process (discCFs + d * amt) obsMap c cfs } else do { evolve modl t anti; obs <- gets fst; let obsMap' = insert t obs obsMap; case mf of { Nothing -> process discCFs obsMap' ccs allcfs Just f -> let newCFs = map ($ obsMap') f insertCFList xs cfList = foldl' (flip insertCF) cfList xs in 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; case mf of { Nothing -> process discCFs obsMap' ccs [] Just f -> let newCFs = map ($ obsMap') f insertCFList xs cfList = foldl' (flip insertCF) cfList xs in process discCFs obsMap' ccs (insertCFList newCFs []) } } process discCFs obsMap [] (cf : cfs) = do { evolve modl (cfTime cf) anti; d <- discountState 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 runSimulation modl ccs seed trials anti = runMC run seed (Observables [], Time 0) where run = simulateState modl ccs trials anti runSimulationAnti modl ccs seed trials = (runSim True + runSim False) / 2 where runSim = runSimulation modl ccs seed (trials `div` 2) quickSim mdl opts trials = runSimulation mdl opts (pureMT 500) trials False quickSimAnti mdl opts trials = runSimulationAnti mdl opts (pureMT 500) trials initialize :: (Discretize a, Discretize a) => a -> MonteCarlo (MCObservables, Time) () evolve :: (Discretize a, Discretize a) => a -> Time -> Bool -> MonteCarlo (MCObservables, Time) () discountState :: (Discretize a, Discretize a) => a -> Time -> MonteCarlo (MCObservables, Time) Double discount :: (Discretize a, Discretize a) => a -> Time -> Double forwardGen :: (Discretize a, Discretize a) => a -> Time -> MonteCarlo (MCObservables, Time) Double evolve' :: (Discretize a, Discretize a) => a -> Time -> Bool -> MonteCarlo (MCObservables, Time) () maxStep :: (Discretize a, Discretize a) => a -> Double simulateState :: (Discretize a, Discretize a) => a -> ContingentClaim -> Int -> Bool -> MonteCarlo (MCObservables, Time) Double runSimulation :: (Discretize a, Discretize a, MonadRandom (StateT b Identity)) => a -> ContingentClaim -> b -> Int -> Bool -> Double runSimulationAnti :: (Discretize a, Discretize a, MonadRandom (StateT b Identity)) => a -> ContingentClaim -> b -> Int -> Double quickSim :: (Discretize a, Discretize a) => a -> ContingentClaim -> Int -> Double quickSimAnti :: (Discretize a, Discretize a) => a -> ContingentClaim -> Int -> Double -- | Type for Put or Calls data OptionType Put :: OptionType Call :: OptionType 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 :: 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 :: 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 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 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 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