net.finmath.time.daycount.DayCountConvention_ACT_ACT_AFB Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of finmath-lib Show documentation
Show all versions of finmath-lib Show documentation
finmath lib is a Mathematical Finance Library in Java.
It provides algorithms and methodologies related to mathematical finance.
/*
* (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
*
* Created on 07.09.2013
*/
package net.finmath.time.daycount;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.Month;
/**
* Implementation of ACT/ACT AFB.
*
* Calculates the day count by calculating the actual number of days between startDate and endDate.
*
* A fractional day is rounded to the approximately nearest day.
*
* The day count fraction is calculated using ACT_ACT_AFB convention. The algorithm works as follows:
*
* -
* If the interval from startDate to endDate spans more than a whole year, then
* the number of whole years is subtracted from the endDate year and added (as an integer) to the day count fraction.
* Here, subtraction of whole year(s) means:
*
* -
* If the end date is on a February 29th and the resulting day is not in a leap year,
* it will be set to February 28th of that year (i.e., we preserve "end of month").
*
* -
* If the end date is on a February 28th of a non-leap year and the resulting day is in a leap year,
* it will be on February 29th of that year (i.e., we preserve "end of month").
*
* -
* Otherwise the resulting day has the same day of month and the same month as the end year.
*
*
*
* -
* For the remaining interval the actual number of days is divided by a denominator,
* where the denominator is 366.0 if February 29th is in between start and end and 365.0 otherwise.
*
*
*
* @author Christian Fries
* @version 1.0
*/
public class DayCountConvention_ACT_ACT_AFB extends DayCountConvention_ACT implements Serializable {
private static final long serialVersionUID = 3362135261620939045L;
/**
* Create an ACT/ACT FBA daycount convention.
*/
public DayCountConvention_ACT_ACT_AFB() {
}
/* (non-Javadoc)
* @see net.finmath.time.daycount.DayCountConvention#getDaycountFraction(java.time.LocalDate, java.time.LocalDate)
*/
@Override
public double getDaycountFraction(final LocalDate startDate, final LocalDate endDate) {
if(startDate.isAfter(endDate)) {
return -getDaycountFraction(endDate,startDate);
}
/*
* Find the "fractionalPeriodEnd", i.e. subtract whole years from endDate.
*/
LocalDate fractionalPeriodEnd = endDate.plusYears(startDate.getYear() - endDate.getYear());
// preserving 'end-of-month' if endDate is 28/Feb of non-leap-year or 29/Feb of non-leap-year.
if (endDate.getDayOfMonth() == endDate.lengthOfMonth()) {
fractionalPeriodEnd = fractionalPeriodEnd.withDayOfMonth(fractionalPeriodEnd.lengthOfMonth());
}
if (fractionalPeriodEnd.isBefore(startDate)) {
fractionalPeriodEnd.plusYears(1);
// preserving 'end-of-month' if endDate is 28/Feb of non-leap-year or 29/Feb of non-leap-year, again after changing the years.
if (endDate.getDayOfMonth() == endDate.lengthOfMonth()) {
fractionalPeriodEnd = fractionalPeriodEnd.withDayOfMonth(fractionalPeriodEnd.lengthOfMonth());
}
}
double daycountFraction = endDate.getYear() - fractionalPeriodEnd.getYear();
double fractionPeriodDenominator = 365.0;
if(fractionalPeriodEnd.isLeapYear()) {
final LocalDate feb29th = LocalDate.of(fractionalPeriodEnd.getYear(), Month.FEBRUARY, 29);
if(startDate.compareTo(feb29th) <= 0 && fractionalPeriodEnd.compareTo(feb29th) > 0) {
fractionPeriodDenominator = 366.0;
}
}
else if(startDate.isLeapYear()) {
final LocalDate feb29th = LocalDate.of(startDate.getYear(), Month.FEBRUARY, 29);
if(startDate.compareTo(feb29th) <= 0 && fractionalPeriodEnd.compareTo(feb29th) > 0) {
fractionPeriodDenominator = 366.0;
}
}
daycountFraction += getDaycount(startDate, fractionalPeriodEnd) / fractionPeriodDenominator;
return daycountFraction;
}
@Override
public String toString() {
return "DayCountConvention_ACT_ACT_AFB";
}
}