{-# LANGUAGE ForeignFunctionInterface #-}
module Q.Options.ImpliedVol.LetsBeRational (
  euImpliedVol
) where

import           Data.Coerce                    (coerce)
import           Data.Number.Erf
import           Foreign.C.Types
import           Numeric.IEEE                   (epsilon, maxFinite, minNormal)
import           Q.Options.BlackScholes
import           Q.Options
import           Q.Types
import           Statistics.Distribution        (cumulative, density, quantile)
import           Statistics.Distribution.Normal (standard)

foreign import ccall
   "lets_be_rational.h implied_volatility_from_a_transformed_rational_guess" c_lbr ::
     CDouble -> CDouble  -> CDouble -> CDouble  -> CDouble  -> CDouble

euImpliedVol :: OptionType -> Forward -> Strike -> YearFrac -> Rate -> Premium -> Vol
euImpliedVol :: OptionType
-> Forward -> Strike -> YearFrac -> Rate -> Premium -> Vol
euImpliedVol OptionType
cp (Forward Double
f) (Strike Double
k) (YearFrac Double
t) (Rate Double
r) (Premium Double
p) =
  CDouble -> Vol
coerce (CDouble -> Vol) -> CDouble -> Vol
forall a b. (a -> b) -> a -> b
$ CDouble -> CDouble -> CDouble -> CDouble -> CDouble -> CDouble
c_lbr (Double -> CDouble
CDouble Double
p) (Double -> CDouble
CDouble Double
f) (Double -> CDouble
CDouble Double
k) (Double -> CDouble
CDouble Double
t) (Double -> CDouble
CDouble (OptionType -> Double
forall p. Num p => OptionType -> p
cpi OptionType
cp))