---------------------------------------------------------
--
-- Module : Parameters
-- Copyright : Bartosz Wójcik (2010)
-- License : BSD3
--
-- Maintainer : bartek@sudety.it
-- Stability : Unstable
-- Portability : portable
--
-- Parameters hidden in the reader monad
---------------------------------------------------------
module Haslo.Parameters (IPPMonad
,runWithIPP
,InstalmentPlanParam (..)
,paramDT
,paramMT
,paramYT
,paramDR
,paramMR
,paramYR
)
where
import Control.Monad.Reader
import Haslo.ErrorHandling
import Haslo.CalcCalendar
type ParamMonad = ReaderT Param IPPMonad
runWithParam param loan = runReaderT loan param
data Param = Param
{ipp :: InstalmentPlanParam
,fin :: FinancingParameters
}
deriving Show
-- | Parameters for loan construction. They have been separated, because they
-- usually do not change often, if at all.
data InstalmentPlanParam = IPP
{freq :: Freq
,rounding :: RoundingType
}
deriving Show
-- | Reader monad for IPP -- to run loan with parameters.
type IPPMonad = ReaderT InstalmentPlanParam ValidMonad
-- | Convenience function.
runWithIPP :: InstalmentPlanParam -> IPPMonad a -> ValidMonad a
runWithIPP param loan = runReaderT loan param
absParamMonthlyTrunc = IPP Monthly Truncated
absParamDailyTrunc = IPP Daily Truncated
absParamYearlyTrunc = IPP Yearly Truncated
-- | Rule of 1st instalment date as function of last financing tranche's date.
data FstInstRule = FstInstDays Int -- ^ Not less than given number of days after.
| FstInstFullFreqAfter -- ^ at least one full 'instFreq' period after, less than two periods.
deriving (Eq,Show)
instance Enum FstInstRule where
toEnum 0 = FstInstFullFreqAfter
toEnum n = FstInstDays n
fromEnum FstInstFullFreqAfter = 0
fromEnum (FstInstDays n) = n
-- | Rule of calculation and maturity of interest for first period of the loan
-- from 1st tranche date till one instalment period before first instalment.
data FstIntRule =
-- | Interest is calculated daily.
-- Mature on each instalment day.
FstIntDaily
-- | Interest is calculated from tranche date till next instalment day, if next instalment
-- day is before first instalment date.
-- Interest matures on each instalment day.
| FstIntTillNextDue
-- | Interest is calculated from tranche date till first instalment date.
-- Interest matures on first instalment date.
| FstIntTill1stInst
-- | Interest is calculated from tranche date till first instalment date
-- which amount > 0. All instalments = 0 before have to be removed. Date of
-- first >0 instalment doesn't change though.
-- Interest matures on date of first >0 instalment.
| FstIntTill1stInstGT0
-- | Proprietary solution.
-- Interest is calculated and matures like for @FstIntTill1stInstGT0@, the difference
-- is that common nominal interest rate is re-caluclated using real number of days of
-- between tranche date and first instalment date. In this solution only one tranche is
-- alowed.
| FstIntCtlm
deriving (Eq,Show,Enum)
-- | Rule defining what to do with late interest coming out of grace period.
data LateIntOfGracePeriodRule =
-- | Late interest will be due on first instalment - will increase its amount.
LateIntFstInst
-- | Late interest will be due on first significant instalment - will increase its amount.
| LateIntFstSignInst
-- | Late interest will be due on last instalment - will increase its amount.
| LateIntLastInst
deriving (Eq,Show)
-- | Collection of parameters customizing financing.
data FinancingParameters = FP {
instFreq :: Freq -- ^ Frequency of instalment must be >= than @intFreq@
, intFreq :: Freq -- ^ Frequency of interest
, fin1stInstRule :: FstInstRule
, fin1stIntRule :: FstIntRule
, finCalendar :: CalendarType -- ^ calendar type
, lateIntRule :: LateIntOfGracePeriodRule
}
deriving (Eq,Show)
paramDT = IPP Daily Truncated
-- | Monthly Truncated
paramMT :: InstalmentPlanParam
paramMT = IPP Monthly Truncated
paramYT = IPP Yearly Truncated
paramDR = IPP Daily Truncated
paramMR = IPP Monthly Rounded
-- | Yearly Rounded
paramYR :: InstalmentPlanParam
paramYR = IPP Yearly Rounded