raft-0.3.2.2: src/Data/Function/Finance.hs
-----------------------------------------------------------------------------
--
-- Module : Data.Function.Finance
-- Copyright : (c) 2014-16 Brian W Bush
-- License : MIT
--
-- Maintainer : Brian W Bush <consult@brianwbush.info>
-- Stability : Stable
-- Portability : Portable
--
-- | Financial functions.
--
-----------------------------------------------------------------------------
{-# LANGUAGE Safe #-}
module Data.Function.Finance (
-- * Financial functions
netPresentValue
, internalRateOfReturn
, capitalRecoveryFactor
) where
import Math.Roots (bracket)
import Math.Roots.Bisection (findRoot)
-- | Compute the net present value of a series of values.
netPresentValue :: (Fractional a, Num a) =>
a -- ^ The rate per period.
-> [a] -- ^ The values at the end of the periods.
-> a -- ^ The net present value.
netPresentValue _ [] = 0
netPresentValue rate (x : xs) = (x + netPresentValue rate xs) / (1 + rate)
-- | Compute the internal rate of return for a series of values.
internalRateOfReturn :: (Fractional a, Num a, Ord a) =>
[a] -- ^ The values at the end of the periods.
-> Either String a -- ^ The rate per period that yields a zero net present value.
internalRateOfReturn x
| null x = return 0
| minimum x * maximum x > 0 = Left "Both negative and positive values must be present."
| otherwise =
do
let
f = flip netPresentValue x
xs <- bracket 100 f (0, 10)
findRoot 100 1e-8 f xs
-- | Compute a capital recovery factor.
capitalRecoveryFactor :: (Floating a, Real b) =>
a -- ^ The interest rate.
-> b -- ^ The lifetime of the capital.
-> a -- ^ The capital recovery factor.
capitalRecoveryFactor interestRate lifetime =
interestRate
* (1 + interestRate)**lifetime'
/ ((1 + interestRate)**lifetime' - 1)
where
lifetime' = fromRational $ toRational lifetime