{- |
Copyright: (c) 2021 Ghais Issa
SPDX-License-Identifier: MIT
Maintainer: Ghais Issa <0x47@0x49.dev>

Haskell binding for Jaekel's "Let's be Rational" implied volatility calculation
-}

module LetsBeRational
       ( lbr
       ) where
import           Foreign.C.Types
import Data.Coerce (coerce)


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

-- | Calculate implied volatility for a European option using Let's Be Rational.
lbr :: Int   -- ^ 1 for CALL -1 for PUT.
  -> Double -- ^ Forward
  -> Double -- ^ Strike
  -> Double -- ^ Time to maturity
  -> Double -- ^ Premium
  -> Double -- ^ Implied vol.
lbr :: Int -> Double -> Double -> Double -> Double -> Double
lbr Int
cp Double
f Double
k Double
t Double
p = CDouble -> Double
coerce (CDouble -> Double) -> CDouble -> Double
forall a b. (a -> b) -> a -> b
$ CDouble -> CDouble -> CDouble -> CDouble -> CDouble -> CDouble
c_lbr (Double -> CDouble
coerce Double
p) (Double -> CDouble
coerce Double
f) (Double -> CDouble
coerce Double
k) (Double -> CDouble
coerce Double
t) (Double -> CDouble
coerce (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
cp::Double))