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


{-# LINE 1 "./QuantLib/Instrument/InflationCapFloor.chs" #-}
module QuantLib.Instrument.InflationCapFloor
  (
    -- * Types
    YoYInflationCapFloor
  , CPICapFloor

    -- * Constructors
  , yoyInflationCap
  , yoyInflationCollar
  , yoyInflationFloor
  , optionlet
  , cpiCapFloor

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


import QuantLib.Internal
import QuantLib.Internal.Type
import QuantLib.Internal.Common
import Data.List.NonEmpty(NonEmpty)








{-# LINE 28 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


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


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


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


{-# LINE 32 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


{-# LINE 33 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


-- |Constructs a YoY-inflation cap: pays the excess of the YoY leg's rate over each exercise
-- rate, if positive. Unlike a nominal cap, the first optionlet is live (YoY inflation sets in
-- arrears, so there is no reason to omit it -- see upstream's own note on
-- 'YoYInflationCapFloor').
yoyInflationCap :: (GenLeg l) -- ^yoyLeg
 -> (NonEmpty Double) -- ^exerciseRates
 -> IO ((YoYInflationCapFloor))
yoyInflationCap :: forall l. GenLeg l -> NonEmpty Double -> IO YoYInflationCapFloor
yoyInflationCap GenLeg l
a1 NonEmpty Double
a2 =
  GenLeg l
-> (Ptr CLeg' -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall l b. GenLeg l -> (Ptr CLeg' -> IO b) -> IO b
withLeg GenLeg l
a1 ((Ptr CLeg' -> IO YoYInflationCapFloor) -> IO YoYInflationCapFloor)
-> (Ptr CLeg' -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr CLeg'
a1' -> 
  NonEmpty Double
-> ((CUInt, Ptr CDouble) -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall b. NonEmpty Double -> ((CUInt, Ptr CDouble) -> IO b) -> IO b
withNonEmptyDoubleArray NonEmpty Double
a2 (((CUInt, Ptr CDouble) -> IO YoYInflationCapFloor)
 -> IO YoYInflationCapFloor)
-> ((CUInt, Ptr CDouble) -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall a b. (a -> b) -> a -> b
$ \(CUInt
a2'1, Ptr CDouble
a2'2) -> 
  (Ptr (Ptr CChar) -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall a b. (Ptr (Ptr a) -> IO b) -> IO b
preErrorCheck ((Ptr (Ptr CChar) -> IO YoYInflationCapFloor)
 -> IO YoYInflationCapFloor)
-> (Ptr (Ptr CChar) -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CChar)
a3' -> 
  Ptr CLeg'
-> CUInt
-> Ptr CDouble
-> Ptr (Ptr CChar)
-> IO (Ptr CYoYInflationCapFloor')
yoyInflationCap'_ Ptr CLeg'
a1' CUInt
a2'1  Ptr CDouble
a2'2 Ptr (Ptr CChar)
a3' IO (Ptr CYoYInflationCapFloor')
-> (Ptr CYoYInflationCapFloor' -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Ptr CYoYInflationCapFloor'
res ->
  Ptr CYoYInflationCapFloor' -> IO YoYInflationCapFloor
peekYoYInflationCapFloor Ptr CYoYInflationCapFloor'
res IO YoYInflationCapFloor
-> (YoYInflationCapFloor -> IO YoYInflationCapFloor)
-> IO YoYInflationCapFloor
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \YoYInflationCapFloor
res' ->
  Ptr (Ptr CChar) -> IO ()
errorCheck  Ptr (Ptr CChar)
a3'IO () -> IO YoYInflationCapFloor -> IO YoYInflationCapFloor
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  YoYInflationCapFloor -> IO YoYInflationCapFloor
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (YoYInflationCapFloor
res')

{-# LINE 41 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


-- |Constructs a YoY-inflation collar: a cap struck at the cap rates combined with a floor
-- struck at the floor rates.
yoyInflationCollar :: (GenLeg l) -- ^yoyLeg
 -> (NonEmpty Double) -- ^capRates
 -> (NonEmpty Double) -- ^floorRates
 -> IO ((YoYInflationCapFloor))
yoyInflationCollar a1 a2 a3 =
  withLeg a1 $ \a1' -> 
  withNonEmptyDoubleArray a2 $ \(a2'1, a2'2) -> 
  withNonEmptyDoubleArray a3 $ \(a3'1, a3'2) -> 
  preErrorCheck $ \a4' -> 
  yoyInflationCollar'_ a1' a2'1  a2'2 a3'1  a3'2 a4' >>= \res ->
  peekYoYInflationCapFloor res >>= \res' ->
  errorCheck  a4'>>
  return (res')

{-# LINE 48 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


-- |Constructs a YoY-inflation floor: pays the excess of each exercise rate over the YoY leg's
-- rate, if positive.
yoyInflationFloor :: (GenLeg l) -- ^yoyLeg
 -> (NonEmpty Double) -- ^exerciseRates
 -> IO ((YoYInflationCapFloor))
yoyInflationFloor a1 a2 =
  withLeg a1 $ \a1' -> 
  withNonEmptyDoubleArray a2 $ \(a2'1, a2'2) -> 
  preErrorCheck $ \a3' -> 
  yoyInflationFloor'_ a1' a2'1  a2'2 a3' >>= \res ->
  peekYoYInflationCapFloor res >>= \res' ->
  errorCheck  a3'>>
  return (res')

{-# LINE 54 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


-- |The fair (at-the-money) rate for the cap\/floor's underlying YoY leg, discounted on the
-- given curve.
atmRate :: (YoYInflationCapFloor) -> (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 60 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


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

{-# LINE 65 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


-- |A CPI cap or floor: a single cumulative option on cumulative inflation up to maturity
-- (@CPI(T)\/CPI(0)@), not a strip of optionlets like 'YoYInflationCapFloor' -- similar in shape
-- to a ZCIIS option. No implied-volatility inspector: pricing goes purely through
-- 'QuantLib.PricingEngine.interpolatingCpiCapFloorEngine' off a market price surface, there is
-- no vol-driven engine for it in QL 1.43.
cpiCapFloor :: (OptionType) -> (Double) -- ^nominal
 -> (Day) -- ^startDate
 -> (Double) -- ^baseCPI
 -> (Day) -- ^maturity
 -> (Calendar) -- ^fixCalendar
 -> (BusinessDayConvention) -- ^fixConvention
 -> (Calendar) -- ^payCalendar
 -> (BusinessDayConvention) -- ^payConvention
 -> (Double) -- ^strike
 -> (ZeroInflationIndex) -> ((Word,TimeUnit)) -- ^observationLag
 -> (CPIInterpolationType) -- ^observationInterpolation
 -> IO ((CPICapFloor))
cpiCapFloor :: OptionType
-> Double
-> Day
-> Double
-> Day
-> Calendar
-> BusinessDayConvention
-> Calendar
-> BusinessDayConvention
-> Double
-> ZeroInflationIndex
-> (Word, TimeUnit)
-> CPIInterpolationType
-> IO CPICapFloor
cpiCapFloor OptionType
a1 Double
a2 Day
a3 Double
a4 Day
a5 Calendar
a6 BusinessDayConvention
a7 Calendar
a8 BusinessDayConvention
a9 Double
a10 ZeroInflationIndex
a11 (Word, TimeUnit)
a12 CPIInterpolationType
a13 =
  let {a1' :: CInt
a1' = OptionType -> CInt
forall a b. (Enum a, Integral b) => a -> b
fromEnumC OptionType
a1} in 
  let {a2' :: CDouble
a2' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a2} in 
  Day -> (CInt -> IO CPICapFloor) -> IO CPICapFloor
forall a. Day -> (CInt -> IO a) -> IO a
withDay Day
a3 ((CInt -> IO CPICapFloor) -> IO CPICapFloor)
-> (CInt -> IO CPICapFloor) -> IO CPICapFloor
forall a b. (a -> b) -> a -> b
$ \CInt
a3' -> 
  let {a4' :: CDouble
a4' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a4} in 
  Day -> (CInt -> IO CPICapFloor) -> IO CPICapFloor
forall a. Day -> (CInt -> IO a) -> IO a
withDay Day
a5 ((CInt -> IO CPICapFloor) -> IO CPICapFloor)
-> (CInt -> IO CPICapFloor) -> IO CPICapFloor
forall a b. (a -> b) -> a -> b
$ \CInt
a5' -> 
  Calendar -> (Ptr CCalendar -> IO CPICapFloor) -> IO CPICapFloor
forall b. Calendar -> (Ptr CCalendar -> IO b) -> IO b
withCalendar Calendar
a6 ((Ptr CCalendar -> IO CPICapFloor) -> IO CPICapFloor)
-> (Ptr CCalendar -> IO CPICapFloor) -> IO CPICapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr CCalendar
a6' -> 
  let {a7' :: CInt
a7' = BusinessDayConvention -> CInt
forall a b. (Enum a, Integral b) => a -> b
fromEnumC BusinessDayConvention
a7} in 
  Calendar -> (Ptr CCalendar -> IO CPICapFloor) -> IO CPICapFloor
forall b. Calendar -> (Ptr CCalendar -> IO b) -> IO b
withCalendar Calendar
a8 ((Ptr CCalendar -> IO CPICapFloor) -> IO CPICapFloor)
-> (Ptr CCalendar -> IO CPICapFloor) -> IO CPICapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr CCalendar
a8' -> 
  let {a9' :: CInt
a9' = BusinessDayConvention -> CInt
forall a b. (Enum a, Integral b) => a -> b
fromEnumC BusinessDayConvention
a9} in 
  let {a10' :: CDouble
a10' = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
a10} in 
  ZeroInflationIndex
-> (Ptr CZeroInflationIndex' -> IO CPICapFloor) -> IO CPICapFloor
forall zidx b.
GenZeroInflationIndex zidx
-> (Ptr CZeroInflationIndex' -> IO b) -> IO b
withZeroInflationIndex ZeroInflationIndex
a11 ((Ptr CZeroInflationIndex' -> IO CPICapFloor) -> IO CPICapFloor)
-> (Ptr CZeroInflationIndex' -> IO CPICapFloor) -> IO CPICapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr CZeroInflationIndex'
a11' -> 
  let {(CInt
a12'1, CInt
a12'2) = (Word, TimeUnit) -> (CInt, CInt)
forall a b c.
(Enum a, Integral b, Integral c) =>
(b, a) -> (CInt, c)
fromEnumQuantity (Word, TimeUnit)
a12} in 
  let {a13' :: CInt
a13' = CPIInterpolationType -> CInt
forall a b. (Enum a, Integral b) => a -> b
fromEnumC CPIInterpolationType
a13} in 
  (Ptr (Ptr CChar) -> IO CPICapFloor) -> IO CPICapFloor
forall a b. (Ptr (Ptr a) -> IO b) -> IO b
preErrorCheck ((Ptr (Ptr CChar) -> IO CPICapFloor) -> IO CPICapFloor)
-> (Ptr (Ptr CChar) -> IO CPICapFloor) -> IO CPICapFloor
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CChar)
a14' -> 
  CInt
-> CDouble
-> CInt
-> CDouble
-> CInt
-> Ptr CCalendar
-> CInt
-> Ptr CCalendar
-> CInt
-> CDouble
-> Ptr CZeroInflationIndex'
-> CInt
-> CInt
-> CInt
-> Ptr (Ptr CChar)
-> IO (Ptr CCPICapFloor')
cpiCapFloor'_ CInt
a1' CDouble
a2' CInt
a3' CDouble
a4' CInt
a5' Ptr CCalendar
a6' CInt
a7' Ptr CCalendar
a8' CInt
a9' CDouble
a10' Ptr CZeroInflationIndex'
a11' CInt
a12'1  CInt
a12'2 CInt
a13' Ptr (Ptr CChar)
a14' IO (Ptr CCPICapFloor')
-> (Ptr CCPICapFloor' -> IO CPICapFloor) -> IO CPICapFloor
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Ptr CCPICapFloor'
res ->
  Ptr CCPICapFloor' -> IO CPICapFloor
peekCPICapFloor Ptr CCPICapFloor'
res IO CPICapFloor -> (CPICapFloor -> IO CPICapFloor) -> IO CPICapFloor
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CPICapFloor
res' ->
  Ptr (Ptr CChar) -> IO ()
errorCheck  Ptr (Ptr CChar)
a14'IO () -> IO CPICapFloor -> IO CPICapFloor
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  CPICapFloor -> IO CPICapFloor
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CPICapFloor
res')

{-# LINE 85 "./QuantLib/Instrument/InflationCapFloor.chs" #-}


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

foreign import ccall safe "QuantLib/Instrument/InflationCapFloor.chs.h qlYoYInflationCap"
  yoyInflationCap'_ :: ((C2HSImp.Ptr (CLeg')) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CYoYInflationCapFloor')))))))

foreign import ccall safe "QuantLib/Instrument/InflationCapFloor.chs.h qlYoYInflationCollar"
  yoyInflationCollar'_ :: ((C2HSImp.Ptr (CLeg')) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CYoYInflationCapFloor')))))))))

foreign import ccall safe "QuantLib/Instrument/InflationCapFloor.chs.h qlYoYInflationFloor"
  yoyInflationFloor'_ :: ((C2HSImp.Ptr (CLeg')) -> (C2HSImp.CUInt -> ((C2HSImp.Ptr C2HSImp.CDouble) -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CYoYInflationCapFloor')))))))

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

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

foreign import ccall safe "QuantLib/Instrument/InflationCapFloor.chs.h qlCPICapFloor"
  cpiCapFloor'_ :: (C2HSImp.CInt -> (C2HSImp.CDouble -> (C2HSImp.CInt -> (C2HSImp.CDouble -> (C2HSImp.CInt -> ((C2HSImp.Ptr (CCalendar)) -> (C2HSImp.CInt -> ((C2HSImp.Ptr (CCalendar)) -> (C2HSImp.CInt -> (C2HSImp.CDouble -> ((C2HSImp.Ptr (CZeroInflationIndex')) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO (C2HSImp.Ptr (CCPICapFloor'))))))))))))))))))