hquantlib 0.0.2.0 → 0.0.2.1
raw patch · 18 files changed
+223/−123 lines, 18 filesdep +basedep +mersenne-randomdep −gsl-randomdep −haskell2010PVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: base, mersenne-random
Dependencies removed: gsl-random, haskell2010
API changes (from Hackage documentation)
- QuantLib.Currencies: Currency :: String -> String -> Integer -> Integer -> Currency
- QuantLib.Currencies: cCode :: Currency -> String
- QuantLib.Currencies: cFracsPerUnit :: Currency -> Integer
- QuantLib.Currencies: cIsoCode :: Currency -> Integer
- QuantLib.Currencies: cName :: Currency -> String
- QuantLib.Currencies: cad :: Currency
- QuantLib.Currencies: chf :: Currency
- QuantLib.Currencies: czk :: Currency
- QuantLib.Currencies: data Currency
- QuantLib.Currencies: dkk :: Currency
- QuantLib.Currencies: eur :: Currency
- QuantLib.Currencies: gbp :: Currency
- QuantLib.Currencies: usd :: Currency
- QuantLib.Stochastic: BlackScholesProcess :: (Double -> Double) -> (Double -> Double) -> (Dot -> Double) -> BlackScholesProcess
- QuantLib.Stochastic: Dot :: Double -> Double -> Dot
- QuantLib.Stochastic: EndEuler :: Double -> EndEuler
- QuantLib.Stochastic: Euler :: Double -> Euler
- QuantLib.Stochastic: GeometricBrownian :: Double -> Double -> GeometricBrownian
- QuantLib.Stochastic: ItoProcess :: (Dot -> Double) -> (Dot -> Double) -> ItoProcess
- QuantLib.Stochastic: OrnsteinUhlenbeckProcess :: Double -> Double -> Double -> OrnsteinUhlenbeckProcess
- QuantLib.Stochastic: SquareRootProcess :: Double -> Double -> Double -> SquareRootProcess
- QuantLib.Stochastic: bspBlackVol :: BlackScholesProcess -> Dot -> Double
- QuantLib.Stochastic: bspDividend :: BlackScholesProcess -> Double -> Double
- QuantLib.Stochastic: bspRiskFree :: BlackScholesProcess -> Double -> Double
- QuantLib.Stochastic: class Discretize b
- QuantLib.Stochastic: class NormalGenerator a
- QuantLib.Stochastic: class StochasticProcess a
- QuantLib.Stochastic: createNormalGen :: RNG -> BoxMuller
- QuantLib.Stochastic: dDiff :: (Discretize b, StochasticProcess a) => a -> b -> Dot -> Double
- QuantLib.Stochastic: dDrift :: (Discretize b, StochasticProcess a) => a -> b -> Dot -> Double
- QuantLib.Stochastic: dDt :: (Discretize b, StochasticProcess a) => a -> b -> Dot -> Double
- QuantLib.Stochastic: data BlackScholesProcess
- QuantLib.Stochastic: data BoxMuller
- QuantLib.Stochastic: data Dot
- QuantLib.Stochastic: data EndEuler
- QuantLib.Stochastic: data Euler
- QuantLib.Stochastic: data GeometricBrownian
- QuantLib.Stochastic: data ItoProcess
- QuantLib.Stochastic: data OrnsteinUhlenbeckProcess
- QuantLib.Stochastic: data SquareRootProcess
- QuantLib.Stochastic: diff :: StochasticProcess a => a -> Dot -> Double
- QuantLib.Stochastic: drift :: StochasticProcess a => a -> Dot -> Double
- QuantLib.Stochastic: eDt :: Euler -> Double
- QuantLib.Stochastic: eeDt :: EndEuler -> Double
- QuantLib.Stochastic: evolve :: (StochasticProcess a, Discretize b) => b -> a -> Dot -> Double -> Dot
- QuantLib.Stochastic: gbDiff :: GeometricBrownian -> Double
- QuantLib.Stochastic: gbDrift :: GeometricBrownian -> Double
- QuantLib.Stochastic: generatePath :: (StochasticProcess a, NormalGenerator b, Discretize c) => b -> c -> a -> Int -> Dot -> IO Path
- QuantLib.Stochastic: getT :: Dot -> Double
- QuantLib.Stochastic: getX :: Dot -> Double
- QuantLib.Stochastic: ipDiff :: ItoProcess -> Dot -> Double
- QuantLib.Stochastic: ipDrift :: ItoProcess -> Dot -> Double
- QuantLib.Stochastic: mkNormalGen :: IO BoxMuller
- QuantLib.Stochastic: ngGetNext :: NormalGenerator a => a -> IO (Double, a)
- QuantLib.Stochastic: ngMkNew :: NormalGenerator a => a -> IO a
- QuantLib.Stochastic: oupLevel :: OrnsteinUhlenbeckProcess -> Double
- QuantLib.Stochastic: oupSigma :: OrnsteinUhlenbeckProcess -> Double
- QuantLib.Stochastic: oupSpeed :: OrnsteinUhlenbeckProcess -> Double
- QuantLib.Stochastic: srpMean :: SquareRootProcess -> Double
- QuantLib.Stochastic: srpSigma :: SquareRootProcess -> Double
- QuantLib.Stochastic: srpSpeed :: SquareRootProcess -> Double
- QuantLib.Stochastic: type Path = [Dot]
+ QuantLib.Math: inverseNormal :: Double -> Double
+ QuantLib.Time: intGregorian :: Day -> (Int, Int, Int)
- QuantLib.Event: class Event a
+ QuantLib.Event: class Event a where evOccured event date = evDate event < date evOccuredInclude event date = evDate event <= date evCompare x y | evDate x == evDate y = EQ | evDate x <= evDate y = LT | otherwise = GT evEqual x y = evDate x == evDate y
- QuantLib.Methods.MonteCarlo: data (Summary s p, PathPricer p, PathGenerator g) => PathMonteCarlo s p g
+ QuantLib.Methods.MonteCarlo: data PathMonteCarlo s p g
- QuantLib.Methods.MonteCarlo: data (StochasticProcess sp, NormalGenerator b, Discretize d) => ProcessGenerator sp b d
+ QuantLib.Methods.MonteCarlo: data ProcessGenerator sp b d
- QuantLib.Quotes: class Quote a
+ QuantLib.Quotes: class Quote a where pureValue x = fromMaybe 0.0 (qValue x)
- QuantLib.Time: class Holiday m
+ QuantLib.Time: class Holiday m where isBusinessDay m d = not (isHoliday m $ toGregorian d) hBusinessDayBetween m (fd, td) = foldl countDays 0 listOfDates where countDays counter x = counter + fromEnum (isBusinessDay m x) listOfDates = getDaysBetween (fd, td)
Files
- hquantlib.cabal +10/−8
- src/QuantLib.hs +6/−13
- src/QuantLib/Currencies.hs +4/−8
- src/QuantLib/Currency.hs +1/−1
- src/QuantLib/Event.hs +5/−5
- src/QuantLib/Instruments/Instrument.hs +1/−1
- src/QuantLib/Math.hs +5/−0
- src/QuantLib/Math/InverseNormal.hs +101/−0
- src/QuantLib/Methods/MonteCarlo.hs +6/−7
- src/QuantLib/PricingEngines/BlackFormula.hs +3/−3
- src/QuantLib/Quotes.hs +3/−3
- src/QuantLib/Stochastic.hs +4/−9
- src/QuantLib/Stochastic/Discretize.hs +6/−6
- src/QuantLib/Stochastic/Process.hs +16/−16
- src/QuantLib/Stochastic/Random.hs +32/−20
- src/QuantLib/Time/Date.hs +1/−1
- src/QuantLib/Time/DayCounter.hs +16/−19
- src/QuantLib/VolatilityModel.hs +3/−3
hquantlib.cabal view
@@ -1,5 +1,5 @@ name: hquantlib-version: 0.0.2.0+version: 0.0.2.1 license: LGPL license-file: LICENSE author: Pavel Ryzhov@@ -13,12 +13,12 @@ cabal-version: >= 1.10.0 source-repository head- type: hg- location: https://hquantlib.googlecode.com/hg/+ type: git+ location: https://github.com/paulrzcz/hquantlib.git source-repository this- type: hg- location: https://hquantlib.googlecode.com/hg/+ type: git+ location: https://github.com/paulrzcz/hquantlib.git tag: 0.0.2 library@@ -36,6 +36,7 @@ QuantLib.Time QuantLib.TimeSeries QuantLib.Money+ QuantLib.Math QuantLib.Prices QuantLib.Position QuantLib.Options@@ -52,15 +53,16 @@ QuantLib.Currency QuantLib.Time.Date QuantLib.Time.DayCounter+ QuantLib.Math.InverseNormal build-depends: - haskell2010 == 1.0.0.0,+ base >3 && <5, time >= 1.2.0.0, containers >= 0.4.0.0, hmatrix >= 0.11.0.0, hmatrix-special >= 0.1.1,- gsl-random >= 0.4.0,- parallel >= 3.1.0.0+ parallel >= 3.1.0.0,+ mersenne-random >= 1.0.0.0 hs-source-dirs: src ghc-options: -Wall
src/QuantLib.hs view
@@ -1,14 +1,7 @@-module QuantLib- ( module QuantLib.Stochastic- , module QuantLib.Money- , module QuantLib.Position- , module QuantLib.TimeSeries- , module QuantLib.Prices- )- where+module QuantLib ( module Q ) where -import QuantLib.Stochastic-import QuantLib.Money-import QuantLib.Position-import QuantLib.TimeSeries-import QuantLib.Prices+import QuantLib.Stochastic as Q+import QuantLib.Money as Q+import QuantLib.Position as Q+import QuantLib.TimeSeries as Q+import QuantLib.Prices as Q
src/QuantLib/Currencies.hs view
@@ -1,9 +1,5 @@-module QuantLib.Currencies- ( module QuantLib.Currency- , module QuantLib.Currencies.Europe- , module QuantLib.Currencies.America- ) where+module QuantLib.Currencies ( module Q ) where -import QuantLib.Currency-import QuantLib.Currencies.Europe-import QuantLib.Currencies.America+import QuantLib.Currency as Q+import QuantLib.Currencies.Europe as Q+import QuantLib.Currencies.America as Q
src/QuantLib/Currency.hs view
@@ -17,4 +17,4 @@ } deriving (Eq) instance Show Currency where- showsPrec _ x s = (cCode x)++s+ showsPrec _ x s = cCode x ++ s
src/QuantLib/Event.hs view
@@ -8,19 +8,19 @@ class Event a where evDate :: a->Date evOccured :: a->Date->Bool- evOccured event date = (evDate event) < date+ evOccured event date = evDate event < date evOccuredInclude:: a->Date->Bool- evOccuredInclude event date = (evDate event) <= date+ evOccuredInclude event date = evDate event <= date evCompare :: a->a->Ordering evCompare x y - | (evDate x) == (evDate y) = EQ- | (evDate x) <= (evDate y) = LT+ | evDate x == evDate y = EQ+ | evDate x <= evDate y = LT | otherwise = GT evEqual :: a->a->Bool- evEqual x y = (evDate x) == (evDate y)+ evEqual x y = evDate x == evDate y -- | Cash flows data type data CashFlow = CashFlow {
src/QuantLib/Instruments/Instrument.hs view
@@ -17,7 +17,7 @@ deriving (Show) instance Instrument a => Instrument (CompositeInstrument a) where- iNPV (CompositeInstrument xs) = M.foldrWithKey (\k x y -> y + (iNPV k)*x) 0.0 xs+ iNPV (CompositeInstrument xs) = M.foldrWithKey (\k x y -> y + iNPV k * x) 0.0 xs iErrorEstimate _ = 0.0 iDate (CompositeInstrument xs) = (iDate . head . M.keys) xs iIsExpired (CompositeInstrument xs) = (any iIsExpired . M.keys) xs
+ src/QuantLib/Math.hs view
@@ -0,0 +1,5 @@+module QuantLib.Math+ ( module QuantLib.Math.InverseNormal+ ) where++import QuantLib.Math.InverseNormal
+ src/QuantLib/Math/InverseNormal.hs view
@@ -0,0 +1,101 @@+{-| The inverse normal cumulative distribution is a non-linear function for which no closed-form solution exists. The function is continuous, monotonically increasing, infinitely differentiable, and maps the open interval (0,1) to the whole real line. By <a href="http://home.online.no/~pjacklam/notes/invnorm/"> An algorithm for computing the inverse normal cumulative distribution function</a>+-}++module QuantLib.Math.InverseNormal+ ( inverseNormal+ ) where+++a1 :: Double+a1 = -3.969683028665376e+01;+a2 :: Double+a2 = 2.209460984245205e+02;+a3 :: Double+a3 = -2.759285104469687e+02;+a4 :: Double+a4 = 1.383577518672690e+02;+a5 :: Double+a5 = -3.066479806614716e+01;+a6 :: Double+a6 = 2.506628277459239e+00;++b1 :: Double+b1 = -5.447609879822406e+01;+b2 :: Double+b2 = 1.615858368580409e+02;+b3 :: Double+b3 = -1.556989798598866e+02;+b4 :: Double+b4 = 6.680131188771972e+01;+b5 :: Double+b5 = -1.328068155288572e+01;++c1 :: Double+c1 = -7.784894002430293e-03;+c2 :: Double+c2 = -3.223964580411365e-01;+c3 :: Double+c3 = -2.400758277161838e+00;+c4 :: Double+c4 = -2.549732539343734e+00;+c5 :: Double+c5 = 4.374664141464968e+00;+c6 :: Double+c6 = 2.938163982698783e+00;++d1 :: Double+d1 = 7.784695709041462e-03;+d2 :: Double+d2 = 3.224671290700398e-01;+d3 :: Double+d3 = 2.445134137142996e+00;+d4 :: Double+d4 = 3.754408661907416e+00;++-- Limits of the approximation regions (break-points)+xlow :: Double+xlow = 0.02425;+xhigh :: Double+xhigh = 1.0 - xlow;++-- Precision of Double at 1.0 point+ulp :: Double+ulp = 2.220446049250313E-16++-- | Computes the inverse cumulative standard normal distribution N(0, 1)+inverseNormal :: Double -> Double+inverseNormal x + | x < xlow = inverseInLowerRegion z+ | x <= xhigh = inverseInCentralRegion z+ | otherwise = inverseInHigherRegion z+ where z | x < 0.0 || x >1.0 = inverseRecovery x+ | otherwise = x+++inverseRecovery :: Double -> Double+inverseRecovery x+ | isCloseToZero = 0.0+ | isCloseToOne = 1.0+ | otherwise = 0.0/0.0 -- NaN effectively+ where isCloseToZero = abs x < ulp+ isCloseToOne = diff <= tolerance * abs x || diff <= tolerance+ diff = abs (x-1.0)+ tolerance = 42*ulp+{-# INLINE inverseRecovery #-}++inverseInLowerRegion :: Double -> Double+inverseInLowerRegion x = (((((c1*z+c2)*z+c3)*z+c4)*z+c5)*z+c6) / ((((d1*z+d2)*z+d3)*z+d4)*z+1.0)+ where z = sqrt (-2.0*log x)+{-# INLINE inverseInLowerRegion #-}++inverseInCentralRegion :: Double -> Double+inverseInCentralRegion x = (((((a1*r+a2)*r+a3)*r+a4)*r+a5)*r+a6)*z / (((((b1*r+b2)*r+b3)*r+b4)*r+b5)*r+1.0)+ where r = z*z+ z = x - 0.5+{-# INLINE inverseInCentralRegion #-}++inverseInHigherRegion :: Double -> Double+inverseInHigherRegion x = -(((((c1*z+c2)*z+c3)*z+c4)*z+c5)*z+c6) / ((((d1*z+d2)*z+d3)*z+d4)*z+1.0)+ where z = sqrt (-2.0 * log (1.0 - x))+{-# INLINE inverseInHigherRegion #-}+
src/QuantLib/Methods/MonteCarlo.hs view
@@ -31,8 +31,7 @@ priced <- mapM (\_ -> pricing) [1..size] return $ sSummarize s priced where pricing = do- rnd <- pgMkNew g- !path <- pgGenerate rnd+ !path <- pgGenerate g return $! ppPrice p path -- | Monte Carlo engine function. Parallelized version@@ -45,12 +44,12 @@ return $! ppPrice p path -- | Path-dependant Monte Carlo engine-data (Summary s p, PathPricer p, PathGenerator g) => PathMonteCarlo s p g- = PathMonteCarlo {+data PathMonteCarlo s p g =+ PathMonteCarlo { pmcSummary :: s, pmcPricer :: p, pmcGenerator :: g- }+ } -- | This pricer gets the last point of path data LastPointPricer = LastPointPricer Dot@@ -59,8 +58,8 @@ ppPrice _ path = LastPointPricer (last path) -- | Stochastic process generator-data (StochasticProcess sp, NormalGenerator b, Discretize d) => ProcessGenerator sp b d - = ProcessGenerator {+data ProcessGenerator sp b d = + ProcessGenerator { pgStart :: Dot, pgLength :: Int, pgProcess :: sp,
src/QuantLib/PricingEngines/BlackFormula.hs view
@@ -23,8 +23,8 @@ blackImpliedStdDevHelper :: OptionType-> Double-> Double-> Double-> Double-> [Double]-> [Double] blackImpliedStdDevHelper opType strike forward blackPrice displacement [x] =- [(max 0.0 result) - blackPrice]- where result = signedForward * (cdf signedD1) - signedStrike * (cdf signedD2)+ [max 0.0 result - blackPrice]+ where result = signedForward * cdf signedD1 - signedStrike * cdf signedD2 signedD1 = d + temp signedD2 = d - temp d = signedMoneyness/x@@ -37,7 +37,7 @@ blackImpliedStdDevHelper _ _ _ _ _ _ = undefined cdf :: Double -> Double-cdf x = 0.5 * (1 + erf (x/(sqrt 2)))+cdf x = 0.5 * (1 + erf (x / sqrt 2)) blackFormulaImpliedStdDevApproximation :: OptionType-> Double-> Double-> Double-> Double-> Double-> Double blackFormulaImpliedStdDevApproximation opType strike forward blackPrice discount displacement
src/QuantLib/Quotes.hs view
@@ -30,7 +30,7 @@ } instance Quote (CompositeQuote a) where- qValue x = (cqComposite x) (cqQuote1 x) (cqQuote2 x)+ qValue x = cqComposite x (cqQuote1 x) (cqQuote2 x) -- | Market element whose value depends on another quote data DerivedQuote a = DerivedQuote {@@ -39,7 +39,7 @@ } instance Quote (DerivedQuote a) where- qValue x = (dqDerivateFunc x) (dqQuote x)+ qValue x = dqDerivateFunc x (dqQuote x) -- | Quote for the implied standard deviation of an underlying data ImpliedStdDevQuote a = ImpliedStdDevQuote {@@ -68,7 +68,7 @@ | strike > forwardValue = blackFormulaImpliedStdDev Call strike forwardValue putValue 1.0 0.0 guess 1.0e-6 100 | otherwise = blackFormulaImpliedStdDev Put strike forwardValue callValue 1.0 0.0 guess 1.0e-6 100 where- forwardValue = 100.0 - (fromMaybe 0.0 (qValue forward))+ forwardValue = 100.0 - fromMaybe 0.0 (qValue forward) putValue = fromMaybe 0.0 (qValue putPrice) callValue = fromMaybe 0.0 (qValue callPrice)
src/QuantLib/Stochastic.hs view
@@ -1,10 +1,5 @@-module QuantLib.Stochastic- ( module QuantLib.Stochastic.Process- , module QuantLib.Stochastic.Discretize- , module QuantLib.Stochastic.Random- )- where+module QuantLib.Stochastic ( module Q ) where -import QuantLib.Stochastic.Process-import QuantLib.Stochastic.Discretize-import QuantLib.Stochastic.Random+import QuantLib.Stochastic.Process as Q+import QuantLib.Stochastic.Discretize as Q+import QuantLib.Stochastic.Random as Q
src/QuantLib/Stochastic/Discretize.hs view
@@ -14,14 +14,14 @@ deriving (Show, Eq) instance Discretize Euler where- dDrift p e dot = (drift p dot)*(eDt e)- dDiff p e dot = (diff p dot)*sqrt (eDt e)+ dDrift p e dot = drift p dot * eDt e+ dDiff p e dot = diff p dot * sqrt (eDt e) dDt _ e _ = eDt e instance Discretize EndEuler where- dDrift p e dot = (drift p nextDot)*(eeDt e)- where nextDot = Dot ((getT dot) + (eeDt e)) (getX dot)- dDiff p e dot = (diff p nextDot)*sqrt (eeDt e)- where nextDot = Dot ((getT dot) + (eeDt e)) (getX dot) + dDrift p e dot = drift p nextDot * eeDt e+ where nextDot = Dot (getT dot + eeDt e) (getX dot)+ dDiff p e dot = diff p nextDot * sqrt (eeDt e)+ where nextDot = Dot (getT dot + eeDt e) (getX dot) dDt _ e _ = eeDt e
src/QuantLib/Stochastic/Process.hs view
@@ -19,11 +19,11 @@ diff :: a->Dot->Double evolve :: Discretize b=> b->a->Dot->Double->Dot evolve discr p dot dw = Dot newT newX- where newT = ((+) (getT dot) (dDt p discr dot))- newX = (getX dot) + (dDrift p discr dot) + (dDiff p discr dot)*dw+ where !newT = getT dot + dDt p discr dot+ !newX = getX dot + dDrift p discr dot + dDiff p discr dot * dw -- | Dot. t and x pair-data Dot = Dot { getT :: Double, getX :: Double }+data Dot = Dot { getT :: {-# UNPACK #-} !Double, getX :: {-# UNPACK #-} !Double } deriving (Show, Eq) -- | Path as list of Dots@@ -33,11 +33,11 @@ generatePath :: (StochasticProcess a, NormalGenerator b, Discretize c) => b->c->a->Int->Dot->IO Path generatePath rnd discr sp steps x0 = do (!list, _) <- foldM generator ([], rnd) [1..steps]- let path = foldl' evolver [x0] list+ let !path = foldl' evolver [x0] list return $! reverse path- where evolver p dw = (evolve discr sp (head p) dw) : p+ where evolver p dw = evolve discr sp (head p) dw : p generator (list, r) _ = do- (p, newRnd) <- ngGetNext r+ (!p, newRnd) <- ngGetNext r return (p:list, newRnd) @@ -48,8 +48,8 @@ } deriving (Show) instance StochasticProcess GeometricBrownian where- drift p (Dot _ x) = (gbDrift p) * x- diff p (Dot _ x) = (gbDiff p) * x+ drift p (Dot _ x) = gbDrift p * x+ diff p (Dot _ x) = gbDiff p * x -- | Ito process data ItoProcess = ItoProcess { @@ -58,8 +58,8 @@ } instance StochasticProcess ItoProcess where- drift p d = (ipDrift p) d- diff p d = (ipDiff p) d+ drift = ipDrift+ diff = ipDiff -- | Square-root process data SquareRootProcess = SquareRootProcess { @@ -69,8 +69,8 @@ } deriving (Show) instance StochasticProcess SquareRootProcess where- drift p (Dot _ x) = (srpSpeed p)*((srpMean p) - x)- diff p (Dot _ x) = (srpSigma p)*(sqrt x)+ drift p (Dot _ x) = srpSpeed p * (srpMean p - x)+ diff p (Dot _ x) = srpSigma p * sqrt x -- | Ornstein-Uhlenbeck process data OrnsteinUhlenbeckProcess = OrnsteinUhlenbeckProcess {@@ -80,8 +80,8 @@ } deriving (Show) instance StochasticProcess OrnsteinUhlenbeckProcess where- drift p (Dot _ x) = (oupSpeed p)*((oupLevel p) - x)- diff p _ = (oupSigma p)+ drift p (Dot _ x) = oupSpeed p * (oupLevel p - x)+ diff p _ = oupSigma p -- | Generalized Black-Scholes process data BlackScholesProcess = BlackScholesProcess {@@ -91,7 +91,7 @@ } instance StochasticProcess BlackScholesProcess where- drift (BlackScholesProcess r q v) dot = (r $ getT dot) - (q $ getT dot) - 0.5*(v dot)**2 - diff p dot = (bspBlackVol p) dot+ drift (BlackScholesProcess r q v) dot = r (getT dot) - q ( getT dot) - 0.5 * v dot ** 2 + diff = bspBlackVol
src/QuantLib/Stochastic/Random.hs view
@@ -4,25 +4,27 @@ , createNormalGen , mkNormalGen , NormalGenerator (..)- , module GSL.Random.Gen+ , InverseNormal+ , mkInverseNormal ) where -import GSL.Random.Gen+import System.Random.Mersenne+import QuantLib.Math.InverseNormal -- | Box-Muller method data BoxMuller = BoxMuller { bmFirst :: Bool, bmSecondValue :: Double,- bmRng :: RNG+ bmRng :: MTGen } mkNormalGen :: IO BoxMuller mkNormalGen = do- rng <- newRNG mt19937+ rng <- newMTGen Nothing return $! createNormalGen rng -- | Creates normally distributed generator-createNormalGen :: RNG->BoxMuller+createNormalGen :: MTGen->BoxMuller createNormalGen r = BoxMuller { bmFirst = True, bmSecondValue = 0.0,@@ -37,24 +39,34 @@ instance NormalGenerator BoxMuller where ngMkNew _ = mkNormalGen ngGetNext (BoxMuller True _ rng) = do- (r, s1, s2) <- getRs- let !ratio = sqrt (-2.0*(log r)/r)- let bm = BoxMuller {+ (!r, !s1, !s2) <- getRs+ let !ratio = sqrt (-2.0 * log r / r)+ let !bm = BoxMuller { bmFirst = False, bmSecondValue = s2*ratio, bmRng = rng }- return $! (s1*ratio, bm)+ return (s1*ratio, bm) where getRs = do- x1 <- getUniformPos rng- x2 <- getUniformPos rng- let s1 = 2.0*x1-1.0- let s2 = 2.0*x2-1.0- let r = s1*s1 + s2*s2- if (r>=1.0 || r<=0.0) then- getRs- else- return $! (r, s1, s2)+ x1 <- random rng :: IO Double+ x2 <- random rng :: IO Double+ let !s1 = 2.0*x1-1.0+ let !s2 = 2.0*x2-1.0+ let !r = s1*s1 + s2*s2+ if r>=1.0 || r<=0.0 then getRs else return (r, s1, s2) - ngGetNext (BoxMuller False s r) = do- return $! (s, BoxMuller True s r)+ ngGetNext (BoxMuller False !s !r) = return (s, BoxMuller True s r)++-- | Normal number generation using inverse cummulative normal distribution+data InverseNormal = InverseNormal MTGen++mkInverseNormal :: IO InverseNormal+mkInverseNormal = do+ rng <- newMTGen Nothing+ return $! InverseNormal rng+ +instance NormalGenerator InverseNormal where+ ngMkNew _ = mkInverseNormal+ ngGetNext gen@(InverseNormal rng) = do+ x <- random rng :: IO Double+ return (inverseNormal x, gen)
src/QuantLib/Time/Date.hs view
@@ -31,7 +31,7 @@ hBusinessDayBetween :: m->(Date, Date)->Int hBusinessDayBetween m (fd, td) = foldl countDays 0 listOfDates- where countDays counter x = counter + (fromEnum $ isBusinessDay m x)+ where countDays counter x = counter + fromEnum (isBusinessDay m x) listOfDates = getDaysBetween (fd, td) -- | Gets a week day
src/QuantLib/Time/DayCounter.hs view
@@ -31,33 +31,30 @@ dcName ThirtyEuropean = "Thirty Euro" dcName ThirtyItalian = "Thirty Italian" - dcYearFraction dc fromDate toDate = (fromIntegral $ dcCount dc fromDate toDate)/360.0+ dcYearFraction dc fromDate toDate = fromIntegral (dcCount dc fromDate toDate) / 360.0 - dcCount ThirtyUSA fd td = 360*(yy2-yy1) + 30*(mm2-mm1-1) + (max 0 (30-dd1)) + (min 30 dd2)- where (y1, mm1, dd1) = toGregorian fd- (y2, m2, d2) = toGregorian td- yy1 = fromIntegral y1- yy2 = fromIntegral y2- (dd2, mm2) = adjust dd1 d2 m2+ dcCount ThirtyUSA fd td = 360*(yy2-yy1) + 30*(mm2-mm1-1) + max 0 (30-dd1) + min 30 dd2+ where (yy1, mm1, dd1) = intGregorian fd+ (yy2, m2, d2) = intGregorian td+ (dd2, mm2) = adjust dd1 d2 m2 adjust x1 x2 z2 | x2 == 31 && x1 < 30 = (1, z2+1) | otherwise = (x2, z2) - dcCount ThirtyEuropean fd td = 360*(yy2-yy1) + 30*(m2-m1-1) + (max 0 (30-d1)) + (min 30 d2)- where (y1, m1, d1) = toGregorian fd- (y2, m2, d2) = toGregorian td- yy1 = fromIntegral y1- yy2 = fromIntegral y2+ dcCount ThirtyEuropean fd td = 360*(yy2-yy1) + 30*(m2-m1-1) + max 0 (30-d1) + min 30 d2+ where (yy1, m1, d1) = intGregorian fd+ (yy2, m2, d2) = intGregorian td - dcCount ThirtyItalian fd td = 360*(yy2-yy1) + 30*(mm2-mm1-1) + (max 0 (30-dd1)) + (min 30 dd2)- where (y1, mm1, d1) = toGregorian fd- (y2, mm2, d2) = toGregorian td- yy1 = fromIntegral y1- yy2 = fromIntegral y2- dd1 = adjust d1 mm1- dd2 = adjust d2 mm2+ dcCount ThirtyItalian fd td = 360*(yy2-yy1) + 30*(mm2-mm1-1) + max 0 (30-dd1) + min 30 dd2+ where (yy1, mm1, d1) = intGregorian fd+ (yy2, mm2, d2) = intGregorian td+ dd1 = adjust d1 mm1+ dd2 = adjust d2 mm2 adjust x1 z1 | z1 == 2 && x1 > 27 = 30 | otherwise = x1 +intGregorian :: Day -> (Int, Int, Int)+intGregorian date = (fromIntegral y, m, d)+ where (y, m, d) = toGregorian date
src/QuantLib/VolatilityModel.hs view
@@ -35,7 +35,7 @@ (result, _) = M.foldrWithKey volFunc ([], Nothing) series volFunc _ s (xs, Nothing) = (xs, Just s) volFunc k s (xs, Just s0) = ((k, estimator s0 s):xs, Just s)- estimator s0 s1 = (abs $ log (s1/s0))/yf+ estimator s0 s1 = abs (log (s1 / s0) ) / yf -- | Garman-Klass interval estimators data GarmanKlass = GarmanKlass {@@ -45,7 +45,7 @@ instance IntervalVolatilityEstimator GarmanKlass where iveCalculate (GarmanKlass yf) ipc series = M.fromList result where result = M.foldrWithKey volFunc [] series- volFunc k s xs = (k, (abs $ calculatePoint s)/yf):xs+ volFunc k s xs = (k, abs (calculatePoint s) / yf):xs calculatePoint = ipcCalculatePoint ipc -- | Types of Garman-Klass estimators@@ -53,7 +53,7 @@ | ParkinsonSigma instance IntervalPointCalculator GarmanKlassPoint where- ipcCalculatePoint GarmanKlassSimpleSigma (IntervalPrice open _ _ close) = (log (close/open))**2+ ipcCalculatePoint GarmanKlassSimpleSigma (IntervalPrice open _ _ close) = log (close/open) ** 2 ipcCalculatePoint ParkinsonSigma (IntervalPrice o h l _) = (u-d)**2 / 4.0 / log 2.0 where u = log (h/o)