-- GENERATED by C->Haskell Compiler, version 0.28.8 Switcheroo, 25 November 2017 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "./QuantLib/Instrument/CapFloor.chs" #-}
module QuantLib.Instrument.CapFloor
  (
    -- * Types
    CapFloor

    -- * Constructors
  , cap
  , collar
  , floor
  , optionlet

    -- * Inspectors
  , atmRate
  , impliedVolatility
  ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.ForeignPtr as C2HSImp
import qualified Foreign.Ptr as C2HSImp


import Prelude hiding(floor)

import QuantLib.Internal
import QuantLib.Internal.Type
import Data.List.NonEmpty(NonEmpty)
import QuantLib.InterestRate(VolatilityType)








{-# LINE 29 "./QuantLib/Instrument/CapFloor.chs" #-}


{-# LINE 30 "./QuantLib/Instrument/CapFloor.chs" #-}


{-# LINE 31 "./QuantLib/Instrument/CapFloor.chs" #-}


-- |constructs a cap: pays the excess of the floating leg's rate over each exercise rate, if positive
cap :: (GenLeg l) -- ^floatingLeg
 -> (NonEmpty Double) -- ^exerciseRates
 -> IO ((CapFloor))
cap :: forall l. GenLeg l -> NonEmpty Double -> IO CapFloor
cap GenLeg l
a1 NonEmpty Double
a2 =
  GenLeg l -> (Ptr CLeg' -> IO CapFloor) -> IO CapFloor
forall l b. GenLeg l -> (Ptr CLeg' -> IO b) -> IO b
withLeg GenLeg l
a1 ((Ptr CLeg' -> IO CapFloor) -> IO CapFloor)
-> (Ptr CLeg' -> IO CapFloor) -> IO CapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr CLeg'
a1' -> 
  NonEmpty Double
-> ((CUInt, Ptr CDouble) -> IO CapFloor) -> IO CapFloor
forall b. NonEmpty Double -> ((CUInt, Ptr CDouble) -> IO b) -> IO b
withNonEmptyDoubleArray NonEmpty Double
a2 (((CUInt, Ptr CDouble) -> IO CapFloor) -> IO CapFloor)
-> ((CUInt, Ptr CDouble) -> IO CapFloor) -> IO CapFloor
forall a b. (a -> b) -> a -> b
$ \(CUInt
a2'1, Ptr CDouble
a2'2) -> 
  (Ptr (Ptr CChar) -> IO CapFloor) -> IO CapFloor
forall a b. (Ptr (Ptr a) -> IO b) -> IO b
preErrorCheck ((Ptr (Ptr CChar) -> IO CapFloor) -> IO CapFloor)
-> (Ptr (Ptr CChar) -> IO CapFloor) -> IO CapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CChar)
a3' -> 
  Ptr CLeg'
-> CUInt -> Ptr CDouble -> Ptr (Ptr CChar) -> IO (Ptr CCapFloor')
cap'_ Ptr CLeg'
a1' CUInt
a2'1  Ptr CDouble
a2'2 Ptr (Ptr CChar)
a3' IO (Ptr CCapFloor')
-> (Ptr CCapFloor' -> IO CapFloor) -> IO CapFloor
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Ptr CCapFloor'
res ->
  Ptr CCapFloor' -> IO CapFloor
peekCapFloor Ptr CCapFloor'
res IO CapFloor -> (CapFloor -> IO CapFloor) -> IO CapFloor
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CapFloor
res' ->
  Ptr (Ptr CChar) -> IO ()
errorCheck  Ptr (Ptr CChar)
a3'IO () -> IO CapFloor -> IO CapFloor
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  CapFloor -> IO CapFloor
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CapFloor
res')

{-# LINE 36 "./QuantLib/Instrument/CapFloor.chs" #-}


-- |constructs a collar: a cap struck at the cap rates combined with a floor struck at the floor rates
collar :: (GenLeg l) -- ^floatingLeg
 -> (NonEmpty Double) -- ^capRates
 -> (NonEmpty Double) -- ^floorRates
 -> IO ((CapFloor))
collar a1 a2 a3 =
  withLeg a1 $ \a1' -> 
  withNonEmptyDoubleArray a2 $ \(a2'1, a2'2) -> 
  withNonEmptyDoubleArray a3 $ \(a3'1, a3'2) -> 
  preErrorCheck $ \a4' -> 
  collar'_ a1' a2'1  a2'2 a3'1  a3'2 a4' >>= \res ->
  peekCapFloor res >>= \res' ->
  errorCheck  a4'>>
  return (res')

{-# LINE 42 "./QuantLib/Instrument/CapFloor.chs" #-}


-- |constructs a floor: pays the excess of each exercise rate over the floating leg's rate, if positive
floor :: (GenLeg l) -- ^floatingLeg
 -> (NonEmpty Double) -- ^exerciseRates
 -> IO ((CapFloor))
floor a1 a2 =
  withLeg a1 $ \a1' -> 
  withNonEmptyDoubleArray a2 $ \(a2'1, a2'2) -> 
  preErrorCheck $ \a3' -> 
  floor'_ a1' a2'1  a2'2 a3' >>= \res ->
  peekCapFloor res >>= \res' ->
  errorCheck  a3'>>
  return (res')

{-# LINE 47 "./QuantLib/Instrument/CapFloor.chs" #-}


-- |returns the fair (at-the-money) rate for the cap/floor's underlying floating leg, discounted on the given curve
atmRate :: (CapFloor) -> (GenYieldTermStructure y) -- ^discountCurve
 -> IO ((Double))
atmRate a1 a2 =
  withGenInstrument a1 $ \a1' -> 
  withYieldTermStructure a2 $ \a2' -> 
  preErrorCheck $ \a3' -> 
  atmRate'_ a1' a2' a3' >>= \res ->
  let {res' = realToFrac res} in
  errorCheck  a3'>>
  return (res')

{-# LINE 51 "./QuantLib/Instrument/CapFloor.chs" #-}


-- |implied term volatility
impliedVolatility :: (CapFloor) -> (Double) -- ^price
 -> (GenYieldTermStructure y) -- ^disc
 -> (Double) -- ^guess
 -> (Double) -- ^accuracy
 -> (Word) -- ^maxEvaluations
 -> (Double) -- ^minVol
 -> (Double) -- ^maxVol
 -> (VolatilityType) -- ^type
 -> (Double) -- ^displacement
 -> IO ((Double))
impliedVolatility :: forall y.
CapFloor
-> Double
-> GenYieldTermStructure y
-> Double
-> Double
-> Word
-> Double
-> Double
-> VolatilityType
-> Double
-> IO Double
impliedVolatility CapFloor
a1 Double
a2 GenYieldTermStructure y
a3 Double
a4 Double
a5 Word
a6 Double
a7 Double
a8 VolatilityType
a9 Double
a10 =
  CapFloor -> (Ptr CCapFloor' -> IO Double) -> IO Double
forall i b. GenInstrument (ForeignPtr i) -> (Ptr i -> IO b) -> IO b
withGenInstrument CapFloor
a1 ((Ptr CCapFloor' -> IO Double) -> IO Double)
-> (Ptr CCapFloor' -> IO Double) -> IO Double
forall a b. (a -> b) -> a -> b
$ \Ptr CCapFloor'
a1' -> 
  let {a2' :: CDouble
a2' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a2} in 
  GenYieldTermStructure y
-> (Ptr CYieldTermStructure' -> IO Double) -> IO Double
forall y b.
GenYieldTermStructure y
-> (Ptr CYieldTermStructure' -> IO b) -> IO b
withYieldTermStructure GenYieldTermStructure y
a3 ((Ptr CYieldTermStructure' -> IO Double) -> IO Double)
-> (Ptr CYieldTermStructure' -> IO Double) -> IO Double
forall a b. (a -> b) -> a -> b
$ \Ptr CYieldTermStructure'
a3' -> 
  let {a4' :: CDouble
a4' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a4} in 
  let {a5' :: CDouble
a5' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a5} in 
  let {a6' :: CUInt
a6' = Word -> CUInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
a6} in 
  let {a7' :: CDouble
a7' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a7} in 
  let {a8' :: CDouble
a8' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a8} in 
  let {a9' :: CInt
a9' = (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> (VolatilityType -> Int) -> VolatilityType -> CInt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VolatilityType -> Int
forall a. Enum a => a -> Int
fromEnum) VolatilityType
a9} in 
  let {a10' :: CDouble
a10' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a10} in 
  (Ptr (Ptr CChar) -> IO Double) -> IO Double
forall a b. (Ptr (Ptr a) -> IO b) -> IO b
preErrorCheck ((Ptr (Ptr CChar) -> IO Double) -> IO Double)
-> (Ptr (Ptr CChar) -> IO Double) -> IO Double
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CChar)
a11' -> 
  Ptr CCapFloor'
-> CDouble
-> Ptr CYieldTermStructure'
-> CDouble
-> CDouble
-> CUInt
-> CDouble
-> CDouble
-> CInt
-> CDouble
-> Ptr (Ptr CChar)
-> IO CDouble
impliedVolatility'_ Ptr CCapFloor'
a1' CDouble
a2' Ptr CYieldTermStructure'
a3' CDouble
a4' CDouble
a5' CUInt
a6' CDouble
a7' CDouble
a8' CInt
a9' CDouble
a10' Ptr (Ptr CChar)
a11' IO CDouble -> (CDouble -> IO Double) -> IO Double
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CDouble
res ->
  let {res' :: Double
res' = CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
res} in
  Ptr (Ptr CChar) -> IO ()
errorCheck  Ptr (Ptr CChar)
a11'IO () -> IO Double -> IO Double
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  Double -> IO Double
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
res')

{-# LINE 63 "./QuantLib/Instrument/CapFloor.chs" #-}


-- |Returns the n-th optionlet as a new CapFloor with only one cash flow.
optionlet :: (CapFloor) -> (Word) -- ^n
 -> IO ((CapFloor))
optionlet a1 a2 =
  withGenInstrument a1 $ \a1' -> 
  let {a2' = fromIntegral a2} in 
  preErrorCheck $ \a3' -> 
  optionlet'_ a1' a2' a3' >>= \res ->
  peekCapFloor res >>= \res' ->
  errorCheck  a3'>>
  return (res')

{-# LINE 67 "./QuantLib/Instrument/CapFloor.chs" #-}


-- vim: set ff=unix ts=8 sts=2 sw=2 et:

foreign import ccall safe "QuantLib/Instrument/CapFloor.chs.h qlCap"
  cap'_ :: ((C2HSImp.Ptr (CLeg')) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CCapFloor')))))))

foreign import ccall safe "QuantLib/Instrument/CapFloor.chs.h qlCollar"
  collar'_ :: ((C2HSImp.Ptr (CLeg')) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CCapFloor')))))))))

foreign import ccall safe "QuantLib/Instrument/CapFloor.chs.h qlFloor"
  floor'_ :: ((C2HSImp.Ptr (CLeg')) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CCapFloor')))))))

foreign import ccall safe "QuantLib/Instrument/CapFloor.chs.h qlCapFloorAtmRate"
  atmRate'_ :: ((C2HSImp.Ptr (CCapFloor')) -> ((C2HSImp.Ptr (CYieldTermStructure')) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CDouble))))

foreign import ccall safe "QuantLib/Instrument/CapFloor.chs.h qlCapFloorImpliedVolatility"
  impliedVolatility'_ :: ((C2HSImp.Ptr (CCapFloor')) -> (C2HSImp.CDouble -> ((C2HSImp.Ptr (CYieldTermStructure')) -> (C2HSImp.CDouble -> (C2HSImp.CDouble -> (C2HSImp.CUInt -> (C2HSImp.CDouble -> (C2HSImp.CDouble -> (C2HSImp.CInt -> (C2HSImp.CDouble -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO C2HSImp.CDouble))))))))))))

foreign import ccall safe "QuantLib/Instrument/CapFloor.chs.h qlCapFloorOptionlet"
  optionlet'_ :: ((C2HSImp.Ptr (CCapFloor')) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CCapFloor'))))))