/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.instrument.bond;
import org.apache.commons.lang.ObjectUtils;
import com.opengamma.analytics.financial.instrument.InstrumentDefinition;
import com.opengamma.analytics.financial.instrument.annuity.AnnuityDefinition;
import com.opengamma.analytics.financial.instrument.payment.CouponDefinition;
import com.opengamma.analytics.financial.instrument.payment.PaymentDefinition;
import com.opengamma.analytics.financial.interestrate.bond.definition.BondSecurity;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Coupon;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment;
import com.opengamma.analytics.financial.legalentity.LegalEntity;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.Currency;
/**
* Describes a generic single currency bond issue.
* @param <N> The notional type (usually FixedPayment or CouponInflationZeroCoupon).
* @param <C> The coupon type.
*/
public abstract class BondSecurityDefinition<N extends PaymentDefinition, C extends CouponDefinition> implements
InstrumentDefinition<BondSecurity<? extends Payment, ? extends Coupon>> {
/**
* The notional payments. For bullet bond, it is restricted to a single payment.
*/
private final AnnuityDefinition<N> _nominal;
/**
* The bond coupons. The coupons notional should be in line with the bond nominal.
*/
private final AnnuityDefinition<C> _coupon;
/**
* Number of days before the payment of the coupon is detached from the bond (and paid to the then owner).
*/
private final int _exCouponDays;
/**
* Standard number of days between trade date and trade settlement. Used for clean price and yield computation.
*/
private final int _settlementDays;
/**
* The calendar used to compute the standard settlement date.
*/
private final Calendar _calendar;
/**
* The bond issuer name.
*/
private final String _issuerName;
/**
* The issuer.
*/
private final LegalEntity _issuer;
/**
* The bond repo type.
*/
private final String _repoType;
/**
* Bond constructor from all the bond details. The repo type is set to an empty string and the legal entity
* only contains the issuer name.
* @param nominal The notional payments. For bullet bond, it is restricted to a single payment.
* @param coupon The bond coupons. The coupons notional and currency should be in line with the bond nominal.
* @param exCouponDays Number of days before the payment of the coupon is detached from the bond (and paid to the then owner).
* @param settlementDays Standard number of days between trade date and trade settlement. Used for clean price and yield computation.
* @param calendar The calendar used to compute the standard settlement date.
* @param issuer The issuer name.
*/
public BondSecurityDefinition(final AnnuityDefinition<N> nominal, final AnnuityDefinition<C> coupon, final int exCouponDays, final int settlementDays,
final Calendar calendar, final String issuer) {
this(nominal, coupon, exCouponDays, settlementDays, calendar, new LegalEntity(null, issuer, null, null, null), "");
}
/**
* Bond constructor from all the bond details. The repo type is set to an empty string.
* @param nominal The notional payments. For bullet bond, it is restricted to a single payment.
* @param coupon The bond coupons. The coupons notional and currency should be in line with the bond nominal.
* @param exCouponDays Number of days before the payment of the coupon is detached from the bond (and paid to the then owner).
* @param settlementDays Standard number of days between trade date and trade settlement. Used for clean price and yield computation.
* @param calendar The calendar used to compute the standard settlement date.
* @param issuer The issuer name.
*/
public BondSecurityDefinition(final AnnuityDefinition<N> nominal, final AnnuityDefinition<C> coupon, final int exCouponDays, final int settlementDays,
final Calendar calendar, final LegalEntity issuer) {
this(nominal, coupon, exCouponDays, settlementDays, calendar, issuer, "");
}
/**
* Bond constructor from all the bond details. The legal entity only contains the issuer name.
* @param nominal The notional payments. For bullet bond, it is restricted to a single payment.
* @param coupon The bond coupons. The coupons notional and currency should be in line with the bond nominal.
* @param exCouponDays Number of days before the payment of the coupon is detached from the bond (and paid to the then owner).
* @param settlementDays Standard number of days between trade date and trade settlement. Used for clean price and yield computation.
* @param calendar The calendar used to compute the standard settlement date.
* @param issuer The issuer name.
* @param repoType The repo type name.
*/
public BondSecurityDefinition(final AnnuityDefinition<N> nominal, final AnnuityDefinition<C> coupon, final int exCouponDays, final int settlementDays,
final Calendar calendar, final String issuer, final String repoType) {
this(nominal, coupon, exCouponDays, settlementDays, calendar, new LegalEntity(null, issuer, null, null, null), repoType);
}
/**
* Bond constructor from all the bond details.
* @param nominal The notional payments. For bullet bond, it is restricted to a single payment.
* @param coupon The bond coupons. The coupons notional and currency should be in line with the bond nominal.
* @param exCouponDays Number of days before the payment of the coupon is detached from the bond (and paid to the then owner).
* @param settlementDays Standard number of days between trade date and trade settlement. Used for clean price and yield computation.
* @param calendar The calendar used to compute the standard settlement date.
* @param issuer The issuer name.
* @param repoType The repo type name.
*/
public BondSecurityDefinition(final AnnuityDefinition<N> nominal, final AnnuityDefinition<C> coupon, final int exCouponDays, final int settlementDays,
final Calendar calendar, final LegalEntity issuer, final String repoType) {
ArgumentChecker.notNull(nominal, "Nominal");
ArgumentChecker.notNull(coupon, "Coupons");
ArgumentChecker.isTrue(nominal.getCurrency().equals(coupon.getCurrency()), "Currency of nominal {} and coupons {} should be the same", nominal.getCurrency(),
coupon.getCurrency());
ArgumentChecker.isTrue(nominal.getNthPayment(nominal.getNumberOfPayments() - 1).getReferenceAmount() > 0, "Notional should be positive");
ArgumentChecker.isTrue(coupon.getNthPayment(coupon.getNumberOfPayments() - 1).getReferenceAmount() > 0, "Coupon notional should be positive");
ArgumentChecker.notNull(issuer, "issuer");
ArgumentChecker.notNull(repoType, "repo type");
_nominal = nominal;
_coupon = coupon;
// TODO: check that the coupon and nominal correspond in term of remaining notional (in the case of amortization)
_exCouponDays = exCouponDays;
_settlementDays = settlementDays;
_calendar = calendar;
_issuerName = issuer.getShortName();
_issuer = issuer;
_repoType = repoType;
}
/**
* Gets the nominal.
* @return The nominal.
*/
public AnnuityDefinition<N> getNominal() {
return _nominal;
}
/**
* Gets the coupons.
* @return The coupons.
*/
public AnnuityDefinition<C> getCoupons() {
return _coupon;
}
/**
* Gets the number of ex-coupon days (business days).
* @return The ex-coupon days.
*/
public int getExCouponDays() {
return _exCouponDays;
}
/**
* Gets the number of days to standard settlement.
* @return The days to settlement.
*/
public int getSettlementDays() {
return _settlementDays;
}
/**
* Gets the issuer name.
* @return The issuer name.
*/
public String getIssuer() {
return _issuerName;
}
/**
* Gets the issuer.
* @return The issuer
*/
public LegalEntity getIssuerEntity() {
return _issuer;
}
/**
* Gets the _repoType name.
* @return the _repoType
*/
public String getRepoType() {
return _repoType;
}
/**
* Gets the currency.
* @return The bond currency.
*/
public Currency getCurrency() {
return _nominal.getCurrency();
}
/**
* Gets the calendar used to compute the standard settlement date.
* @return The calendar.
*/
public Calendar getCalendar() {
return _calendar;
}
@Override
public String toString() {
String result = "Bond : \n";
result += "Notional: " + _nominal.toString();
result += "\nCoupons: \n" + _coupon.toString() + "\n";
return result;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + _coupon.hashCode();
result = prime * result + _exCouponDays;
result = prime * result + _issuer.hashCode();
result = prime * result + _nominal.hashCode();
result = prime * result + _repoType.hashCode();
result = prime * result + _settlementDays;
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 BondSecurityDefinition<?, ?> other = (BondSecurityDefinition<?, ?>) obj;
if (!ObjectUtils.equals(_coupon, other._coupon)) {
return false;
}
if (!ObjectUtils.equals(_nominal, other._nominal)) {
return false;
}
if (!ObjectUtils.equals(_issuer, other._issuer)) {
return false;
}
if (_exCouponDays != other._exCouponDays) {
return false;
}
if (!ObjectUtils.equals(_repoType, other._repoType)) {
return false;
}
if (_settlementDays != other._settlementDays) {
return false;
}
return true;
}
}