module QuantLib.Time.Date ( module QuantLib.Time.Date ) where import Data.Time import Data.Time.Calendar.WeekDate {- | Business Day conventions - These conventions specify the algorithm used to adjust a date in case it is not a valid business day. -} data BusinessDayConvention = Following | ModifiedFollowing | Preceding | ModifiedPreceding | Unadjusted deriving (Show, Eq, Enum) -- | Week days data WeekDay = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday deriving (Show, Eq, Enum) -- | Date type Date = Day -- | Defines a holidays for given calendar. Corresponds to calendar class in QuantLib class Holiday m where isHoliday :: m->(Integer, Int, Int)->Bool isBusinessDay :: m->Date->Bool isBusinessDay m d = not (isHoliday m $ toGregorian d) hBusinessDayBetween :: m->(Date, Date)->Int hBusinessDayBetween m (fd, td) = foldl countDays 0 listOfDates where countDays counter x = counter + fromEnum (isBusinessDay m x) listOfDates = getDaysBetween (fd, td) -- | Gets a week day getWeekDay :: Date->WeekDay getWeekDay d = toEnum (weekDay - 1) where (_, _, weekDay) = toWeekDate d -- | Generate a list of all dates inbetween getDaysBetween :: (Day, Day) -> [Day] getDaysBetween (fd, td) = reverse $ generator fd [] where generator date x | date < td = generator nextDate (nextDate : x) | otherwise = x where nextDate = addDays 1 date -- | Checks if the day is a weekend, i.e. Saturday or Sunday isWeekEnd :: Date->Bool isWeekEnd d = (weekday == Saturday) || (weekday == Sunday) where weekday = getWeekDay d -- | Gets the next working day getNextBusinessDay :: Holiday a => a->Date->Date getNextBusinessDay m d | isBusinessDay m nextDay = nextDay | otherwise = getNextBusinessDay m nextDay where nextDay = addDays 1 d