/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.financial.instrument; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitorAdapter; import com.opengamma.analytics.financial.interestrate.YieldCurveBundle; import com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity; import com.opengamma.analytics.financial.interestrate.fra.derivative.ForwardRateAgreement; import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIbor; import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborGearing; import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborSpread; import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment; import com.opengamma.analytics.financial.interestrate.swap.derivative.Swap; import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.money.CurrencyAmount; import com.opengamma.util.money.MultipleCurrencyAmount; /** * Returns all of the projected receive floating cash-flows of an instrument. * @deprecated {@link YieldCurveBundle} is deprecated */ @Deprecated public final class ProjectedReceiveCashFlowVisitor extends InstrumentDerivativeVisitorAdapter<YieldCurveBundle, List<MultipleCurrencyAmount>> { private static final ProjectedReceiveCashFlowVisitor INSTANCE = new ProjectedReceiveCashFlowVisitor(); public static ProjectedReceiveCashFlowVisitor getInstance() { return INSTANCE; } private ProjectedReceiveCashFlowVisitor() { // super(Collections.<MultipleCurrencyAmount>emptyList()); } /** * If the notional is negative (i.e. the amount is to be paid), returns * an empty list. Otherwise, returns a list containing the payment estimated * from the forward curve. * @param coupon The coupon instrument, not null * @param data The yield curves, not null * @return A list containing the (single) amount, or an empty list, as appropriate */ @Override public List<MultipleCurrencyAmount> visitCouponIbor(final CouponIbor coupon, final YieldCurveBundle data) { ArgumentChecker.notNull(coupon, "coupon"); ArgumentChecker.notNull(data, "data"); if (coupon.getNotional() < 0) { return Collections.emptyList(); } final YieldAndDiscountCurve forwardCurve = data.getCurve(coupon.getForwardCurveName()); final double forward = (forwardCurve.getDiscountFactor(coupon.getFixingPeriodStartTime()) / forwardCurve.getDiscountFactor(coupon.getFixingPeriodEndTime()) - 1) / coupon.getFixingAccrualFactor(); final double amount = coupon.getNotional() * coupon.getPaymentYearFraction() * forward; return Collections.singletonList(MultipleCurrencyAmount.of(CurrencyAmount.of(coupon.getCurrency(), amount))); } /** * If the notional is negative (i.e. the amount is to be paid), returns * an empty list. Otherwise, returns a list containing the payment estimated * from the forward curve. * @param coupon The coupon instrument, not null * @param data The yield curves, not null * @return A list containing the (single) amount, or an empty list, as appropriate */ @Override public List<MultipleCurrencyAmount> visitCouponIborSpread(final CouponIborSpread coupon, final YieldCurveBundle data) { ArgumentChecker.notNull(coupon, "coupon"); ArgumentChecker.notNull(data, "data"); if (coupon.getNotional() < 0) { return Collections.emptyList(); } final YieldAndDiscountCurve forwardCurve = data.getCurve(coupon.getForwardCurveName()); final double forward = (forwardCurve.getDiscountFactor(coupon.getFixingPeriodStartTime()) / forwardCurve.getDiscountFactor(coupon.getFixingPeriodEndTime()) - 1) / coupon.getFixingAccrualFactor(); final double amount = -(coupon.getNotional() * coupon.getPaymentYearFraction() * forward + coupon.getSpreadAmount()); return Collections.singletonList(MultipleCurrencyAmount.of(CurrencyAmount.of(coupon.getCurrency(), amount))); } /** * If the notional is positive (i.e. the amount is to be received), returns * an empty list. Otherwise, returns a list containing the payment * estimated from the forward curve. * @param coupon The coupon instrument, not null * @param data The yield curves, not null * @return A list containing the (single) amount, or an empty list, as appropriate */ @Override public List<MultipleCurrencyAmount> visitCouponIborGearing(final CouponIborGearing coupon, final YieldCurveBundle data) { ArgumentChecker.notNull(coupon, "coupon"); ArgumentChecker.notNull(data, "data"); if (coupon.getNotional() > 0) { return Collections.emptyList(); } final YieldAndDiscountCurve forwardCurve = data.getCurve(coupon.getForwardCurveName()); final double forward = (forwardCurve.getDiscountFactor(coupon.getFixingPeriodStartTime()) / forwardCurve.getDiscountFactor(coupon.getFixingPeriodEndTime()) - 1) / coupon.getFixingAccrualFactor(); final double amount = -(coupon.getNotional() * coupon.getPaymentYearFraction() * (coupon.getFactor() * forward) + coupon.getSpreadAmount()); return Collections.singletonList(MultipleCurrencyAmount.of(CurrencyAmount.of(coupon.getCurrency(), amount))); } /** * If the notional is negative (i.e. the FRA is a receiver), returns an empty list. Otherwise, returns * a list containing the payment estimated from the forward curve. * @param fra The FRA, not null * @param data The yield curves, not null * @return A list containing the (single) amount, or an empty list, as appropriate */ @Override public List<MultipleCurrencyAmount> visitForwardRateAgreement(final ForwardRateAgreement fra, final YieldCurveBundle data) { ArgumentChecker.notNull(fra, "FRA"); ArgumentChecker.notNull(data, "data"); if (fra.getNotional() < 0) { return Collections.emptyList(); } final YieldAndDiscountCurve forwardCurve = data.getCurve(fra.getForwardCurveName()); final double forward = (forwardCurve.getDiscountFactor(fra.getFixingPeriodStartTime()) / forwardCurve.getDiscountFactor(fra.getFixingPeriodEndTime()) - 1) / fra.getFixingYearFraction(); final double amount = fra.getPaymentYearFraction() * fra.getNotional() * forward / (1 + fra.getPaymentYearFraction() * forward); return Collections.singletonList(MultipleCurrencyAmount.of(CurrencyAmount.of(fra.getCurrency(), amount))); } /** * Returns a list containing all of the estimated floating payments of an annuity. If there are no floating payments to be made, * an empty list is returned * @param annuity The annuity, not null * @param data The yield curves, not null * @return A list containing the amounts */ @Override public List<MultipleCurrencyAmount> visitGenericAnnuity(final Annuity<? extends Payment> annuity, final YieldCurveBundle data) { ArgumentChecker.notNull(annuity, "annuity"); ArgumentChecker.notNull(data, "data"); return getDatesFromAnnuity(annuity, data); } /** * Returns a list containing all of the estimated floating payments to be made. * @param swap The swap, not null * @param data The yield curves, not null * @return A list containing floating payments */ @Override public List<MultipleCurrencyAmount> visitSwap(final Swap<?, ?> swap, final YieldCurveBundle data) { ArgumentChecker.notNull(swap, "swap"); ArgumentChecker.notNull(data, "data"); if (!swap.getFirstLeg().isPayer()) { return swap.getFirstLeg().accept(this, data); } return swap.getSecondLeg().accept(this, data); } private List<MultipleCurrencyAmount> getDatesFromAnnuity(final Annuity<? extends Payment> annuity, final YieldCurveBundle data) { final List<MultipleCurrencyAmount> result = new ArrayList<>(); for (final Payment payment : annuity.getPayments()) { final List<MultipleCurrencyAmount> payments = payment.accept(this, data); for (final MultipleCurrencyAmount mca : payments) { final int scale = mca.getCurrencyAmounts()[0].getAmount() < 0 ? -1 : 1; result.add(mca.multipliedBy(scale)); } } return result; } }