packages feed

hquantlib 0.0.2.1 → 0.0.2.3

raw patch · 9 files changed

+209/−17 lines, 9 filesdep +HUnitdep +QuickCheckdep +test-frameworkdep ~basePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: HUnit, QuickCheck, test-framework, test-framework-hunit, test-framework-quickcheck2

Dependency ranges changed: base

API changes (from Hackage documentation)

- QuantLib.Instruments: iErrorEstimate :: Instrument a => a -> Double
- QuantLib.Instruments: iNPV :: Instrument a => a -> Double
+ QuantLib.Math.Copulas: AliMikhailHaqCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: ClaytonCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: FarlieGumbelMorgensternCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: FrankCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: GalambosCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: GaussianCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: GumbelCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: HuslerReissCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: IndependentCopula :: Copulas
+ QuantLib.Math.Copulas: MarshallOlkinCopula :: Double -> Double -> Copulas
+ QuantLib.Math.Copulas: MaxCopula :: Copulas
+ QuantLib.Math.Copulas: MinCopula :: Copulas
+ QuantLib.Math.Copulas: PlackettCopula :: Double -> Copulas
+ QuantLib.Math.Copulas: class Copula a where copula t = precheckRange (copulaFunc t)
+ QuantLib.Math.Copulas: data Copulas
+ QuantLib.Math.Copulas: instance Copula Copulas
+ QuantLib.Priceable: class Priceable a
+ QuantLib.Priceable: errorEstimate :: Priceable a => a -> Double
+ QuantLib.Priceable: npv :: Priceable a => a -> Double
- QuantLib.Instruments: CompositeInstrument :: (Map a Double) -> CompositeInstrument a
+ QuantLib.Instruments: CompositeInstrument :: (Map a Double) -> CompositeInstrument
- QuantLib.Instruments: data Instrument a => CompositeInstrument a
+ QuantLib.Instruments: data CompositeInstrument

Files

hquantlib.cabal view
@@ -1,5 +1,5 @@ name:           hquantlib-version:        0.0.2.1+version:        0.0.2.3 license:        LGPL license-file:   LICENSE author:         Pavel Ryzhov@@ -9,7 +9,7 @@ description:    HQuantLib is intended to be a functional style port of QuantLib (http://quantlib.org) build-type:     Simple stability:      alpha-homepage:       http://code.google.com/p/hquantlib/+homepage:       http://github.com/paulrzcz/hquantlib.git cabal-version:  >= 1.10.0  source-repository head@@ -19,8 +19,12 @@ source-repository this         type:           git         location:       https://github.com/paulrzcz/hquantlib.git-        tag:            0.0.2+        tag:            0.0.2.3 +flag optimize+        description : Enable optimizations for library and benchmarks+        default     : True+ library         default-language: Haskell2010         exposed-modules:@@ -29,6 +33,7 @@                 QuantLib.Instruments                 QuantLib.Currencies                 QuantLib.Stochastic+                QuantLib.Priceable                 QuantLib.PricingEngines                 QuantLib.PricingEngines.BlackFormula                 QuantLib.Quotes@@ -37,6 +42,7 @@                 QuantLib.TimeSeries                 QuantLib.Money                 QuantLib.Math+                QuantLib.Math.Copulas                 QuantLib.Prices                 QuantLib.Position                 QuantLib.Options@@ -66,4 +72,18 @@          hs-source-dirs: src         ghc-options:    -Wall+        if flag(optimize)+                ghc-options: -funbox-strict-fields -O2 -fspec-constr -fdicts-cheap++Test-Suite main-test+        default-language:   Haskell2010+        type            :   exitcode-stdio-1.0+        main-is         :   Test.hs+        hs-source-dirs  :   src+        build-depends   :   base,+                            test-framework  >= 0.6,+                            test-framework-hunit >= 0.2.7,+                            test-framework-quickcheck2 >= 0.2.12.0,+                            QuickCheck      >= 2.4.0,+                            HUnit           >= 1.2.4.0 
src/QuantLib.hs view
@@ -5,3 +5,4 @@ import QuantLib.Position as Q import QuantLib.TimeSeries as Q import QuantLib.Prices as Q+import QuantLib.Math as Q
src/QuantLib/Instruments.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ExistentialQuantification #-} module QuantLib.Instruments         ( module QuantLib.Instruments.Instrument         , module QuantLib.Instruments.Stock
src/QuantLib/Instruments/Instrument.hs view
@@ -1,23 +1,25 @@+{-# LANGUAGE ExistentialQuantification #-} module QuantLib.Instruments.Instrument-        (module QuantLib.Instruments.Instrument-        ) where+    ( Instrument (..)+    , CompositeInstrument (..)+    ) where  import Data.Time.LocalTime import qualified Data.Map as M+import QuantLib.Priceable  -- | Instrument type class class Instrument a where-        iNPV            :: a->Double-        iErrorEstimate  :: a->Double-        iDate           :: a->LocalTime-        iIsExpired      :: a->Bool+        iDate           :: a -> LocalTime+        iIsExpired      :: a -> Bool  -- | Composite instrument is an aggregate of other instruments.-data Instrument a => CompositeInstrument a = CompositeInstrument (M.Map a Double) -        deriving (Show)+data CompositeInstrument = forall a . (Instrument a, Priceable a) => CompositeInstrument (M.Map a Double)  -instance Instrument a => Instrument (CompositeInstrument a) where-        iNPV (CompositeInstrument xs)   = M.foldrWithKey (\k x y -> y + iNPV k * x) 0.0 xs-        iErrorEstimate _                = 0.0+instance Priceable CompositeInstrument where+        npv (CompositeInstrument xs)   = M.foldrWithKey (\k x y -> y + npv k * x) 0.0 xs+        errorEstimate _                = 0.0++instance Instrument CompositeInstrument where         iDate (CompositeInstrument xs)  = (iDate . head . M.keys) xs         iIsExpired (CompositeInstrument xs) = (any iIsExpired . M.keys) xs
src/QuantLib/Instruments/Stock.hs view
@@ -2,8 +2,9 @@         ( module QuantLib.Instruments.Stock         ) where -import QuantLib.Instruments.Instrument import Data.Time.LocalTime+import QuantLib.Instruments.Instrument+import QuantLib.Priceable  -- | Single stock instrument  data Stock = Stock {@@ -12,8 +13,9 @@         } deriving (Show)  instance Instrument Stock where-       iNPV             = sQuote-       iErrorEstimate _ = 0.0        iDate            = sDate        iIsExpired     _ = False +instance Priceable Stock where+    npv (Stock q _)     = q+    errorEstimate _     = 0.0
src/QuantLib/Math.hs view
@@ -1,5 +1,7 @@ module QuantLib.Math         ( module QuantLib.Math.InverseNormal+        , module QuantLib.Math.Copulas         ) where  import QuantLib.Math.InverseNormal+import QuantLib.Math.Copulas
+ src/QuantLib/Math/Copulas.hs view
@@ -0,0 +1,128 @@+module QuantLib.Math.Copulas+        ( Copula,+          Copulas (..) +        ) where++{-| Copula type class. + -| Normally instance should implement only copulaFunc.+ -| Method copula provides a precheck for [0..1] range for x and y but real implementation is in copulaFunc+ -}+class Copula a where+        copula :: a -> Double -> Double -> Maybe Double+        copula t = precheckRange (copulaFunc t)+        copulaFunc :: a -> Double -> Double -> Maybe Double++-- Copula must be in [0,1] range+precheckRange :: (Double->Double->Maybe Double) -> Double -> Double -> Maybe Double+precheckRange f x y+        | x >= 0.0 || x <= 1.0+        || y>= 0.0 || y <= 1.0+                = f x y+        | otherwise+                = Nothing++{-| Copula data types with parameters required by the concrete copula definition+ -}+data Copulas = ClaytonCopula Double+        | MinCopula+        | MaxCopula+        | AliMikhailHaqCopula Double+        | FarlieGumbelMorgensternCopula Double+        | FrankCopula Double+        | GalambosCopula Double+        | GaussianCopula Double+        | GumbelCopula Double+        | HuslerReissCopula Double+        | IndependentCopula+        | MarshallOlkinCopula Double Double+        | PlackettCopula Double++instance Copula Copulas where+        copulaFunc (ClaytonCopula theta)                    = claytonCopula theta+        copulaFunc MinCopula                                = minCopula+        copulaFunc MaxCopula                                = maxCopula+        copulaFunc (AliMikhailHaqCopula theta)              = aliMikhailHaqCopula theta+        copulaFunc (FarlieGumbelMorgensternCopula theta)    = farlieGumbelMorgenstern theta+        copulaFunc (FrankCopula theta)                      = frankCopula theta+        copulaFunc (GalambosCopula theta)                   = galambosCopula theta+        copulaFunc (GaussianCopula rho)                     = gaussianCopula rho+        copulaFunc (GumbelCopula theta)                     = gumbelCopula theta+        copulaFunc (HuslerReissCopula theta)                = huslerReissCopula theta +        copulaFunc IndependentCopula                        = independentCopula+        copulaFunc (MarshallOlkinCopula a b)                = marshallOlkinCopula a b+        copulaFunc (PlackettCopula theta)                   = plackettCopula theta++{- Private implementations   -}++aliMikhailHaqCopula :: (Fractional a, Ord a) => a -> a -> a -> Maybe a+aliMikhailHaqCopula theta x y+        | theta >= -1.0 && theta <= 1.0+                = Just ((x*y)/(1.0 - theta * (1.0-x)*(1.0-y)))+        | otherwise+                = Nothing++farlieGumbelMorgenstern :: (Fractional a, Ord a) => a -> a -> a -> Maybe a+farlieGumbelMorgenstern theta x y+        | theta >= -1.0 && theta <= 1.0+                = Just (x*y + theta*x*y*(1.0-x)*(1.0-y))+        | otherwise+                = Nothing++{-|  Original code and algorithm from the Quantlib project+     implemented in Haskell by Nicholas Pezolano +                                  npezolano "at" gmail.com+-}+claytonCopula :: Double -> Double -> Double -> Maybe Double+claytonCopula theta x y+	|  theta ==0 +	|| theta < -1.0+	 = Nothing++	| otherwise +	= Just $ max( (x ** (-theta) ) +   (y ** (-theta)-1.0)  **   (-1.0/theta)) 0+	+minCopula ::  Ord a => a -> a -> Maybe a+minCopula x y = Just (min x y)++maxCopula ::  (Fractional a, Ord a) => a -> a -> Maybe a+maxCopula x y = Just (max 0.0 (x+y-1.0))++frankCopula ::  (Eq a, Floating a) => a -> a -> a -> Maybe a+frankCopula theta x y+    | theta     == 0.0 = Nothing+    | otherwise = Just (-1.0/theta * log (1 + (exp (-theta*x) - 1.0) * (exp (-theta*y) -1.0) / (exp (-theta) - 1.0)   ))+ +galambosCopula ::  (Floating a, Ord a) => a -> a -> a -> Maybe a+galambosCopula theta x y+    | theta <= 0.0  = Nothing+    | otherwise     = Just (x * y * exp ( ( (-log x) ** (-theta) + (-log y) ** (-theta) ) ** (-1.0/theta)  ))++gaussianCopula ::  (Fractional a, Ord a) => a -> t -> t1 -> Maybe a1+gaussianCopula rho x y+    | rho >= -1.0 && rho <= 1.0 = undefined+    | otherwise                 = Nothing++gumbelCopula ::  (Floating a, Ord a) => a -> a -> a -> Maybe a+gumbelCopula theta x y+    | theta >= 1.0  = Just (exp ( - ( (-log x) ** theta + (-log y) ** theta) ** (1.0/theta)))+    | otherwise     = Nothing++huslerReissCopula theta x y+    | theta > 0.0   = undefined+    | otherwise     = Nothing++independentCopula ::  Num a => a -> a -> Maybe a+independentCopula x y = Just (x*y)++marshallOlkinCopula :: (Floating a, Ord a) => a -> a -> a -> a -> Maybe a+marshallOlkinCopula a b x y+    | a >= 0.0 && b >= 0.0  = Just (min (y * (x ** (1-a))) (x * (y ** (1-b))))+    | otherwise             = Nothing++plackettCopula ::  (Floating a, Ord a) => a -> a -> a -> Maybe a+plackettCopula theta x y+    | theta >= 0.0 && theta /= 1.0  = Just $ (sumXyTheta1 - sqrt (sumXyTheta1 * sumXyTheta1 - 4.0 * x * y * theta * theta1))/(2*theta1)+    | otherwise                     = Nothing+        where   sumXy           = x + y+                theta1          = theta - 1.0+                sumXyTheta1     = 1.0 + theta1 * sumXy
+ src/QuantLib/Priceable.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE ExistentialQuantification #-}+module QuantLib.Priceable+    ( Priceable (..)+    ) where++-- | All instruments and events have a net present value+class Priceable a where+    npv             :: a -> Double+    errorEstimate   :: a -> Double+
+ src/Test.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE BangPatterns #-}+module Main where++import Test.Framework (Test)+import Test.Framework (defaultMain, testGroup)+import Test.Framework.Providers.HUnit+import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck hiding ( (==>) )++main :: IO () +main = defaultMain tests++ignore :: Functor f => f a -> f () +ignore = fmap (const ())++sumTest :: Int->Int->Int+sumTest x y = x + y++tests :: [Test]+tests = +    [ testGroup "cases" $ zipWith (testCase . show) [1 :: Int ..] $+        [] +    , testGroup "properties" $ zipWith (testProperty . show) [1 :: Int ..] $ +        [ property $ \ a b -> sumTest a b == a + b+        ] +    ]