/** * 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 org.threeten.bp.ZonedDateTime; import com.opengamma.analytics.financial.instrument.InstrumentDefinition; 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.bond.definition.BondTransaction; import com.opengamma.analytics.financial.interestrate.payments.derivative.Coupon; import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment; import com.opengamma.util.ArgumentChecker; /** * Describes a generic single currency bond transaction. * @param <N> The notional type (usually FixedPayment or CouponInflationZeroCoupon). * @param <C> The coupon type. */ public abstract class BondTransactionDefinition<N extends PaymentDefinition, C extends CouponDefinition> implements InstrumentDefinition<BondTransaction<? extends BondSecurity<? extends Payment, ? extends Coupon>>> { /** * The bond underlying the transaction. */ private final BondSecurityDefinition<N, C> _underlyingBond; /** * The number of bonds purchased (can be negative or positive). */ private final double _quantity; /** * Transaction settlement date. */ private final ZonedDateTime _settlementDate; /** * The (quoted) price of the transaction in relative term (i.e. 0.90 if the clean price is 90% of nominal). * The meaning of this number will depend on the type of bond (fixed coupon, FRN, inflation). */ private final double _price; /** * The coupon index of the transaction settlement date. Take the ex-coupon period into account. */ private int _couponIndex; /** * Previous accrual date. Take the ex-coupon period into account, i.e. the previous and next accrual dates are relative * to the settlement date plus the ex-coupon period. */ private final ZonedDateTime _previousAccrualDate; /** * Next accrual date. The next accrual date is the first end accrual date which is strictly after the settlement date plus ex-coupon period. */ private final ZonedDateTime _nextAccrualDate; /** * Constructor of the bond transaction from all the transaction details. * @param underlyingBond The bond underlying the transaction. * @param quantity The number of bonds purchased (can be negative or positive). * @param settlementDate Transaction settlement date. * @param price The (dirty) price of the transaction in relative term (i.e. 0.90 if the dirty price is 90% of nominal). */ public BondTransactionDefinition(final BondSecurityDefinition<N, C> underlyingBond, final double quantity, final ZonedDateTime settlementDate, final double price) { ArgumentChecker.notNull(underlyingBond, "Underlying bond"); ArgumentChecker.notNull(settlementDate, "Settlement date"); _underlyingBond = underlyingBond; _quantity = quantity; _settlementDate = settlementDate; _price = price; final int nbCoupon = underlyingBond.getCoupons().getNumberOfPayments(); for (int loopcpn = 0; loopcpn < nbCoupon; loopcpn++) { if (underlyingBond.getCoupons().getNthPayment(loopcpn).getAccrualEndDate().isAfter(_settlementDate)) { _couponIndex = loopcpn; break; } } _previousAccrualDate = underlyingBond.getCoupons().getNthPayment(getCouponIndex()).getAccrualStartDate(); _nextAccrualDate = underlyingBond.getCoupons().getNthPayment(getCouponIndex()).getAccrualEndDate(); } /** * Gets the bond underlying the transaction. * @return The underlying Bond. */ public BondSecurityDefinition<N, C> getUnderlyingBond() { return _underlyingBond; } /** * Gets the number (or quantity) of bonds purchased (can be negative or positive). * @return The quantity. */ public double getQuantity() { return _quantity; } /** * Gets the settlement date. * @return The settlement date. */ public ZonedDateTime getSettlementDate() { return _settlementDate; } /** * Returns the (dirty) price of the bond. * @return The price. */ public double getPrice() { return _price; } /** * Gets the coupon index of the transaction settlement date. * @return The coupon index of the settlement date. */ public int getCouponIndex() { return _couponIndex; } /** * Gets the previous accrual date with respect to the settlement date. * @return The previous accrual date. */ public ZonedDateTime getPreviousAccrualDate() { return _previousAccrualDate; } /** * Gets the next accrual date with respect to the settlement date. * @return The next accrual date. */ public ZonedDateTime getNextAccrualDate() { return _nextAccrualDate; } @Override public int hashCode() { final int prime = 31; int result = 1; long temp; temp = Double.doubleToLongBits(_price); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(_quantity); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + _settlementDate.hashCode(); result = prime * result + _underlyingBond.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 BondTransactionDefinition<?, ?> other = (BondTransactionDefinition<?, ?>) obj; if (Double.doubleToLongBits(_price) != Double.doubleToLongBits(other._price)) { return false; } if (Double.doubleToLongBits(_quantity) != Double.doubleToLongBits(other._quantity)) { return false; } if (!ObjectUtils.equals(_settlementDate, other._settlementDate)) { return false; } if (!ObjectUtils.equals(_underlyingBond, other._underlyingBond)) { return false; } return true; } }