/*
Copyright (C) 2007 Richard Gomes
This source code is release under the BSD License.
This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/
JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license. You should have received a
copy of the license along with this program; if not, please email
. The license is also available online at
.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
*/
package org.jquantlib.daycounters;
import org.jquantlib.lang.annotation.QualityAssurance;
import org.jquantlib.lang.annotation.QualityAssurance.Quality;
import org.jquantlib.lang.annotation.QualityAssurance.Version;
import org.jquantlib.lang.exceptions.LibraryException;
import org.jquantlib.time.Date;
/**
* 30/360 day count convention
*
* The 30/360 day count can be calculated according to US, European, or Italian
* conventions.
*
* US (NASD) convention: if the starting date is the 31st of a month, it becomes
* equal to the 30th of the same month. If the ending date is the 31st of a
* month and the starting date is earlier than the 30th of a month, the ending
* date becomes equal to the 1st of the next month, otherwise the ending date
* becomes equal to the 30th of the same month. Also known as "30/360",
* "360/360", or "Bond Basis"
*
* European convention: starting dates or ending dates that occur on the 31st of
* a month become equal to the 30th of the same month. Also known as "30E/360",
* or "Eurobond Basis"
*
* Italian convention: starting dates or ending dates that occur on February and
* are grater than 27 become equal to 30 for computational sake.
*
* @see Day count convention
*
* @author Srinivas Hasti
* @author Richard Gomes
*/
@QualityAssurance(quality=Quality.Q4_UNIT, version=Version.V097, reviewers="Richard Gomes")
public class Thirty360 extends DayCounter {
/**
* 30/360 Calendar Conventions
*/
public enum Convention {
USA, BondBasis,
European, EurobondBasis,
Italian;
}
//
// public constructors
//
public Thirty360() {
this(Convention.BondBasis);
}
public Thirty360(final Thirty360.Convention c) {
switch (c) {
case USA:
case BondBasis:
super.impl = new Impl_US();
break;
case European:
case EurobondBasis:
super.impl = new Impl_EU();
break;
case Italian:
super.impl = new Impl_IT();
break;
default:
throw new LibraryException("unknown 30/360 convention"); // TODO: message
}
}
//
// private inner classes
//
/**
* Implementation of Thirty360 class abstraction according to US convention
*
* @see Bridge pattern
*
* @author Richard Gomes
*/
private final class Impl_US extends DayCounter.Impl {
@Override
public final String name() /* @ReadOnly */{
return "30/360 (Bond Basis)";
}
@Override
protected long dayCount(final Date d1, final Date d2) /* @ReadOnly */ {
final int dd1 = d1.dayOfMonth();
int dd2 = d2.dayOfMonth();
final int mm1 = d1.month().value();
int mm2 = d2.month().value();
final int yy1 = d1.year();
final int yy2 = d2.year();
if (dd2 == 31 && dd1 < 30) { dd2 = 1; mm2++; }
return 360*(yy2-yy1) + 30*(mm2-mm1-1) + Math.max(0, 30-dd1) + Math.min(30, dd2);
}
@Override
public /*@Time*/ final double yearFraction(
final Date dateStart, final Date dateEnd,
final Date refPeriodStart, final Date refPeriodEnd) /* @ReadOnly */{
return /*@Time*/ dayCount(dateStart, dateEnd) / 360.0;
}
}
/**
* Implementation of Thirty360 class abstraction according to European convention
*
* @see Bridge pattern
*
* @author Richard Gomes
*/
private final class Impl_EU extends DayCounter.Impl {
@Override
public final String name() /* @ReadOnly */{
return "30E/360 (Eurobond Basis)";
}
@Override
public /*@Time*/ final double yearFraction(
final Date dateStart, final Date dateEnd,
final Date refPeriodStart, final Date refPeriodEnd) /* @ReadOnly */{
return /*@Time*/ dayCount(dateStart, dateEnd) / 360.0;
}
@Override
protected long dayCount(final Date d1, final Date d2) /* @ReadOnly */ {
final int dd1 = d1.dayOfMonth();
final int dd2 = d2.dayOfMonth();
final int mm1 = d1.month().value();
final int mm2 = d2.month().value();
final int yy1 = d1.year();
final int yy2 = d2.year();
return 360*(yy2-yy1) + 30*(mm2-mm1-1) + Math.max(0, 30-dd1) + Math.min(30, dd2);
}
}
/**
* Implementation of Thirty360 class abstraction according to Italian convention
*
* @see Bridge pattern
*
* @author Richard Gomes
*/
private final class Impl_IT extends DayCounter.Impl {
@Override
protected final String name() /* @ReadOnly */{
return "30/360 (Italian)";
}
@Override
public /*@Time*/ final double yearFraction(
final Date dateStart, final Date dateEnd,
final Date refPeriodStart, final Date refPeriodEnd) /* @ReadOnly */{
return /*@Time*/ dayCount(dateStart, dateEnd) / 360.0;
}
@Override
protected long dayCount(final Date d1, final Date d2) /* @ReadOnly */ {
int dd1 = d1.dayOfMonth();
int dd2 = d2.dayOfMonth();
final int mm1 = d1.month().value();
final int mm2 = d2.month().value();
final int yy1 = d1.year();
final int yy2 = d2.year();
if (mm1 == 2 && dd1 > 27) {
dd1 = 30;
}
if (mm2 == 2 && dd2 > 27) {
dd2 = 30;
}
return 360*(yy2-yy1) + 30*(mm2-mm1-1) + Math.max(0, 30-dd1) + Math.min(30, dd2);
}
}
}
Ads help maintain this website.