packages feed

hquantlib 0.0.1 → 0.0.1.1

raw patch · 13 files changed

+372/−5 lines, 13 files

Files

hquantlib.cabal view
@@ -1,5 +1,5 @@ name:           hquantlib-version:        0.0.1+version:        0.0.1.1 license:        LGPL license-file:   LICENSE author:         Pavel Ryzhov@@ -29,6 +29,19 @@                 QuantLib.Instruments                 QuantLib.Currencies                 QuantLib.Stochastic+                QuantLib.PricingEngines+                QuantLib.PricingEngines.BlackFormula+                QuantLib.Quotes+                QuantLib.VolatilityModel+                QuantLib.TimeSeries+                QuantLib.Money+                QuantLib.Position+        +        other-modules:+                QuantLib.Currencies.America+                QuantLib.Currencies.Europe+                QuantLib.Instruments.Instrument+                QuantLib.Instruments.Stock                  build-depends:                           haskell2010 == 1.0.0.0,
src/QuantLib.hs view
@@ -1,18 +1,14 @@ module QuantLib         ( module QuantLib.Stochastic         , module QuantLib.Money-        , module QuantLib.Currencies         , module QuantLib.Position         , module QuantLib.TimeSeries         , module QuantLib.Prices-        , module QuantLib.VolatilityModel         )         where  import QuantLib.Stochastic import QuantLib.Money-import QuantLib.Currencies import QuantLib.Position import QuantLib.TimeSeries import QuantLib.Prices-import QuantLib.VolatilityModel
+ src/QuantLib/Currencies/America.hs view
@@ -0,0 +1,24 @@+module QuantLib.Currencies.America+        ( module QuantLib.Currencies.America+        ) where ++import QuantLib.Currency++-- | Canadian dollar+cad :: Currency+cad = Currency {+        cName           = "Canadian dollar",+        cCode           = "CAD",+        cIsoCode        = 124,+        cFracsPerUnit   = 100+        }++-- | U.S. dollar+usd :: Currency+usd = Currency {+        cName           = "U.S. dollar",+        cCode           = "USD",+        cIsoCode        = 840,+        cFracsPerUnit   = 100+        }+
+ src/QuantLib/Currencies/Europe.hs view
@@ -0,0 +1,51 @@+module QuantLib.Currencies.Europe+        ( module QuantLib.Currencies.Europe+        ) where++import QuantLib.Currency++-- | Swiss france+chf :: Currency+chf = Currency {+        cName           = "Swiss franc",+        cCode           = "CHF",+        cIsoCode        = 756,+        cFracsPerUnit   = 100+        }++-- | Czech koruna+czk :: Currency+czk = Currency {+        cName           = "Czech koruna",+        cCode           = "CZK",+        cIsoCode        = 203,+        cFracsPerUnit   = 100+        }++-- | Danish krone+dkk :: Currency+dkk = Currency {+        cName           = "Danish krone",+        cCode           = "DKK",+        cIsoCode        = 208,+        cFracsPerUnit   = 100+        }++-- | European Euro+eur :: Currency+eur = Currency {+        cName           = "European Euro",+        cCode           = "EUR",+        cIsoCode        = 978,+        cFracsPerUnit   = 100+        }++-- | British pound sterling+gbp :: Currency+gbp = Currency {+        cName           = "British pound sterling",+        cCode           = "GBP",+        cIsoCode        = 826,+        cFracsPerUnit   = 100+        }+
+ src/QuantLib/Instruments/Instrument.hs view
@@ -0,0 +1,23 @@+module QuantLib.Instruments.Instrument+        (module QuantLib.Instruments.Instrument+        ) where++import Data.Time.LocalTime+import qualified Data.Map as M++-- | Instrument type class+class Instrument a where+        iNPV            :: a->Double+        iErrorEstimate  :: a->Double+        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)++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+        iDate (CompositeInstrument xs)  = (iDate . head . M.keys) xs+        iIsExpired (CompositeInstrument xs) = (any iIsExpired . M.keys) xs
+ src/QuantLib/Instruments/Stock.hs view
@@ -0,0 +1,19 @@+module QuantLib.Instruments.Stock+        ( module QuantLib.Instruments.Stock+        ) where++import QuantLib.Instruments.Instrument+import Data.Time.LocalTime++-- | Single stock instrument +data Stock = Stock {+        sQuote  :: Double,+        sDate   :: LocalTime+        } deriving (Show)++instance Instrument Stock where+       iNPV             = sQuote+       iErrorEstimate _ = 0.0+       iDate            = sDate+       iIsExpired     _ = False+
+ src/QuantLib/Money.hs view
@@ -0,0 +1,28 @@+module QuantLib.Money+        ( module QuantLib.Money+        ) where++import QuantLib.Currency+import QuantLib.Currencies.Europe (eur)++-- | Amount of cash. Please, note that currency conversion is not implemented yet.+data Money = Money {+        mValue          :: Double,+        mCurrency       :: Currency+        } deriving (Eq)++instance Show Money where+        showsPrec _ (Money v c) s = show v++" "++show c++s++instance Num Money where+        (+) (Money v0 c0) (Money v1 c1)+                | c0 == c1      = Money (v0+v1) c0+                | otherwise     = error "Currency conversion is not implemented"+        (*) _ _         = error "Multiplying moneys has no sense"+        (-) (Money v0 c0) (Money v1 c1)+                | c0 == c1      = Money (v0-v1) c0+                | otherwise     = error "Currency conversion is not implemented"+        negate (Money v c)      = Money (-v) c+        abs    (Money v c)      = Money (abs v) c+        signum (Money v c)      = Money (signum v) c+        fromInteger     i       = Money (fromInteger i) eur
+ src/QuantLib/Position.hs view
@@ -0,0 +1,7 @@+module QuantLib.Position+        (module QuantLib.Position+        ) where++-- | Position types+data Position = Long | Short+        deriving (Show, Eq)
+ src/QuantLib/PricingEngines.hs view
@@ -0,0 +1,6 @@+module QuantLib.PricingEngines+        ( module QuantLib.PricingEngines+        ) where++class PricingEngine a where+        peCalculate :: a->a
+ src/QuantLib/PricingEngines/BlackFormula.hs view
@@ -0,0 +1,56 @@+module QuantLib.PricingEngines.BlackFormula+        ( blackFormulaImpliedStdDev+        ) where++import Data.Maybe+import QuantLib.Options+import Numeric.GSL.Root+import Numeric.GSL.Special.Erf++blackFormulaImpliedStdDev :: OptionType->Double->Double->Double->Double->Double->Maybe Double->Double->Int->Maybe Double+blackFormulaImpliedStdDev opType strike forward blackPrice discount displacement guess accuracy maxIter+        | blackPrice < 0.0      = Nothing+        | discount  <= 0.0      = Nothing+        | strike     < 0.0      = Nothing+        | forward   <= 0.0      = Nothing+        | displacement < 0.0    = Nothing+        | otherwise             = Just stdDev+        where+                realGuess               = fromMaybe apprGuess guess+                apprGuess               = blackFormulaImpliedStdDevApproximation opType strike forward blackPrice discount displacement+                blackFunction           = blackImpliedStdDevHelper opType strike forward blackPrice displacement+                ([stdDev], _)           = root DNewton accuracy maxIter blackFunction [realGuess]++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)+                signedD1 = d + temp+                signedD2 = d - temp+                d        = signedMoneyness/x+                temp     = intOpType * 0.5 * x+                intOpType= toDouble opType+                signedMoneyness = intOpType*log ((forward+displacement)/(strike+displacement))+                signedForward = intOpType*(forward+displacement)+                signedStrike  = intOpType*(strike +displacement)++blackImpliedStdDevHelper _ _ _ _ _ _ = undefined++cdf ::  Double -> Double+cdf x = 0.5 * (1 + erf (x/(sqrt 2)))++blackFormulaImpliedStdDevApproximation :: OptionType-> Double-> Double-> Double-> Double-> Double-> Double+blackFormulaImpliedStdDevApproximation opType strike forward blackPrice discount displacement+        | realStrike == realForward     = blackPrice/discount*sqrt2pi/realForward+        | otherwise     = if stdDev < 0.0 then 0.0 else stdDev+        where   realForward     = forward + displacement+                realStrike      = strike  + displacement+                intOpType       = toDouble opType+                moneynessDelta  = intOpType * (forward-strike)+                moneynessDeltaPi= moneynessDelta**2/pi+                temp1           = blackPrice/discount - moneynessDelta/2.0+                temp2           = temp1**2 - moneynessDeltaPi+                temp3           = if temp2<0.0 then 0.0 else sqrt temp2+                temp            = sqrt2pi*(temp1 + temp3)+                sqrt2pi         = sqrt (2.0*pi)+                stdDev          = temp/(realForward + realStrike)
+ src/QuantLib/Quotes.hs view
@@ -0,0 +1,75 @@+module QuantLib.Quotes+        ( module QuantLib.Quotes+        ) where++import Data.Maybe+import QuantLib.Options+import QuantLib.PricingEngines.BlackFormula++-- | Base type class for market observables+class Quote a where+        qValue :: a->Maybe Double+        pureValue :: a->Double+        pureValue x = fromMaybe 0.0 (qValue x)++-- | Market element returning a stored value+data SimpleQuote = SimpleQuote (Maybe Double)+        deriving (Show, Eq)++instance Quote SimpleQuote where+        qValue (SimpleQuote x) = x++-- | Market element whose value depends on two other market elements+data CompositeQuote a = CompositeQuote {+        -- | First element+        cqQuote1        :: a,+        -- | Second element+        cqQuote2        :: a,+        -- | Composition function+        cqComposite     :: a->a->Maybe Double+        }++instance Quote (CompositeQuote a) where+        qValue x        = (cqComposite x) (cqQuote1 x) (cqQuote2 x)++-- | Market element whose value depends on another quote+data DerivedQuote a = DerivedQuote {+        dqQuote         :: a,+        dqDerivateFunc  :: a->Maybe Double+        }++instance Quote (DerivedQuote a) where+        qValue x        = (dqDerivateFunc x) (dqQuote x)++-- | Quote for the implied standard deviation of an underlying+data ImpliedStdDevQuote a = ImpliedStdDevQuote {+        isdqOptionType  :: OptionType,+        isdqForward     :: a,+        isdqPrice       :: a,+        isdqStrike      :: Double,+        isdqGuess       :: Maybe Double+        } deriving (Show)++instance Quote a => Quote (ImpliedStdDevQuote a) where+        qValue (ImpliedStdDevQuote opType fwd price strike guess) +                = blackFormulaImpliedStdDev opType (pureValue fwd) (pureValue price) strike 1.0 0.0 guess 1.0e-6 100++-- | Quote for the Eurodollar-future implied standard deviation+data EurodollarFutureQuote a = EurodollarFutureQuote {+        efqForward      :: a,+        efqCallPrice    :: a,+        efqPutPrice     :: a,+        efqStrike       :: Double,+        efqGuess        :: Maybe Double+        } deriving (Show)++instance Quote a => Quote (EurodollarFutureQuote a) where+        qValue (EurodollarFutureQuote forward callPrice putPrice strike guess)+                | 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))+                        putValue     = fromMaybe 0.0 (qValue putPrice)+                        callValue    = fromMaybe 0.0 (qValue callPrice)++
+ src/QuantLib/TimeSeries.hs view
@@ -0,0 +1,9 @@+module QuantLib.TimeSeries+        ( module QuantLib.TimeSeries+        ) where++import Data.Time.LocalTime+import qualified Data.Map as M++-- | Time series+type TimeSeries m = M.Map LocalTime m
+ src/QuantLib/VolatilityModel.hs view
@@ -0,0 +1,60 @@+module QuantLib.VolatilityModel+        ( module QuantLib.VolatilityModel+        ) where++import QuantLib.Prices+import QuantLib.TimeSeries+import qualified Data.Map as M++-- | Volatility type+type Volatility = Double++-- | Volatility time series+type VolatilitySeries = TimeSeries Volatility++-- | The estimator of time series of doubles+class DoubleVolatilityEstimator a where+        dveCalculate :: a->TimeSeries Double->VolatilitySeries++-- | The calculator of volatility for interval price+class IntervalPointCalculator a where+        ipcCalculatePoint :: a->IntervalPrice->Volatility++-- | Interval price volatility estimator+class IntervalVolatilityEstimator a where+        iveCalculate :: IntervalPointCalculator b => a->b->TimeSeries IntervalPrice->VolatilitySeries++-- | Simple local estimator+data SimpleLocalEstimator = SimpleLocalEstimator {+        sleYearFraction :: Double+        } deriving (Show, Eq)++instance DoubleVolatilityEstimator SimpleLocalEstimator where+        dveCalculate (SimpleLocalEstimator yf) series = M.fromList result+                where+                       (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++-- | Garman-Klass interval estimators+data GarmanKlass = GarmanKlass {+        gkYearFraction  :: Double+        } deriving (Show, Eq)++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+                        calculatePoint = ipcCalculatePoint ipc++-- | Types of Garman-Klass estimators+data GarmanKlassPoint = GarmanKlassSimpleSigma+        | ParkinsonSigma++instance IntervalPointCalculator GarmanKlassPoint where+        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)+                        d = log (l/o)