module QuantLib.Methods.MonteCarlo
( module QuantLib.Methods.MonteCarlo
) where
import Control.Monad ()
import Control.Parallel.Strategies
import QuantLib.Stochastic.Process
import QuantLib.Stochastic.Random
class PathPricer p => Summary m p | m->p where
sSummarize :: m -> [p] -> m
sNorm :: m -> m -> Double
class PathGenerator m where
pgMkNew :: m->IO m
pgGenerate :: Integer -> m->Path
class PathPricer m where
ppPrice :: m -> Path -> m
monteCarlo :: (Summary s p, PathGenerator g) => PathMonteCarlo s p g->Int->s
monteCarlo (PathMonteCarlo s p g) size = sSummarize s priced
where
!priced = map pricing [1..size]
pricing seed = ppPrice p (pgGenerate (fromIntegral seed) g)
monteCarloParallel :: (Summary s p, PathGenerator g) => PathMonteCarlo s p g->Int->s
monteCarloParallel (PathMonteCarlo s p g) size = sSummarize s priced
where
!priced = map pricing [1..size] `using` rpar
pricing seed = ppPrice p (pgGenerate (fromIntegral seed) g)
data PathMonteCarlo s p g =
PathMonteCarlo {
pmcSummary :: s,
pmcPricer :: p,
pmcGenerator :: g
}
data ProcessGenerator sp b d =
ProcessGenerator {
pgStart :: Dot,
pgLength :: Int,
pgProcess :: sp,
pgGenerator :: b,
pgDiscretize :: d
}
instance (StochasticProcess sp, NormalGenerator b, Discretize d) => PathGenerator (ProcessGenerator sp b d) where
pgMkNew (ProcessGenerator start len process rnd d) = do
newRnd <- ngMkNew rnd
return $! ProcessGenerator start len process newRnd d
pgGenerate seed (ProcessGenerator start len sp b d) = generatePath newB d sp len start
where (_, newB) = ngSplitWithSeed seed b