/**
* 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 com.opengamma.analytics.financial.forex.derivative.Forex;
import com.opengamma.analytics.financial.forex.derivative.ForexNonDeliverableForward;
import com.opengamma.analytics.financial.forex.derivative.ForexSwap;
import com.opengamma.analytics.financial.forex.provider.ForexDiscountingMethod;
import com.opengamma.analytics.financial.forex.provider.ForexNonDeliverableForwardDiscountingMethod;
import com.opengamma.analytics.financial.forex.provider.ForexSwapDiscountingMethod;
import com.opengamma.analytics.financial.instrument.index.IndexDeposit;
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.cash.derivative.Cash;
import com.opengamma.analytics.financial.interestrate.cash.derivative.DepositIbor;
import com.opengamma.analytics.financial.interestrate.cash.provider.CashDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.cash.provider.DepositIborDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.fra.derivative.ForwardRateAgreement;
import com.opengamma.analytics.financial.interestrate.fra.provider.ForwardRateAgreementDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.future.derivative.FederalFundsFutureTransaction;
import com.opengamma.analytics.financial.interestrate.future.derivative.InterestRateFutureTransaction;
import com.opengamma.analytics.financial.interestrate.future.derivative.SwapFuturesPriceDeliverableTransaction;
import com.opengamma.analytics.financial.interestrate.future.provider.FuturesTransactionMulticurveMethod;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixed;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixedAccruedCompounding;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixedCompounding;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponFixedFxReset;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIbor;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborAverage;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborAverageFixingDates;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborAverageFixingDatesCompounding;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborAverageFixingDatesCompoundingFlatSpread;
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.CouponIborCompoundingSimpleSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborCompoundingSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponIborFxReset;
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.CouponON;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponONArithmeticAverage;
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.CouponONCompounded;
import com.opengamma.analytics.financial.interestrate.payments.derivative.CouponONSpread;
import com.opengamma.analytics.financial.interestrate.payments.derivative.DepositIndexCoupon;
import com.opengamma.analytics.financial.interestrate.payments.derivative.InterpolatedStubCoupon;
import com.opengamma.analytics.financial.interestrate.payments.derivative.Payment;
import com.opengamma.analytics.financial.interestrate.payments.derivative.PaymentFixed;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponFixedAccruedCompoundingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponFixedCompoundingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponFixedDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponFixedFxResetDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborAverageDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborAverageFixingDatesCompoundingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborAverageFixingDatesCompoundingFlatSpreadDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborAverageFixingDatesDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborCompoundingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborCompoundingFlatSpreadDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborCompoundingSimpleSpreadDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborCompoundingSpreadDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborFxResetDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborGearingDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponIborSpreadDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponONArithmeticAverageDiscountingApproxMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponONArithmeticAverageSpreadDiscountingApproxMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponONArithmeticAverageSpreadSimplifiedDiscountingApproxMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponONCompoundedDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponONDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.CouponONSpreadDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.payments.provider.PaymentFixedDiscountingMethod;
import com.opengamma.analytics.financial.interestrate.swap.derivative.Swap;
import com.opengamma.analytics.financial.interestrate.swap.derivative.SwapFixedCoupon;
import com.opengamma.analytics.financial.interestrate.swap.derivative.SwapMultileg;
import com.opengamma.analytics.financial.provider.description.interestrate.ParameterProviderInterface;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.money.MultipleCurrencyAmount;
import com.opengamma.util.money.MultipleCurrencyAmountPricer;
/**
* Calculator of the present value as a multiple currency amount using cash-flow discounting and forward estimation.
*/
public final class PresentValueDiscountingCalculator extends
InstrumentDerivativeVisitorAdapter<ParameterProviderInterface, MultipleCurrencyAmount> {
/**
* The unique instance of the calculator.
*/
private static final PresentValueDiscountingCalculator INSTANCE = new PresentValueDiscountingCalculator();
/**
* Gets the calculator instance.
* @return The calculator.
*/
public static PresentValueDiscountingCalculator getInstance() {
return INSTANCE;
}
/**
* Constructor.
*/
private PresentValueDiscountingCalculator() {
}
/**
* The methods used by the different instruments.
*/
private static final CashDiscountingMethod METHOD_DEPOSIT = CashDiscountingMethod.getInstance();
private static final PaymentFixedDiscountingMethod METHOD_PAY_FIXED = PaymentFixedDiscountingMethod.getInstance();
private static final DepositIborDiscountingMethod METHOD_DEPOSIT_IBOR = DepositIborDiscountingMethod.getInstance();
private static final CouponFixedDiscountingMethod METHOD_CPN_FIXED = CouponFixedDiscountingMethod.getInstance();
private static final CouponFixedCompoundingDiscountingMethod METHOD_CPN_FIXED_COMPOUNDING =
CouponFixedCompoundingDiscountingMethod.getInstance();
private static final CouponFixedFxResetDiscountingMethod METHOD_CPN_FIXED_FXRESET =
CouponFixedFxResetDiscountingMethod.getInstance();
private static final CouponIborFxResetDiscountingMethod METHOD_CPN_IBOR_FXRESET =
CouponIborFxResetDiscountingMethod.getInstance();
private static final CouponIborDiscountingMethod METHOD_CPN_IBOR = CouponIborDiscountingMethod.getInstance();
private static final CouponIborAverageDiscountingMethod METHOD_CPN_IBOR_AVERAGE =
CouponIborAverageDiscountingMethod.getInstance();
private static final CouponIborSpreadDiscountingMethod METHOD_CPN_IBOR_SPREAD =
CouponIborSpreadDiscountingMethod.getInstance();
private static final CouponIborGearingDiscountingMethod METHOD_CPN_IBOR_GEARING =
CouponIborGearingDiscountingMethod.getInstance();
private static final CouponIborCompoundingDiscountingMethod METHOD_CPN_IBOR_COMP =
CouponIborCompoundingDiscountingMethod.getInstance();
private static final CouponIborCompoundingSpreadDiscountingMethod METHOD_CPN_IBOR_COMP_SPREAD =
CouponIborCompoundingSpreadDiscountingMethod.getInstance();
private static final CouponIborCompoundingFlatSpreadDiscountingMethod METHOD_CPN_IBOR_COMP_FLAT_SPREAD =
CouponIborCompoundingFlatSpreadDiscountingMethod.getInstance();
private static final CouponIborCompoundingSimpleSpreadDiscountingMethod METHOD_CPN_IBOR_COMP_SIMPLE_SPREAD =
CouponIborCompoundingSimpleSpreadDiscountingMethod.getInstance();
private static final CouponONDiscountingMethod METHOD_CPN_ON = CouponONDiscountingMethod.getInstance();
private static final CouponONSpreadDiscountingMethod METHOD_CPN_ON_SPREAD =
CouponONSpreadDiscountingMethod.getInstance();
private static final CouponONArithmeticAverageDiscountingApproxMethod METHOD_CPN_AAON =
CouponONArithmeticAverageDiscountingApproxMethod.getInstance();
private static final CouponONArithmeticAverageSpreadDiscountingApproxMethod METHOD_CPN_AAON_SPREAD =
CouponONArithmeticAverageSpreadDiscountingApproxMethod.getInstance();
private static final CouponONArithmeticAverageSpreadSimplifiedDiscountingApproxMethod METHOD_CPN_ONAA_SPREADSIMPL =
CouponONArithmeticAverageSpreadSimplifiedDiscountingApproxMethod.getInstance();
private static final ForwardRateAgreementDiscountingMethod METHOD_FRA = ForwardRateAgreementDiscountingMethod.getInstance();
private static final ForexDiscountingMethod METHOD_FOREX = ForexDiscountingMethod.getInstance();
private static final ForexSwapDiscountingMethod METHOD_FOREX_SWAP = ForexSwapDiscountingMethod.getInstance();
private static final ForexNonDeliverableForwardDiscountingMethod METHOD_FOREX_NDF =
ForexNonDeliverableForwardDiscountingMethod.getInstance();
private static final FuturesTransactionMulticurveMethod METHOD_FUT = new FuturesTransactionMulticurveMethod();
private static final CouponFixedAccruedCompoundingDiscountingMethod METHOD_CPN_FIXED_ACCRUED_COMPOUNDING =
CouponFixedAccruedCompoundingDiscountingMethod.getInstance();
private static final CouponONCompoundedDiscountingMethod METHOD_CPN_ON_COMPOUNDING =
CouponONCompoundedDiscountingMethod.getInstance();
private static final InterpolatedStubPresentValueDiscountingCalculator METHOD_CPN_INTERP_STUB =
InterpolatedStubPresentValueDiscountingCalculator.getInstance();
private static final CouponIborAverageFixingDatesDiscountingMethod METHOD_CPN_IBOR_AVERAGE_FIXING_DATES =
CouponIborAverageFixingDatesDiscountingMethod.getInstance();
private static final CouponIborAverageFixingDatesCompoundingDiscountingMethod METHOD_CPN_IBOR_AVERAGE_CMP =
CouponIborAverageFixingDatesCompoundingDiscountingMethod.getInstance();
private static final CouponIborAverageFixingDatesCompoundingFlatSpreadDiscountingMethod METHOD_CPN_IBOR_FLAT_CMP_SPREAD =
CouponIborAverageFixingDatesCompoundingFlatSpreadDiscountingMethod.getInstance();
// ----- Deposit -----
@Override
public MultipleCurrencyAmount visitCash(final Cash deposit, final ParameterProviderInterface multicurve) {
return METHOD_DEPOSIT.presentValue(deposit, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitDepositIbor(final DepositIbor deposit, final ParameterProviderInterface multicurve) {
return METHOD_DEPOSIT_IBOR.presentValue(deposit, multicurve.getMulticurveProvider());
}
// ----- Payment/Coupon ------
@Override
public MultipleCurrencyAmount visitFixedPayment(final PaymentFixed payment, final ParameterProviderInterface multicurve) {
return METHOD_PAY_FIXED.presentValue(payment, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponFixed(final CouponFixed coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_FIXED.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponFixedCompounding(final CouponFixedCompounding coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_FIXED_COMPOUNDING.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponFixedFxReset(final CouponFixedFxReset coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_FIXED_FXRESET.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborFxReset(final CouponIborFxReset coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_FXRESET.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitInterpolatedStubCoupon(
final InterpolatedStubCoupon<? extends DepositIndexCoupon<? extends IndexDeposit>, ? extends IndexDeposit> payment,
final ParameterProviderInterface data) {
return payment.getFullCoupon().accept(METHOD_CPN_INTERP_STUB, InterpolatedStubData.of(data.getMulticurveProvider(), payment));
}
@Override
public MultipleCurrencyAmount visitCouponIbor(final CouponIbor coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborAverage(final CouponIborAverage coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_AVERAGE.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborSpread(final CouponIborSpread coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_SPREAD.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborGearing(final CouponIborGearing coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_GEARING.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborCompounding(final CouponIborCompounding coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_COMP.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborCompoundingSpread(final CouponIborCompoundingSpread coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_COMP_SPREAD.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborCompoundingFlatSpread(final CouponIborCompoundingFlatSpread coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_COMP_FLAT_SPREAD.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborCompoundingSimpleSpread(final CouponIborCompoundingSimpleSpread coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_COMP_SIMPLE_SPREAD.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponOIS(final CouponON coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_ON.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponONSpread(final CouponONSpread coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_ON_SPREAD.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponONArithmeticAverage(final CouponONArithmeticAverage coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_AAON.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponONArithmeticAverageSpread(CouponONArithmeticAverageSpread coupon,
ParameterProviderInterface multicurve) {
return METHOD_CPN_AAON_SPREAD.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponONArithmeticAverageSpreadSimplified(final CouponONArithmeticAverageSpreadSimplified coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_ONAA_SPREADSIMPL.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitForwardRateAgreement(final ForwardRateAgreement fra, final ParameterProviderInterface multicurve) {
return METHOD_FRA.presentValue(fra, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponFixedAccruedCompounding(final CouponFixedAccruedCompounding coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_FIXED_ACCRUED_COMPOUNDING.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponONCompounded(final CouponONCompounded coupon, final ParameterProviderInterface multicurve) {
return METHOD_CPN_ON_COMPOUNDING.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborAverageFixingDates(final CouponIborAverageFixingDates coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_AVERAGE_FIXING_DATES.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborAverageCompounding(final CouponIborAverageFixingDatesCompounding coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_AVERAGE_CMP.presentValue(coupon, multicurve.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitCouponIborAverageFlatCompoundingSpread(final CouponIborAverageFixingDatesCompoundingFlatSpread coupon,
final ParameterProviderInterface multicurve) {
return METHOD_CPN_IBOR_FLAT_CMP_SPREAD.presentValue(coupon, multicurve.getMulticurveProvider());
}
// ----- Annuity ------
@Override
public MultipleCurrencyAmount visitGenericAnnuity(final Annuity<? extends Payment> annuity,
final ParameterProviderInterface multicurve) {
ArgumentChecker.notNull(annuity, "Annuity");
ArgumentChecker.notNull(multicurve, "multicurve");
MultipleCurrencyAmount pv = annuity.getNthPayment(0).accept(this, multicurve);
MultipleCurrencyAmountPricer pricer = new MultipleCurrencyAmountPricer(pv);
for (int i = 1; i < annuity.getNumberOfPayments(); i++) {
pricer.plus(annuity.getNthPayment(i).accept(this, multicurve));
}
return pricer.getSum();
}
@Override
public MultipleCurrencyAmount visitFixedCouponAnnuity(final AnnuityCouponFixed annuity,
final ParameterProviderInterface multicurve) {
return visitGenericAnnuity(annuity, multicurve);
}
// ----- Swap ------
@Override
public MultipleCurrencyAmount visitSwap(final Swap<?, ?> swap, final ParameterProviderInterface multicurve) {
final MultipleCurrencyAmount pv1 = swap.getFirstLeg().accept(this, multicurve);
final MultipleCurrencyAmount pv2 = swap.getSecondLeg().accept(this, multicurve);
return pv1.plus(pv2);
}
@Override
public MultipleCurrencyAmount visitFixedCouponSwap(final SwapFixedCoupon<?> swap, final ParameterProviderInterface multicurves) {
return visitSwap(swap, multicurves);
}
@Override
public MultipleCurrencyAmount visitSwapMultileg(final SwapMultileg swap, final ParameterProviderInterface multicurve) {
final int nbLegs = swap.getLegs().length;
MultipleCurrencyAmount pv = swap.getLegs()[0].accept(this, multicurve);
for (int loopleg = 1; loopleg < nbLegs; loopleg++) {
pv = pv.plus(swap.getLegs()[loopleg].accept(this, multicurve));
}
return pv;
}
// ----- Futures ------
@Override
public MultipleCurrencyAmount visitFederalFundsFutureTransaction(final FederalFundsFutureTransaction futures,
final ParameterProviderInterface multicurves) {
return METHOD_FUT.presentValue(futures, multicurves);
}
@Override
public MultipleCurrencyAmount visitInterestRateFutureTransaction(final InterestRateFutureTransaction future,
final ParameterProviderInterface multicurves) {
return METHOD_FUT.presentValue(future, multicurves);
}
@Override
public MultipleCurrencyAmount visitSwapFuturesPriceDeliverableTransaction(final SwapFuturesPriceDeliverableTransaction future,
final ParameterProviderInterface multicurves) {
return METHOD_FUT.presentValue(future, multicurves);
}
// ----- Forex ------
@Override
public MultipleCurrencyAmount visitForex(final Forex derivative, final ParameterProviderInterface multicurves) {
return METHOD_FOREX.presentValue(derivative, multicurves.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitForexSwap(final ForexSwap derivative, final ParameterProviderInterface multicurves) {
return METHOD_FOREX_SWAP.presentValue(derivative, multicurves.getMulticurveProvider());
}
@Override
public MultipleCurrencyAmount visitForexNonDeliverableForward(final ForexNonDeliverableForward derivative,
final ParameterProviderInterface multicurves) {
return METHOD_FOREX_NDF.presentValue(derivative, multicurves.getMulticurveProvider());
}
}