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 a
x = Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
0.0 (a -> Maybe Double
forall a. Quote a => a -> Maybe Double
qValue a
x)

-- | Market element returning a stored value
data SimpleQuote = SimpleQuote (Maybe Double)
        deriving (Int -> SimpleQuote -> ShowS
[SimpleQuote] -> ShowS
SimpleQuote -> String
(Int -> SimpleQuote -> ShowS)
-> (SimpleQuote -> String)
-> ([SimpleQuote] -> ShowS)
-> Show SimpleQuote
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SimpleQuote] -> ShowS
$cshowList :: [SimpleQuote] -> ShowS
show :: SimpleQuote -> String
$cshow :: SimpleQuote -> String
showsPrec :: Int -> SimpleQuote -> ShowS
$cshowsPrec :: Int -> SimpleQuote -> ShowS
Show, SimpleQuote -> SimpleQuote -> Bool
(SimpleQuote -> SimpleQuote -> Bool)
-> (SimpleQuote -> SimpleQuote -> Bool) -> Eq SimpleQuote
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SimpleQuote -> SimpleQuote -> Bool
$c/= :: SimpleQuote -> SimpleQuote -> Bool
== :: SimpleQuote -> SimpleQuote -> Bool
$c== :: SimpleQuote -> SimpleQuote -> Bool
Eq)

instance Quote SimpleQuote where
        qValue :: SimpleQuote -> Maybe Double
qValue (SimpleQuote Maybe Double
x) = Maybe Double
x

-- | Market element whose value depends on two other market elements
data CompositeQuote a = CompositeQuote {
        -- | First element
        CompositeQuote a -> a
cqQuote1        :: a,
        -- | Second element
        CompositeQuote a -> a
cqQuote2        :: a,
        -- | Composition function
        CompositeQuote a -> a -> a -> Maybe Double
cqComposite     :: a->a->Maybe Double
        }

instance Quote (CompositeQuote a) where
        qValue :: CompositeQuote a -> Maybe Double
qValue CompositeQuote a
x        = CompositeQuote a -> a -> a -> Maybe Double
forall a. CompositeQuote a -> a -> a -> Maybe Double
cqComposite CompositeQuote a
x (CompositeQuote a -> a
forall a. CompositeQuote a -> a
cqQuote1 CompositeQuote a
x) (CompositeQuote a -> a
forall a. CompositeQuote a -> a
cqQuote2 CompositeQuote a
x)

-- | Market element whose value depends on another quote
data DerivedQuote a = DerivedQuote {
        DerivedQuote a -> a
dqQuote         :: a,
        DerivedQuote a -> a -> Maybe Double
dqDerivateFunc  :: a->Maybe Double
        }

instance Quote (DerivedQuote a) where
        qValue :: DerivedQuote a -> Maybe Double
qValue DerivedQuote a
x        = DerivedQuote a -> a -> Maybe Double
forall a. DerivedQuote a -> a -> Maybe Double
dqDerivateFunc DerivedQuote a
x (DerivedQuote a -> a
forall a. DerivedQuote a -> a
dqQuote DerivedQuote a
x)

-- | Quote for the implied standard deviation of an underlying
data ImpliedStdDevQuote a = ImpliedStdDevQuote {
        ImpliedStdDevQuote a -> OptionType
isdqOptionType  :: OptionType,
        ImpliedStdDevQuote a -> a
isdqForward     :: a,
        ImpliedStdDevQuote a -> a
isdqPrice       :: a,
        ImpliedStdDevQuote a -> Double
isdqStrike      :: Double,
        ImpliedStdDevQuote a -> Maybe Double
isdqGuess       :: Maybe Double
        } deriving (Int -> ImpliedStdDevQuote a -> ShowS
[ImpliedStdDevQuote a] -> ShowS
ImpliedStdDevQuote a -> String
(Int -> ImpliedStdDevQuote a -> ShowS)
-> (ImpliedStdDevQuote a -> String)
-> ([ImpliedStdDevQuote a] -> ShowS)
-> Show (ImpliedStdDevQuote a)
forall a. Show a => Int -> ImpliedStdDevQuote a -> ShowS
forall a. Show a => [ImpliedStdDevQuote a] -> ShowS
forall a. Show a => ImpliedStdDevQuote a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ImpliedStdDevQuote a] -> ShowS
$cshowList :: forall a. Show a => [ImpliedStdDevQuote a] -> ShowS
show :: ImpliedStdDevQuote a -> String
$cshow :: forall a. Show a => ImpliedStdDevQuote a -> String
showsPrec :: Int -> ImpliedStdDevQuote a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> ImpliedStdDevQuote a -> ShowS
Show)

instance Quote a => Quote (ImpliedStdDevQuote a) where
        qValue :: ImpliedStdDevQuote a -> Maybe Double
qValue (ImpliedStdDevQuote OptionType
opType a
fwd a
price Double
strike Maybe Double
guess) 
                = OptionType
-> Double
-> Double
-> Double
-> Double
-> Double
-> Maybe Double
-> Double
-> Int
-> Maybe Double
blackFormulaImpliedStdDev OptionType
opType (a -> Double
forall a. Quote a => a -> Double
pureValue a
fwd) (a -> Double
forall a. Quote a => a -> Double
pureValue a
price) Double
strike Double
1.0 Double
0.0 Maybe Double
guess Double
1.0e-6 Int
100

-- | Quote for the Eurodollar-future implied standard deviation
data EurodollarFutureQuote a = EurodollarFutureQuote {
        EurodollarFutureQuote a -> a
efqForward      :: a,
        EurodollarFutureQuote a -> a
efqCallPrice    :: a,
        EurodollarFutureQuote a -> a
efqPutPrice     :: a,
        EurodollarFutureQuote a -> Double
efqStrike       :: Double,
        EurodollarFutureQuote a -> Maybe Double
efqGuess        :: Maybe Double
        } deriving (Int -> EurodollarFutureQuote a -> ShowS
[EurodollarFutureQuote a] -> ShowS
EurodollarFutureQuote a -> String
(Int -> EurodollarFutureQuote a -> ShowS)
-> (EurodollarFutureQuote a -> String)
-> ([EurodollarFutureQuote a] -> ShowS)
-> Show (EurodollarFutureQuote a)
forall a. Show a => Int -> EurodollarFutureQuote a -> ShowS
forall a. Show a => [EurodollarFutureQuote a] -> ShowS
forall a. Show a => EurodollarFutureQuote a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EurodollarFutureQuote a] -> ShowS
$cshowList :: forall a. Show a => [EurodollarFutureQuote a] -> ShowS
show :: EurodollarFutureQuote a -> String
$cshow :: forall a. Show a => EurodollarFutureQuote a -> String
showsPrec :: Int -> EurodollarFutureQuote a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> EurodollarFutureQuote a -> ShowS
Show)

instance Quote a => Quote (EurodollarFutureQuote a) where
        qValue :: EurodollarFutureQuote a -> Maybe Double
qValue (EurodollarFutureQuote a
forward a
callPrice a
putPrice Double
strike Maybe Double
guess)
                | Double
strike Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
forwardValue = OptionType
-> Double
-> Double
-> Double
-> Double
-> Double
-> Maybe Double
-> Double
-> Int
-> Maybe Double
blackFormulaImpliedStdDev OptionType
Call Double
strike Double
forwardValue Double
putValue Double
1.0 Double
0.0 Maybe Double
guess Double
1.0e-6 Int
100
                | Bool
otherwise     = OptionType
-> Double
-> Double
-> Double
-> Double
-> Double
-> Maybe Double
-> Double
-> Int
-> Maybe Double
blackFormulaImpliedStdDev OptionType
Put Double
strike Double
forwardValue Double
callValue Double
1.0 Double
0.0 Maybe Double
guess Double
1.0e-6 Int
100
                where
                        forwardValue :: Double
forwardValue = Double
100.0 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
0.0 (a -> Maybe Double
forall a. Quote a => a -> Maybe Double
qValue a
forward)
                        putValue :: Double
putValue     = Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
0.0 (a -> Maybe Double
forall a. Quote a => a -> Maybe Double
qValue a
putPrice)
                        callValue :: Double
callValue    = Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
0.0 (a -> Maybe Double
forall a. Quote a => a -> Maybe Double
qValue a
callPrice)