The daycount module allows you to calculate the duration between two dates according to the calculation convention of your choice. The user is encouraged to see the yearFraction proc for more details.
Types
bdDayCountConvention = enum dccThirtyA360 = "30A/360", ## Also known as "30/360 Bond basis" or "30/360 ISDA" dccThirtyU360 = "30U/360", ## Also known as "30US/360", "30/360 US" or "30/360 SIA" dccThirtyE360 = "30E/360", ## Also known as "30/360 European", "Eurobond basis", ## "Special German", "30/360 ISMA" or "30/360 ICMA" dccThirtyEPlus360 = "30E+/360", ## No other name known dccThirtyG360 = "30/360 German", ## Also known as "30E/360 ISDA" dccActual360 = "Actual/360", ## Also known as "French" dccActual365F = "Actual/365 Fixed", ## Also known as "English" dccActual366 = "Actual/366", ## No other name known dccActual364 = "Actual/364", ## No other name known dccActual36525 = "Actual/365.25", ## No other name known dccActual365L = "Actual/365L", ## Also known as "ISMA-Year" dccActual365A = "Actual/365A", ## No other name known dccNL365 = "NL/365", ## Also known as "Actual/365 No leap year", "NL365" dccActualActual = "Actual/Actual", ## Also known as "Actual/Actual ISDA" dccActualActualAFB = "Actual/Actual AFB", ## No other name known dccBusinessDays252 = "BusinessDays/252", ## Also known as "BUS/252" or "BD/252" dccOneOne = "1/1" ## Also known as "One/One"
-
Description of each element of the bdDayCountConvention enumeration.
- bdDayCountConvention.dccThirtyA360
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / 30/360 ISDA day count method.
- bdDayCountConvention.dccThirtyU360
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / 30/360 US day count method.
- bdDayCountConvention.dccThirtyE360
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / 30E/360 day count method.
- bdDayCountConvention.dccThirtyEPlus360
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / 30E+/360 day count method.
- bdDayCountConvention.dccThirtyG360
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / 30/360 German day count method.
- bdDayCountConvention.dccActual360
- The number of days between the start and end dates is divided by 360 (each full year is therefore assumed to have 360 ​​days).
- bdDayCountConvention.dccActual365F
- The number of days between the start and end dates is divided by 365 (each full year is therefore assumed to have 365 ​​days).
- bdDayCountConvention.dccActual366
- The number of days between the start and end dates is divided by 366 (each full year is therefore assumed to have 366 ​​days).
- bdDayCountConvention.dccActual364
- The number of days between the start and end dates is divided by 364 (each full year is therefore assumed to have 364 ​​days).
- bdDayCountConvention.dccActual36525
- The number of days between the start and end dates is divided by 365.25 (each full year is therefore assumed to have 365.25 ​​days).
- bdDayCountConvention.dccActual365L
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / Act/365L day count method.
- bdDayCountConvention.dccActual365A
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / Act/365A day count method.
- bdDayCountConvention.dccNL365
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / NL/365 day count method.
- bdDayCountConvention.dccActualActual
- http://deltaquants.com/day-count-conventions / Table 2: DCF calculations / Act/Act day count method.
- bdDayCountConvention.dccActualActualAFB
- bdDayCountConvention.dccBusinessDays252
- The number of business days between the start and end dates is divided by 252 (each full year is therefore assumed to have 252 business ​​days).
- bdDayCountConvention.dccOneOne
- bdDayCountConvention.dccThirtyA360
Procs
proc yearFraction(startDate, endDate: DateTime; dcc: bdDayCountConvention; calendar: bdCalendar = nil; dateInterval: BoundedRealInterval = BoundedRightOpen): float64 {. ...raises: [Exception], tags: [RootEffect], forbids: [].}
-
Calculates the duration between the starting date <startDate> and the end date <endDate>, according to the day count convention <dcc>.
Notes:
- If endDate < startDate the result is equal to -yearFraction(startDate = endDate, endDate = startDate, dcc, calendar, dateInterval).
- calendar and dateInterval parameters are only use when dcc == dccBusinessDays252.
- The dateInterval parameter allows you to include/exclude <fromDate> and <toDate> for business day counting.
Main references:
- http://deltaquants.com/day-count-conventions
- https://en.wikipedia.org/wiki/Day_count_convention
- https://quant.opengamma.io/Interest-Rate-Instruments-and-Market-Conventions.pdf (pp. 5-7)
Example:
# Time interval 1: from 31 January 2008 to 28 February 2008 (leap year) # -------------------------------------------------------------------------- let startDate1 = dateTime(2008, mJan, 31) let endDate1 = dateTime(2008, mFeb, 28) doAssert: yearFraction(startDate1, endDate1, dccActual360) == 28.0/360.0 doAssert: yearFraction(startDate1, endDate1, dccThirtyA360) == 28.0/360.0 doAssert: yearFraction(startDate1, endDate1, dccThirtyU360) == 28.0/360.0 doAssert: yearFraction(startDate1, endDate1, dccThirtyE360) == 28.0/360.0 doAssert: yearFraction(startDate1, endDate1, dccThirtyEPlus360) == 28.0/360.0 doAssert: yearFraction(startDate1, endDate1, dccThirtyG360) == 28.0/360.0 # Day count is 28.0 for all considered day count conventions. # Time interval 2: from 28 February 2007 to 31 March 2007 (non-leap year) # ---------------------------------------------------------------------------- let startDate2 = dateTime(2007, mFeb, 28) let endDate2 = dateTime(2007, mMar, 31) doAssert: yearFraction(startDate2, endDate2, dccActual360) == 31.0/360.0 doAssert: yearFraction(startDate2, endDate2, dccThirtyA360) == 33.0/360.0 doAssert: yearFraction(startDate2, endDate2, dccThirtyU360) == 30.0/360.0 doAssert: yearFraction(startDate2, endDate2, dccThirtyE360) == 32.0/360.0 doAssert: yearFraction(startDate2, endDate2, dccThirtyEPlus360) == 33.0/360.0 doAssert: yearFraction(startDate2, endDate2, dccThirtyG360) == 30.0/360.0 # - Depending on the considered day count convention, # the day count varies from 30.0 to 33.0 (4 values). # # - The actual number of days is 31.0. But depending on # how the convention manages the end of the month, and # the end of the month of February, we can also obtain # 30.0, 32.0 or 33.0 days. # The following 4 numerical examples are taken from # http://deltaquants.com/day-count-conventions # Time interval 3: from 28 December 2007 to 28 February 2008 # -------------------------------------------------------------- let startDate3 = dateTime(2007, mDec, 28) let endDate3 = dateTime(2008, mFeb, 28) doAssert: yearFraction(startDate3, endDate3, dccThirtyA360) == 60.0/360.0 doAssert: yearFraction(startDate3, endDate3, dccThirtyU360) == 60.0/360.0 doAssert: yearFraction(startDate3, endDate3, dccThirtyE360) == 60.0/360.0 doAssert: yearFraction(startDate3, endDate3, dccThirtyEPlus360) == 60.0/360.0 doAssert: yearFraction(startDate3, endDate3, dccThirtyG360) == 60.0/360.0 doAssert: yearFraction(startDate3, endDate3, dccActual360) == 62.0/360.0 doAssert: yearFraction(startDate3, endDate3, dccActual365F) == 62.0/365.0 doAssert: yearFraction(startDate3, endDate3, dccActual365L) == 62.0/366.0 doAssert: yearFraction(startDate3, endDate3, dccActual365A) == 62.0/365.0 doAssert: yearFraction(startDate3, endDate3, dccNL365) == 62.0/365.0 doAssert: yearFraction(startDate3, endDate3, dccActualActual) == 4.0/365.0+58.0/366.0 # Time interval 4: from 28 December 2007 to 29 February 2008 # -------------------------------------------------------------- let startDate4 = dateTime(2007, mDec, 28) let endDate4 = dateTime(2008, mFeb, 29) doAssert: yearFraction(startDate4, endDate4, dccThirtyA360) == 61.0/360.0 doAssert: yearFraction(startDate4, endDate4, dccThirtyU360) == 61.0/360.0 doAssert: yearFraction(startDate4, endDate4, dccThirtyE360) == 61.0/360.0 doAssert: yearFraction(startDate4, endDate4, dccThirtyEPlus360) == 61.0/360.0 doAssert: yearFraction(startDate4, endDate4, dccThirtyG360) == 62.0/360.0 doAssert: yearFraction(startDate4, endDate4, dccActual360) == 63.0/360.0 doAssert: yearFraction(startDate4, endDate4, dccActual365F) == 63.0/365.0 doAssert: yearFraction(startDate4, endDate4, dccActual365L) == 63.0/366.0 doAssert: yearFraction(startDate4, endDate4, dccActual365A) == 63.0/366.0 doAssert: yearFraction(startDate4, endDate4, dccNL365) == 62.0/365.0 doAssert: yearFraction(startDate4, endDate4, dccActualActual) == 4.0/365.0+59.0/366.0 # Time interval 5: from 31 October 2007 to 30 November 2008 # -------------------------------------------------------------- let startDate5 = dateTime(2007, mOct, 31) let endDate5 = dateTime(2008, mNov, 30) doAssert: yearFraction(startDate5, endDate5, dccThirtyA360) == 390.0/360.0 doAssert: yearFraction(startDate5, endDate5, dccThirtyU360) == 390.0/360.0 doAssert: yearFraction(startDate5, endDate5, dccThirtyE360) == 390.0/360.0 doAssert: yearFraction(startDate5, endDate5, dccThirtyEPlus360) == 390.0/360.0 doAssert: yearFraction(startDate5, endDate5, dccThirtyG360) == 390.0/360.0 doAssert: yearFraction(startDate5, endDate5, dccActual360) == 396.0/360.0 doAssert: yearFraction(startDate5, endDate5, dccActual365F) == 396.0/365.0 doAssert: yearFraction(startDate5, endDate5, dccActual365L) == 396.0/366.0 doAssert: yearFraction(startDate5, endDate5, dccActual365A) == 396.0/366.0 doAssert: yearFraction(startDate5, endDate5, dccNL365) == 395.0/365.0 doAssert: yearFraction(startDate5, endDate5, dccActualActual) == 62.0/365.0+334.0/366.0 # Time interval 6: from 1 February 2008 to 31 May 2009 # -------------------------------------------------------- let startDate6 = dateTime(2008, mFeb, 1) let endDate6 = dateTime(2009, mMay, 31) doAssert: yearFraction(startDate6, endDate6, dccThirtyA360) == 480.0/360.0 doAssert: yearFraction(startDate6, endDate6, dccThirtyU360) == 480.0/360.0 doAssert: yearFraction(startDate6, endDate6, dccThirtyE360) == 479.0/360.0 doAssert: yearFraction(startDate6, endDate6, dccThirtyEPlus360) == 480.0/360.0 doAssert: yearFraction(startDate6, endDate6, dccThirtyG360) == 479.0/360.0 doAssert: yearFraction(startDate6, endDate6, dccActual360) == 485.0/360.0 doAssert: yearFraction(startDate6, endDate6, dccActual365F) == 485.0/365.0 doAssert: yearFraction(startDate6, endDate6, dccActual365L) == 485.0/365.0 doAssert: yearFraction(startDate6, endDate6, dccActual365A) == 485.0/366.0 doAssert: yearFraction(startDate6, endDate6, dccNL365) == 484.0/365.0 doAssert: yearFraction(startDate6, endDate6, dccActualActual) == 335.0/366.0+150.0/365.0 # "Actual/Actual AFB" day count method # ------------------------------------ # (https://en.wikipedia.org/wiki/Day_count_convention#Actual/Actual_AFB) let startDate7 = dateTime(2004, mFeb, 28) let endDate7 = dateTime(2008, mFeb, 27) let endDate7bis = dateTime(2008, mFeb, 28) let endDate7ter = dateTime(2008, mFeb, 29) let startDate8 = dateTime(1994, mFeb, 10) let endDate8 = dateTime(1997, mJun, 30) doAssert: yearFraction(startDate7, endDate7, dccActualActualAFB) == 3.0+365.0/366.0 doAssert: yearFraction(startDate7, endDate7bis, dccActualActualAFB) == 4.0 doAssert: yearFraction(startDate7, endDate7ter, dccActualActualAFB) == 4.0+1.0/366.0 doAssert: yearFraction(startDate8, endDate8, dccActualActualAFB) == 3.0+140.0/365.0
Source Edit
Exports
-
klndrStaticHolidays, klndrTARGET, isholidayEngland, bdays, $, holidayUSMemorialDay, isweekendTARGETCalendar, usInaugurationDay, isholidayUSBondMrkt, holidayWhitSunday, boxingDay, holidayUSNYSEElectionDay, klndrNoHolidayOrWeekend, observedHolidays, USVeteransDay, newCalendarGBEngWls, holidayTargetLabourDay, NewYearsDay, holidayGBSctOrangemensDay, holidayGBEarlyMay, bdcFollowing, bdBusinessCalendar, holidayGBSpring, orangemensDay, newCalendarUSFederalGovt, klndrGBEngWls, isweekend, bdHoliday, stPatricksDay, USJuneteenthIndependenceDay, holidayUSWashingtonBirthday, christmasDay, klndrUSFederalGovt, LabourDay, isholiday, holidayUSChristmasDay, klndrGBNir, holidayUSLaborDay, bdcEndOfMonth, holidayTargetDecember31, holidayGBChristmasDay, BoxingDay, holidayAscension, isholidayTARGETCalendar, december31, ChristmasDay, isholiday, bdCalendar, isholiday, holidayEasterNCo, bdcPredecing, holiday, holidayWhitMonday, OrangemensDay, isbday, holidayUSVeteransDay, isholidayUSNYSE, holidayUSIndependenceDay, StPatricksDay, holidayGoodFriday, klndrUSNYSE, holidayEasterSunday, holidayUSThanksgivingDay, holidayGBSctStAndrewsDay, holidayGBSctJanuary2, observedHolidays, newYearsDay, isholidayNorthIreland, holidayGBNirStPatricksDay, nextMondayIfWeekend, holidayUSColumbusDay, holidayEasterMonday, newCalendarGBSct, observedHolidays, bdcModifFollowingFornight, holidayUSNYSENewYearsDay, newCalendarGBNir, holidayUSNewYearsDay, StAndrewsDay, addbdays, USIndependenceDay, bdBusinessDayConvention, isholidayScotland, bdcModifFollowing, newCalendarUSBondMrkt, newCalendarUSNYSE, stAndrewsDay, holidayGBEngNirWlsSummer, December31, info, holidayTargetChristmasDay, newCalendarWeekendsOnly, holidayGBBoxingDay, nearestWeekday, nextbday, klndrWeekendsOnly, holidayTargetNewYearsDay, labourDay, bday, newCalendarTARGET, newCalendar, holidayGBNewYearsDay, holidayUSInaugurationDay, holidayTargetBoxingDay, holidayUSJuneteenthIndependenceDay, newCalendarStaticHolidays, holidayUSMartinLutherKingBirthday, nextWeekday, klndrGBSct, nextMondayIfSunday, holidayGBSctSummer, newCalendarNoHolidayOrWeekend, isholidayUSFederalGovt, klndrUSBondMrkt