* * This method is not identical to ACT/ACT ISDA. For ACT/ACT ISDA use {@link net.finmath.time.daycount.DayCountConvention_ACT_ACT_ISDA}. * *
* ** In addition the method has the defect, that it is not additive (if you consider small intervals). For example * YEARFRAC(30.12.2011, 04.01.2012, 1) is not equal to YEARFRAC(30.12.2011, 01.01.2012, 1) + YEARFRAC(01.01.2012, 04.01.2012, 1). *
* * @author Christian Fries */ public class DayCountConvention_ACT_ACT_YEARFRAC extends DayCountConvention_ACT { /** * Create an ACT/ACT YEARFRAC daycount convention. */ public DayCountConvention_ACT_ACT_YEARFRAC() { } /* (non-Javadoc) * @see net.finmath.time.daycount.DayCountConventionInterface#getDaycountFraction(java.time.LocalDate, java.time.LocalDate) */ @Override public double getDaycountFraction(LocalDate startDate, LocalDate endDate) { if(startDate.isAfter(endDate)) return -getDaycountFraction(endDate,startDate); /* * Determine the denominator of act/act. */ double denominator; LocalDate startDatePlusOneYear = startDate.plusYears(1); if(endDate.isAfter(startDatePlusOneYear)) { /* * The following method applies, if the interval spans more than one year: * fraction = actual number of days / average number of days per year. */ LocalDate startDateYearStart = startDate.withDayOfYear(1); LocalDate endDateYearEnd = endDate.withDayOfYear(endDate.lengthOfYear()).plusDays(1); double spannedYears = endDate.getYear() - startDate.getYear() + 1; denominator = getDaycount(startDateYearStart, endDateYearEnd) / spannedYears; } else { boolean isStartLeapYear = startDate.isLeapYear(); boolean isEndLeapYear = endDate.isLeapYear(); /* * If the start and end span less or equal one year: * If start and end fall in a leap year, use ACT/366. */ if(isStartLeapYear && isEndLeapYear) { denominator = 366.0; } else /* * If the start and end span less or equal one year: * If either falls in a leap year and Feb 29th of that leap year lies in between start and end (or is equal to start or end), use ACT/366. */ if(isStartLeapYear || isEndLeapYear) { // Get February 29th of the respective leap year LocalDate leapYearsFeb29th = isStartLeapYear ? LocalDate.of(startDate.getYear(), Month.FEBRUARY, 29) : LocalDate.of(endDate.getYear(), Month.FEBRUARY, 29); // Check position of February 29th if(startDate.compareTo(leapYearsFeb29th) <= 0 && endDate.compareTo(leapYearsFeb29th) >= 0) { denominator = 366.0; } else { denominator = 365.0; } } else { /* * If the start and end span less or equal one year: * If none of the above applies, use denominator = ACT/365. */ denominator = 365.0; } } double daycountFraction = getDaycount(startDate, endDate) / denominator; return daycountFraction; } @Override public String toString() { return "DayCountConvention_ACT_ACT_YEARFRAC"; } }