/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.commodity.multicurvecommodity.definition; import org.threeten.bp.ZonedDateTime; import com.opengamma.OpenGammaRuntimeException; import com.opengamma.analytics.financial.commodity.multicurvecommodity.derivative.CouponCommodityCashSettle; import com.opengamma.analytics.financial.commodity.multicurvecommodity.underlying.CommodityUnderlying; import com.opengamma.analytics.financial.instrument.InstrumentDefinitionVisitor; import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment; import com.opengamma.analytics.financial.interestrate.payments.derivative.PaymentFixed; import com.opengamma.analytics.util.time.TimeCalculator; import com.opengamma.financial.convention.calendar.Calendar; import com.opengamma.timeseries.DoubleTimeSeries; import com.opengamma.util.ArgumentChecker; /** * Class describing a Coupon Commodity Cash Settle. */ public class CouponCommodityCashSettleDefinition extends CouponCommodityDefinition { /** * The fixing date. */ private final ZonedDateTime _fixingDate; /** * Constructor with all details. * @param paymentYearFraction payment year fraction, positive * @param underlying The commodity underlying, not null * @param unitName name of the unit of the commodity delivered, not null * @param notional notional * @param settlementDate The settlement date, not null * @param calendar The holiday calendar, not null * @param fixingDate the fixing date */ public CouponCommodityCashSettleDefinition(final double paymentYearFraction, final CommodityUnderlying underlying, final String unitName, final double notional, final ZonedDateTime settlementDate, final Calendar calendar, final ZonedDateTime fixingDate) { super(paymentYearFraction, underlying, unitName, notional, settlementDate, calendar); ArgumentChecker.notNull(fixingDate, "fixing date"); ArgumentChecker.isTrue(settlementDate.isAfter(fixingDate), "settlement date must be after the fixing date"); _fixingDate = fixingDate; } /** * Constructor with all details. With a payment year fraction of 1. * @param underlying The commodity underlying, not null * @param notional notional * @param settlementDate The settlement date, not null * @param calendar The holiday calendar, not null * @param fixingDate the fixing date */ public CouponCommodityCashSettleDefinition(final CommodityUnderlying underlying, final double notional, final ZonedDateTime settlementDate, final Calendar calendar, final ZonedDateTime fixingDate) { super(1.0, underlying, underlying.getName(), notional, settlementDate, calendar); ArgumentChecker.notNull(fixingDate, "fixing date"); ArgumentChecker.isTrue(settlementDate.isAfter(fixingDate), "settlement date must be after the fixing date"); _fixingDate = fixingDate; } /** * Gets the payment date. * @return The payment date. */ public ZonedDateTime getFixingDate() { return _fixingDate; } @Override public double getReferenceAmount() { return getNotional(); } @Override public Payment toDerivative(final ZonedDateTime date) { ArgumentChecker.notNull(date, "date"); ArgumentChecker.inOrderOrEqual(date, getFixingDate(), "date", "expiry date"); final double settlementTime = TimeCalculator.getTimeBetween(date, getSettlementDate()); return new CouponCommodityCashSettle(getPaymentYearFractione(), getUnderlying(), getUnitName(), getNotional(), settlementTime, getCalendar()); } public Payment toDerivative(final ZonedDateTime date, final DoubleTimeSeries<ZonedDateTime> priceIndexTimeSeries, final String... yieldCurveNames) { return toDerivative(date, priceIndexTimeSeries); } public Payment toDerivative(final ZonedDateTime date, final DoubleTimeSeries<ZonedDateTime> commoIndexTimeSeries) { ArgumentChecker.notNull(date, "date"); ArgumentChecker.notNull(commoIndexTimeSeries, "Index fixing time series"); final double settlementTime = TimeCalculator.getTimeBetween(date, getSettlementDate()); if (date.equals(getFixingDate())) { final Double commodityFixing = commoIndexTimeSeries.getValue(getFixingDate()); if (commodityFixing != null) { return new PaymentFixed(getCurrency(), settlementTime, commodityFixing * getNotional()); } } if (date.isAfter(getFixingDate())) { final Double commodityFixing = commoIndexTimeSeries.getValue(getFixingDate()); if (commodityFixing == null) { throw new OpenGammaRuntimeException("Could not get fixing value for date " + getFixingDate()); } return new PaymentFixed(getCurrency(), settlementTime, commodityFixing * getNotional()); } return new CouponCommodityCashSettle(getPaymentYearFractione(), getUnderlying(), getUnitName(), getNotional(), settlementTime, getCalendar()); } @Override public <U, V> V accept(final InstrumentDefinitionVisitor<U, V> visitor, final U data) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitCouponCommodityCashSettleDefinition(this, data); } @Override public <V> V accept(final InstrumentDefinitionVisitor<?, V> visitor) { ArgumentChecker.notNull(visitor, "visitor"); return visitor.visitCouponCommodityCashSettleDefinition(this); } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "CouponCommodityCashSettleDefinition [_fixingDate=" + _fixingDate + "]"; } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((_fixingDate == null) ? 0 : _fixingDate.hashCode()); return result; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } final CouponCommodityCashSettleDefinition other = (CouponCommodityCashSettleDefinition) obj; if (_fixingDate == null) { if (other._fixingDate != null) { return false; } } else if (!_fixingDate.equals(other._fixingDate)) { return false; } return true; } }