/*
Copyright (C) 2008 Srinivas Hasti
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.indexes;
import org.jquantlib.QL;
import org.jquantlib.Settings;
import org.jquantlib.currencies.Currency;
import org.jquantlib.daycounters.DayCounter;
import org.jquantlib.lang.exceptions.LibraryException;
import org.jquantlib.math.Constants;
import org.jquantlib.quotes.Handle;
import org.jquantlib.termstructures.YieldTermStructure;
import org.jquantlib.time.Calendar;
import org.jquantlib.time.Date;
import org.jquantlib.time.Period;
import org.jquantlib.time.TimeUnit;
import org.jquantlib.util.Observer;
/**
*
* @author Srinivas Hasti
* @author Zahid Hussain
*
*/
// TODO: code review :: please verify against QL/C++ code
// TODO: code review :: license, class comments, comments for access modifiers, comments for @Override
public abstract class InterestRateIndex extends Index implements Observer {
protected String familyName;
protected Period tenor;
protected /*Natural*/ int fixingDays;
protected Calendar fixingCalendar;
protected Currency currency;
protected DayCounter dayCounter;
public InterestRateIndex(final String familyName,
final Period tenor,
final int fixingDays,
final Currency currency,
final Calendar fixingCalendar,
final DayCounter dayCounter) {
this.familyName = familyName;
this.tenor = tenor;
this.fixingDays = fixingDays;
this.fixingCalendar = fixingCalendar;
this.currency = currency;
this.dayCounter = dayCounter;
this.tenor.normalize();
new Settings().evaluationDate().addObserver(this);
IndexManager.getInstance().notifier(name()).addObserver(this);
}
@Override
public String name() {
final StringBuilder builder = new StringBuilder(familyName);
if (tenor.equals(new Period(1,TimeUnit.Days))) {
if (fixingDays == 0) {
builder.append("ON");
} else if (fixingDays == 1) {
builder.append("TN");
} else if (fixingDays == 2) {
builder.append("SN");
} else {
builder.append(tenor.getShortFormat());
}
} else {
builder.append(tenor.getShortFormat());
}
builder.append(' ').append(dayCounter.name());
return builder.toString();
}
@Override
public Calendar fixingCalendar() {
return fixingCalendar;
}
@Override
public boolean isValidFixingDate(final Date fixingDate) {
return fixingCalendar.isBusinessDay(fixingDate);
}
public String familyName() {
return familyName;
}
public Period tenor() {
return tenor;
}
public int fixingDays() {
return fixingDays;
}
public Currency currency() {
return currency;
}
public DayCounter dayCounter() {
return dayCounter;
}
//
// protected abstract methods
//
protected abstract double forecastFixing(Date fixingDate);
//
// public abstract methods
//
public abstract Handle termStructure();
public abstract Date maturityDate(Date valueDate);
//
// public methods
//
@Override
public double fixing(final Date fixingDate,
final boolean forecastTodaysFixing) {
QL.require(isValidFixingDate(fixingDate) , "Fixing date " + fixingDate.toString() + " is not valid"); // QA:[RG]::verified
final Date today = new Settings().evaluationDate();
final boolean enforceTodaysHistoricFixings = new Settings().isEnforcesTodaysHistoricFixings();
if (fixingDate.lt(today) || (fixingDate.equals(today) && enforceTodaysHistoricFixings && !forecastTodaysFixing)) {
// must have been fixed
double /*Rate*/ pastFixing =
IndexManager.getInstance().getHistory(name()).get(fixingDate);
QL.require(pastFixing != Constants.NULL_REAL,
"Missing " + name() + " fixing for " + fixingDate);
return pastFixing;
}
if ((fixingDate.equals(today)) && !forecastTodaysFixing) {
// might have been fixed
try {
double /*Rate*/ pastFixing =
IndexManager.getInstance().getHistory(name()).get(fixingDate);
if (pastFixing != Constants.NULL_REAL)
return pastFixing;
else
; // fall through and forecast
} catch (final Exception e) {
; // fall through and forecast
}
}
// forecast
return forecastFixing(fixingDate);
}
@Override
public double fixing(final Date fixingDate) {
return fixing(fixingDate, false);
}
public Date fixingDate(final Date valueDate) {
final Date fixingDate = fixingCalendar().advance(valueDate, fixingDays, TimeUnit.Days);
QL.ensure(isValidFixingDate(fixingDate) , "fixing date " + fixingDate + " is not valid");
return fixingDate;
}
public Date valueDate(final Date fixingDate) {
QL.require(isValidFixingDate(fixingDate) , "Fixing date is not valid"); // TODO: message
return fixingCalendar().advance(fixingDate, fixingDays, TimeUnit.Days);
}
//
// implements Observer
//
//XXX:registerWith
// @Override
// public void registerWith(final Observable o) {
// o.addObserver(this);
// }
//
// @Override
// public void unregisterWith(final Observable o) {
// o.deleteObserver(this);
// }
@Override
//XXX::OBS public void update(final Observable o, final Object arg) {
public void update() {
//XXX::OBS notifyObservers(arg);
notifyObservers();
}
}
Ads help maintain this website.