/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.provider.calculator.discounting;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivativeVisitorAdapter;
import com.opengamma.analytics.financial.interestrate.annuity.derivative.Annuity;
import com.opengamma.analytics.financial.interestrate.annuity.derivative.AnnuityCouponFixed;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Coupon;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixed;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIbor;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborCompounding;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborCompoundingFlatSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponONArithmeticAverageSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponONArithmeticAverageSpreadSimplified;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponONSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment;
import com.opengamma.analytics.financial.interestrate.payments.derivative.PaymentFixed;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface;
import com.opengamma.analytics.financial.provider.sensitivity.multicurve.MulticurveSensitivity;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.tuple.DoublesPair;
/**
* Computes the sensitivity to the curves (in the Market description of curve bundle) of the market quote sensitivity.
*/
public final class PresentValueMarketQuoteSensitivityCurveSensitivityDiscountingCalculator extends InstrumentDerivativeVisitorAdapter<MulticurveProviderInterface, MulticurveSensitivity> {
/**
* The unique instance of the calculator.
*/
private static final PresentValueMarketQuoteSensitivityCurveSensitivityDiscountingCalculator INSTANCE = new PresentValueMarketQuoteSensitivityCurveSensitivityDiscountingCalculator();
/**
* Gets the calculator instance.
* @return The calculator.
*/
public static PresentValueMarketQuoteSensitivityCurveSensitivityDiscountingCalculator getInstance() {
return INSTANCE;
}
/**
* Constructor.
*/
private PresentValueMarketQuoteSensitivityCurveSensitivityDiscountingCalculator() {
}
// ----- Payment/Coupon ------
@Override
public MulticurveSensitivity visitFixedPayment(final PaymentFixed payment, final MulticurveProviderInterface multicurve) {
return new MulticurveSensitivity();
}
public MulticurveSensitivity visitCoupon(final Coupon coupon, final MulticurveProviderInterface multicurve) {
ArgumentChecker.notNull(multicurve, "Market");
ArgumentChecker.notNull(coupon, "Coupon");
final double df = multicurve.getDiscountFactor(coupon.getCurrency(), coupon.getPaymentTime());
// Backward sweep
final double mqsBar = 1.0;
final double dfBar = coupon.getPaymentYearFraction() * coupon.getNotional() * mqsBar;
final Map<String, List<DoublesPair>> resultMapDsc = new HashMap<>();
final List<DoublesPair> listDiscounting = new ArrayList<>();
listDiscounting.add(DoublesPair.of(coupon.getPaymentTime(), -coupon.getPaymentTime() * df * dfBar));
// resultMapDsc.put(coupon.getFundingCurveName(), listDiscounting);
resultMapDsc.put(multicurve.getName(coupon.getCurrency()), listDiscounting);
return MulticurveSensitivity.ofYieldDiscounting(resultMapDsc);
}
@Override
public MulticurveSensitivity visitCouponFixed(final CouponFixed coupon, final MulticurveProviderInterface multicurve) {
return visitCoupon(coupon, multicurve);
}
@Override
public MulticurveSensitivity visitCouponONSpread(final CouponONSpread coupon, final MulticurveProviderInterface multicurve) {
return visitCoupon(coupon, multicurve);
}
@Override
public MulticurveSensitivity visitCouponONArithmeticAverageSpreadSimplified(final CouponONArithmeticAverageSpreadSimplified coupon, final MulticurveProviderInterface multicurve) {
return visitCoupon(coupon, multicurve);
}
@Override
public MulticurveSensitivity visitCouponONArithmeticAverageSpread(final CouponONArithmeticAverageSpread coupon, final MulticurveProviderInterface multicurve) {
return visitCoupon(coupon, multicurve);
}
@Override
public MulticurveSensitivity visitCouponIbor(final CouponIbor coupon, final MulticurveProviderInterface multicurve) {
return visitCoupon(coupon, multicurve);
}
@Override
public MulticurveSensitivity visitCouponIborSpread(final CouponIborSpread coupon, final MulticurveProviderInterface multicurve) {
return visitCoupon(coupon, multicurve);
}
@Override
public MulticurveSensitivity visitCouponIborCompounding(final CouponIborCompounding coupon, final MulticurveProviderInterface multicurve) {
return visitCoupon(coupon, multicurve);
}
@Override
public MulticurveSensitivity visitCouponIborCompoundingFlatSpread(final CouponIborCompoundingFlatSpread coupon, final MulticurveProviderInterface multicurve) {
// TODO: [PLAT-5978] Change to exact sensitivity.
return visitCoupon(coupon, multicurve);
}
// ----- Annuity ------
@Override
public MulticurveSensitivity visitGenericAnnuity(final Annuity<? extends Payment> annuity, final MulticurveProviderInterface multicurve) {
ArgumentChecker.notNull(multicurve, "multicurve");
ArgumentChecker.notNull(annuity, "Annuity");
MulticurveSensitivity pvbpSensi = new MulticurveSensitivity();
for (final Payment p : annuity.getPayments()) {
pvbpSensi = pvbpSensi.plus(p.accept(this, multicurve));
}
return pvbpSensi;
}
@Override
public MulticurveSensitivity visitFixedCouponAnnuity(final AnnuityCouponFixed annuity, final MulticurveProviderInterface multicurve) {
return visitGenericAnnuity(annuity, multicurve);
}
}