module Q.ContingentClaim.Options where

import           Data.Time
import           Q.ContingentClaim
import           Q.Types

vanillaPayout :: OptionType  -- ^ Put or call
              -> Double      -- ^ strike
              -> Double      -- ^ Observable level
              -> Double      -- ^ Payout
vanillaPayout :: OptionType -> Double -> Double -> Double
vanillaPayout OptionType
Call Double
k Double
s = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (Double
s Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
k) Double
0
vanillaPayout OptionType
Put  Double
k Double
s = Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
s) Double
0


spreadPayout :: OptionType -- ^ Put or call
             -> Double     -- ^ Low strike
             -> Double     -- ^ High strike
             -> Double     -- ^ Observable level
             -> Double     -- ^ Payout

straddlePayout :: Double -- ^ Strike
               -> Double -- ^ Observable
               -> Double -- ^ Payout
straddlePayout :: Double -> Double -> Double
straddlePayout Double
k Double
s = (OptionType -> Double -> Double -> Double
vanillaPayout OptionType
Call Double
k Double
s) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (OptionType -> Double -> Double -> Double
vanillaPayout OptionType
Put Double
k Double
s)

spreadPayout :: OptionType -> Double -> Double -> Double -> Double
spreadPayout OptionType
Call Double
lowStrike Double
highStrike Double
s = (OptionType -> Double -> Double -> Double
vanillaPayout OptionType
Call Double
lowStrike Double
s) Double -> Double -> Double
forall a. Num a => a -> a -> a
- (OptionType -> Double -> Double -> Double
vanillaPayout OptionType
Call Double
highStrike Double
s)
spreadPayout OptionType
Put Double
lowStrike Double
highStrike Double
s = (OptionType -> Double -> Double -> Double
vanillaPayout OptionType
Put Double
highStrike Double
s) Double -> Double -> Double
forall a. Num a => a -> a -> a
- (OptionType -> Double -> Double -> Double
vanillaPayout OptionType
Put Double
lowStrike Double
s)

vanillaOption :: OptionType -- ^ Option type
  -> Double                 -- ^ Strike
  -> LocalTime              -- ^ Expiry
  -> ContingentClaim Double -- ^ Contingent claim
vanillaOption :: OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
cp Double
k LocalTime
t = LocalTime
-> CCBuilder
     (ContingentClaim Double) (Map LocalTime Double) CashFlow
-> ContingentClaim Double
forall a.
LocalTime
-> CCBuilder (ContingentClaim a) (Map LocalTime a) CashFlow
-> ContingentClaim a
pay LocalTime
t (CCBuilder (ContingentClaim Double) (Map LocalTime Double) CashFlow
 -> ContingentClaim Double)
-> CCBuilder
     (ContingentClaim Double) (Map LocalTime Double) CashFlow
-> ContingentClaim Double
forall a b. (a -> b) -> a -> b
$ do
  Double
s <- LocalTime
-> CCBuilder (ContingentClaim Double) (Map LocalTime Double) Double
forall a.
LocalTime -> CCBuilder (ContingentClaim a) (Map LocalTime a) a
monitor LocalTime
t
  CashFlow
-> CCBuilder
     (ContingentClaim Double) (Map LocalTime Double) CashFlow
forall (m :: * -> *) a. Monad m => a -> m a
return (CashFlow
 -> CCBuilder
      (ContingentClaim Double) (Map LocalTime Double) CashFlow)
-> CashFlow
-> CCBuilder
     (ContingentClaim Double) (Map LocalTime Double) CashFlow
forall a b. (a -> b) -> a -> b
$ LocalTime -> Double -> CashFlow
CashFlow LocalTime
t (Double -> CashFlow) -> Double -> CashFlow
forall a b. (a -> b) -> a -> b
$ OptionType -> Double -> Double -> Double
vanillaPayout OptionType
cp Double
k Double
s

callOption :: Double -> LocalTime -> ContingentClaim Double
callOption = OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Call
putOption :: Double -> LocalTime -> ContingentClaim Double
putOption = OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Put

-- | A call spread is a portfolio: \(C(K1, T) - C(K2 T) \) s.t. \( K1 < K2 \)
callSpread :: Double -> Double -> LocalTime -> ContingentClaim Double
callSpread Double
k1 Double
k2 LocalTime
t = (OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Call Double
k1 LocalTime
t) ContingentClaim Double
-> ContingentClaim Double -> ContingentClaim Double
forall a. Semigroup a => a -> a -> a
<> (ContingentClaim Double -> ContingentClaim Double
forall a. ContingentClaim a -> ContingentClaim a
short (ContingentClaim Double -> ContingentClaim Double)
-> ContingentClaim Double -> ContingentClaim Double
forall a b. (a -> b) -> a -> b
$ OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Call Double
k2 LocalTime
t)

-- | A put spread is a portfolio: \(P(K2, T) - P(K1 T) \) s.t. \( K1 < K2 \)
putSpread :: Double -> Double -> LocalTime -> ContingentClaim Double
putSpread Double
k1 Double
k2 LocalTime
t = (OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Put Double
k2 LocalTime
t) ContingentClaim Double
-> ContingentClaim Double -> ContingentClaim Double
forall a. Semigroup a => a -> a -> a
<> (ContingentClaim Double -> ContingentClaim Double
forall a. ContingentClaim a -> ContingentClaim a
short (ContingentClaim Double -> ContingentClaim Double)
-> ContingentClaim Double -> ContingentClaim Double
forall a b. (a -> b) -> a -> b
$ OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Put Double
k1 LocalTime
t)

-- | A straddle is a a portfolio :\(C(K, T) + Put(K, T)\)
straddle :: Double -> LocalTime -> ContingentClaim Double
straddle :: Double -> LocalTime -> ContingentClaim Double
straddle Double
strike LocalTime
t = OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Put Double
strike LocalTime
t ContingentClaim Double
-> ContingentClaim Double -> ContingentClaim Double
forall a. Semigroup a => a -> a -> a
<> OptionType -> Double -> LocalTime -> ContingentClaim Double
vanillaOption OptionType
Call Double
strike LocalTime
t