/*
Copyright (C) 2009 John Nichol
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
<jquant-devel@lists.sourceforge.net>. The license is also available online at
<http://www.jquantlib.org/index.php/LICENSE.TXT>.
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.
*/
/*
Copyright (C) 2007 Ferdinando Ametrano
Copyright (C) 2007 Chiara Fornarola
Copyright (C) 2005, 2006, 2008 StatPro Italia srl
This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/
QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev@lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.
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.
*/
package org.jquantlib.indexes.ibor;
import org.jquantlib.QL;
import org.jquantlib.currencies.Currency;
import org.jquantlib.currencies.Europe.EURCurrency;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.indexes.IborIndex;
import org.jquantlib.quotes.Handle;
import org.jquantlib.termstructures.AbstractYieldTermStructure;
import org.jquantlib.termstructures.YieldTermStructure;
import org.jquantlib.time.BusinessDayConvention;
import org.jquantlib.time.Calendar;
import org.jquantlib.time.Date;
import org.jquantlib.time.Period;
import org.jquantlib.time.TimeUnit;
import org.jquantlib.time.calendars.JointCalendar;
import org.jquantlib.time.calendars.UnitedKingdom;
import org.jquantlib.time.calendars.JointCalendar.JointCalendarRule;
/**
* base class for all BBA LIBOR indexes but the EUR, O/N, and S/N ones
*
* LIBOR fixed by BBA.
*
* @see <a href="http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1414">http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1414</a>
*/
public class Libor extends IborIndex {
//
// private final fields
//
private final Calendar financialCenterCalendar_;
private final Calendar jointCalendar_;
//
// public constructors
//
public Libor(
final String familyName,
final Period tenor,
final int settlementDays,
final Currency currency,
final Calendar financialCenterCalendar,
final DayCounter dayCounter) {
this(familyName, tenor, settlementDays,
currency, financialCenterCalendar, dayCounter,
new Handle<YieldTermStructure>(
new AbstractYieldTermStructure() {
@Override
protected double discountImpl(final double t) {
throw new UnsupportedOperationException();
}
@Override
public Date maxDate() {
throw new UnsupportedOperationException();
}
}
));
}
public Libor(
final String familyName,
final Period tenor,
final int settlementDays,
final Currency currency,
final Calendar financialCenterCalendar,
final DayCounter dayCounter,
final Handle<YieldTermStructure> h) {
// http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 :
// UnitedKingdom::Exchange is the fixing calendar for
// a) all currencies but EUR
// b) all indexes but o/n and s/n
super(familyName, tenor, settlementDays,
currency, new UnitedKingdom(UnitedKingdom.Market.Exchange),
liborConvention(tenor), liborEOM(tenor), dayCounter, h);
financialCenterCalendar_ = financialCenterCalendar;
jointCalendar_ = new JointCalendar(new UnitedKingdom(UnitedKingdom.Market.Exchange),
financialCenterCalendar_,
JointCalendarRule.JoinHolidays);
QL.require(this.tenor().units()!= TimeUnit.Days,
"for daily tenors (" + this.tenor() +
") dedicated DailyTenor constructor must be used");
QL.require(! currency.equals(new EURCurrency()),
"for EUR Libor dedicated EurLibor constructor must be used");
}
//
// overrides InterestRateIndex
//
/**
* Date calculations
*
* @see <a href="http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412">http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412</a>
*/
@Override
public Date valueDate(final Date fixingDate) {
QL.require(isValidFixingDate(fixingDate),
"Fixing date " + fixingDate + " is not valid");
// http://www.bba.org.uk/bba/jsp/polopoly.jsp?d=225&a=1412 :
// For all currencies other than EUR and GBP the period between
// Fixing Date and Value Date will be two London business days
// after the Fixing Date, or if that day is not both a London
// business day and a business day in the principal financial centre
// of the currency concerned, the next following day which is a
// business day in both centres shall be the Value Date.
final Date d = fixingCalendar().advance(fixingDate, fixingDays(), TimeUnit.Days);
return jointCalendar_.adjust(d);
}
@Override
public Date maturityDate(final Date valueDate) {
// Where a deposit is made on the final business day of a
// particular calendar month, the maturity of the deposit shall
// be on the final business day of the month in which it matures
// (not the corresponding date in the month of maturity). Or in
// other words, in line with market convention, BBA LIBOR rates
// are dealt on an end-end basis. For instance a one month
// deposit for value 28th February would mature on 31st March,
// not the 28th of March.
return jointCalendar_.advance(valueDate, tenor(), businessDayConvention(),
endOfMonth());
}
//TODO: code review :: InterestRateIndex#clone returns IborIndex whilst this class returns Handle<IborIndex>
//
// @Override
// public Handle<IborIndex> clone(final Handle<YieldTermStructure> h) {
// return new Handle<IborIndex>(
// new Libor(familyName(),
// tenor(),
// fixingDays(),
// currency(),
// financialCenterCalendar_,
// dayCounter(),
// h));
//
// }
//
// private static methods
//
private static BusinessDayConvention liborConvention(final Period p) {
switch (p.units()) {
case Days:
case Weeks:
return BusinessDayConvention.Following;
case Months:
case Years:
return BusinessDayConvention.ModifiedFollowing;
default:
QL.error("invalid time units");
}
// Keep the compiler happy, can not reach here
return null;
}
private static boolean liborEOM(final Period p) {
switch (p.units()) {
case Days:
case Weeks:
return false;
case Months:
case Years:
return true;
default:
QL.error("invalid time units");
}
// Keep the compiler happy, can not reach here
return false;
}
}