module Q.Options (
    Valuation(..)
  , intrinsinc
  , hasTimeValue
  , module Q.Types) where

import           Numeric.IEEE
import           Q.Types


data Valuation = Valuation {
    Valuation -> Premium
vPremium :: Premium
  , Valuation -> Delta
vDelta   :: Delta
  , Valuation -> Vega
vVega    :: Vega
  , Valuation -> Gamma
vGamma   :: Gamma
} deriving (Int -> Valuation -> ShowS
[Valuation] -> ShowS
Valuation -> String
(Int -> Valuation -> ShowS)
-> (Valuation -> String)
-> ([Valuation] -> ShowS)
-> Show Valuation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Valuation] -> ShowS
$cshowList :: [Valuation] -> ShowS
show :: Valuation -> String
$cshow :: Valuation -> String
showsPrec :: Int -> Valuation -> ShowS
$cshowsPrec :: Int -> Valuation -> ShowS
Show)


-- | intrinsinc value of an option.
intrinsinc :: OptionType -> Forward -> Strike -> DF -> Double
intrinsinc :: OptionType -> Forward -> Strike -> DF -> Double
intrinsinc OptionType
Call (Forward Double
f) (Strike Double
k) (DF Double
df) = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (Double
f Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
k) Double
0
intrinsinc OptionType
Put  (Forward Double
f) (Strike Double
k) (DF Double
df) = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
f) Double
0

-- | returns True if the undiscounted option premium is greater than the 'intrinsinc'
hasTimeValue ::
     OptionType
  -> Forward
  -> Strike
  -> Premium
  -> DF
  -> Bool
hasTimeValue :: OptionType -> Forward -> Strike -> Premium -> DF -> Bool
hasTimeValue OptionType
cp Forward
f Strike
k Premium
p DF
df =  DF
df DF -> Double -> Double
`undiscount` Double
p' Double -> Double -> Double
forall a. Num a => a -> a -> a
- (OptionType -> Forward -> Strike -> DF -> Double
intrinsinc OptionType
cp Forward
f Strike
k DF
df) Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
forall a. IEEE a => a
epsilon
    where (Premium Double
p') = Premium
p