/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.instrument.index;
import org.apache.commons.lang.ObjectUtils;
import org.threeten.bp.Period;
import org.threeten.bp.ZonedDateTime;
import com.opengamma.analytics.financial.instrument.swap.SwapFixedONDefinition;
import com.opengamma.analytics.financial.schedule.ScheduleCalculator;
import com.opengamma.financial.convention.businessday.BusinessDayConvention;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.util.ArgumentChecker;
/**
* Generator (or template) for OIS.
*/
public class GeneratorSwapFixedON extends GeneratorInstrument<GeneratorAttributeIR> {
/**
* The ON index of the floating leg.
*/
private final IndexON _index;
/**
* The legs period of payments (both fixed and ON legs have the same payment frequency).
*/
private final Period _legsPeriod;
/**
* The fixed leg day count.
*/
private final DayCount _fixedLegDayCount;
/**
* The business day convention for the payments (used for both legs).
*/
private final BusinessDayConvention _businessDayConvention;
/**
* The flag indicating if the end-of-month rule is used (used for both legs).
*/
private final boolean _endOfMonth;
/**
* The spot lag in days between trade and settlement date (usually 2 or 0).
*/
private final int _spotLag;
/**
* The lag in days between the last ON fixing date and the coupon payment. Usually is the same as the _spotLag.
*/
private final int _paymentLag;
/**
* In case the the periods do not fit exactly between start and end date, is the remaining interval shorter (true) or longer (false) than the requested period.
*/
private final boolean _stubShort;
/**
* The dates in the schedule can be computed from the end date (true) or from the start date (false).
*/
private final boolean _fromEnd;
/**
* The holiday calendar associated with the overnight index.
*/
private final Calendar _calendar;
/**
* Constructor from all details. The stub is short and date constructed from the end.
* @param name The generator name.
* @param index The ON index of the floating leg.
* @param legsPeriod The legs period of payments (both fixed and ON legs have the same payment frequency).
* @param fixedLegDayCount The fixed leg day count.
* @param businessDayConvention The business day convention for the payments (used for both legs).
* @param endOfMonth The flag indicating if the end-of-month rule is used (used for both legs).
* @param spotLag The index spot lag in days between trade and settlement date (usually 2 or 0).
* @param calendar The calendar associated with the overnight index.
*/
public GeneratorSwapFixedON(final String name, final IndexON index, final Period legsPeriod, final DayCount fixedLegDayCount, final BusinessDayConvention businessDayConvention,
final boolean endOfMonth, final int spotLag, final Calendar calendar) {
super(name);
ArgumentChecker.notNull(legsPeriod, "Period");
ArgumentChecker.notNull(fixedLegDayCount, "Fixed leg day count");
ArgumentChecker.notNull(businessDayConvention, "Business day convention");
ArgumentChecker.notNull(index, "Index ON");
ArgumentChecker.isFalse(legsPeriod.isZero(), "legsPeriod must be non zero");
_index = index;
_legsPeriod = legsPeriod;
_fixedLegDayCount = fixedLegDayCount;
_businessDayConvention = businessDayConvention;
_endOfMonth = endOfMonth;
_spotLag = spotLag;
_paymentLag = spotLag;
_stubShort = true;
_fromEnd = true;
_calendar = calendar;
}
/**
* Constructor from all details. The stub is short and date constructed from the end.
* @param name The generator name.
* @param index The ON index of the floating leg.
* @param legsPeriod The legs period of payments (both fixed and ON legs have the same payment frequency).
* @param fixedLegDayCount The fixed leg day count.
* @param businessDayConvention The business day convention for the payments (used for both legs).
* @param endOfMonth The flag indicating if the end-of-month rule is used (used for both legs).
* @param spotLag The index spot lag in days between trade and settlement date (usually 2 or 0).
* @param paymentLag The lag in days between the last ON fixing date and the coupon payment.
* @param calendar The calendar associated with the overnight index.
*/
public GeneratorSwapFixedON(final String name, final IndexON index, final Period legsPeriod, final DayCount fixedLegDayCount, final BusinessDayConvention businessDayConvention,
final boolean endOfMonth, final int spotLag, final int paymentLag, final Calendar calendar) {
super(name);
ArgumentChecker.notNull(legsPeriod, "Period");
ArgumentChecker.notNull(fixedLegDayCount, "Fixed leg day count");
ArgumentChecker.notNull(businessDayConvention, "Business day convention");
ArgumentChecker.notNull(index, "Index ON");
ArgumentChecker.isFalse(legsPeriod.isZero(), "legsPeriod must be non zero");
_index = index;
_legsPeriod = legsPeriod;
_fixedLegDayCount = fixedLegDayCount;
_businessDayConvention = businessDayConvention;
_endOfMonth = endOfMonth;
_spotLag = spotLag;
_paymentLag = paymentLag;
_stubShort = true;
_fromEnd = true;
_calendar = calendar;
}
/**
* Gets the legs period of payments (both fixed and ON legs have the same payment frequency).
* @return The period.
*/
public Period getLegsPeriod() {
return _legsPeriod;
}
/**
* Gets the fixed leg day count.
* @return The day count.
*/
public DayCount getFixedLegDayCount() {
return _fixedLegDayCount;
}
/**
* Gets The business day convention for the payments (used for both legs).
* @return The business day convention.
*/
public BusinessDayConvention getBusinessDayConvention() {
return _businessDayConvention;
}
/**
* Gets the flag indicating if the end-of-month rule is used (used for both legs).
* @return The flag indicating if the end-of-month rule is used.
*/
public boolean isEndOfMonth() {
return _endOfMonth;
}
/**
* Gets the ON index of the floating leg.
* @return The ON index.
*/
public IndexON getIndex() {
return _index;
}
/**
* Gets the flag indicating if the remaining interval is shorter (true) or longer (false) than the requested period.
* @return The flag.
*/
public boolean isStubShort() {
return _stubShort;
}
/**
* Gets the flag indicating if dates in the schedule are be computed from the end date (true) or from the start date (false).
* @return The flag.
*/
public boolean isFromEnd() {
return _fromEnd;
}
/**
* Gets the spot lag in days between trade and settlement date (usually 2 or 0).
* @return The spot lag.
*/
public int getSpotLag() {
return _spotLag;
}
/**
* Gets the lag in days between the last ON fixing date and the coupon payment.
* @return The payment lag.
*/
public int getPaymentLag() {
return _paymentLag;
}
/**
* Gets the calendar associated to the OIS index.
* @return The calendar.
*/
public Calendar getOvernightCalendar() {
return _calendar;
}
/**
* {@inheritDoc}
* The effective date is date+_spotLag. The end of fixing period is effective date+tenor.
*/
@Override
public SwapFixedONDefinition generateInstrument(final ZonedDateTime date, final double rate, final double notional, final GeneratorAttributeIR attribute) {
ArgumentChecker.notNull(date, "Reference date");
ArgumentChecker.notNull(attribute, "Attributes");
final ZonedDateTime spot = ScheduleCalculator.getAdjustedDate(date, _spotLag, _calendar);
final ZonedDateTime startDate = ScheduleCalculator.getAdjustedDate(spot, attribute.getStartPeriod(), _businessDayConvention, _calendar, _endOfMonth);
return SwapFixedONDefinition.from(startDate, attribute.getEndPeriod(), notional, this, rate, true);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + _businessDayConvention.hashCode();
result = prime * result + (_endOfMonth ? 1231 : 1237);
result = prime * result + _fixedLegDayCount.hashCode();
result = prime * result + (_fromEnd ? 1231 : 1237);
result = prime * result + ((_index == null) ? 0 : _index.hashCode());
result = prime * result + _legsPeriod.hashCode();
result = prime * result + _paymentLag;
result = prime * result + _spotLag;
result = prime * result + (_stubShort ? 1231 : 1237);
result = prime * result + _calendar.hashCode();
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final GeneratorSwapFixedON other = (GeneratorSwapFixedON) obj;
if (!ObjectUtils.equals(_businessDayConvention, other._businessDayConvention)) {
return false;
}
if (_endOfMonth != other._endOfMonth) {
return false;
}
if (!ObjectUtils.equals(_fixedLegDayCount, other._fixedLegDayCount)) {
return false;
}
if (_fromEnd != other._fromEnd) {
return false;
}
if (_index == null) {
if (other._index != null) {
return false;
}
} else if (!_index.equals(other._index)) {
return false;
}
if (!ObjectUtils.equals(_legsPeriod, other._legsPeriod)) {
return false;
}
if (_paymentLag != other._paymentLag) {
return false;
}
if (_spotLag != other._spotLag) {
return false;
}
if (_stubShort != other._stubShort) {
return false;
}
if (!ObjectUtils.equals(_calendar, other._calendar)) {
return false;
}
return true;
}
}