/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.pricer.impl.swap; import com.opengamma.strata.basics.currency.MultiCurrencyAmount; import com.opengamma.strata.collect.ArgChecker; import com.opengamma.strata.market.explain.ExplainMapBuilder; import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder; import com.opengamma.strata.pricer.rate.RatesProvider; import com.opengamma.strata.pricer.swap.SwapPaymentPeriodPricer; import com.opengamma.strata.product.swap.KnownAmountSwapPaymentPeriod; import com.opengamma.strata.product.swap.RatePaymentPeriod; import com.opengamma.strata.product.swap.SwapPaymentPeriod; /** * Pricer implementation for payment periods using multiple dispatch. * <p> * Dispatches the request to the correct implementation. */ public class DispatchingSwapPaymentPeriodPricer implements SwapPaymentPeriodPricer<SwapPaymentPeriod> { /** * Default implementation. */ public static final DispatchingSwapPaymentPeriodPricer DEFAULT = new DispatchingSwapPaymentPeriodPricer( DiscountingRatePaymentPeriodPricer.DEFAULT, DiscountingKnownAmountPaymentPeriodPricer.DEFAULT); /** * Pricer for {@link RatePaymentPeriod}. */ private final SwapPaymentPeriodPricer<RatePaymentPeriod> ratePaymentPeriodPricer; /** * Pricer for {@link KnownAmountSwapPaymentPeriod}. */ private final SwapPaymentPeriodPricer<KnownAmountSwapPaymentPeriod> knownAmountPaymentPeriodPricer; /** * Creates an instance. * * @param ratePaymentPeriodPricer the pricer for {@link RatePaymentPeriod} * @param knownAmountPaymentPeriodPricer the pricer for {@link KnownAmountSwapPaymentPeriod} */ public DispatchingSwapPaymentPeriodPricer( SwapPaymentPeriodPricer<RatePaymentPeriod> ratePaymentPeriodPricer, SwapPaymentPeriodPricer<KnownAmountSwapPaymentPeriod> knownAmountPaymentPeriodPricer) { this.ratePaymentPeriodPricer = ArgChecker.notNull(ratePaymentPeriodPricer, "ratePaymentPeriodPricer"); this.knownAmountPaymentPeriodPricer = ArgChecker.notNull(knownAmountPaymentPeriodPricer, "knownAmountPaymentPeriodPricer"); } //------------------------------------------------------------------------- @Override public double presentValue(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.presentValue((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.presentValue((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentPeriod type: " + paymentPeriod.getClass().getSimpleName()); } } @Override public PointSensitivityBuilder presentValueSensitivity(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.presentValueSensitivity((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.presentValueSensitivity((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentPeriod type: " + paymentPeriod.getClass().getSimpleName()); } } //------------------------------------------------------------------------- @Override public double forecastValue(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.forecastValue((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.forecastValue((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentPeriod type: " + paymentPeriod.getClass().getSimpleName()); } } @Override public PointSensitivityBuilder forecastValueSensitivity(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.forecastValueSensitivity((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.forecastValueSensitivity((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentPeriod type: " + paymentPeriod.getClass().getSimpleName()); } } //------------------------------------------------------------------------- @Override public double pvbp(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.pvbp((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.pvbp((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentPeriod type: " + paymentPeriod.getClass().getSimpleName()); } } @Override public PointSensitivityBuilder pvbpSensitivity(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.pvbpSensitivity((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.pvbpSensitivity((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentPeriod type: " + paymentPeriod.getClass().getSimpleName()); } } //------------------------------------------------------------------------- @Override public double accruedInterest(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.accruedInterest((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.accruedInterest((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentPeriod type: " + paymentPeriod.getClass().getSimpleName()); } } //------------------------------------------------------------------------- @Override public void explainPresentValue(SwapPaymentPeriod paymentPeriod, RatesProvider provider, ExplainMapBuilder builder) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { ratePaymentPeriodPricer.explainPresentValue((RatePaymentPeriod) paymentPeriod, provider, builder); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { knownAmountPaymentPeriodPricer.explainPresentValue((KnownAmountSwapPaymentPeriod) paymentPeriod, provider, builder); } else { throw new IllegalArgumentException("Unknown PaymentEvent type: " + paymentPeriod.getClass().getSimpleName()); } } //------------------------------------------------------------------------- @Override public MultiCurrencyAmount currencyExposure(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.currencyExposure((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.currencyExposure((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentEvent type: " + paymentPeriod.getClass().getSimpleName()); } } @Override public double currentCash(SwapPaymentPeriod paymentPeriod, RatesProvider provider) { // dispatch by runtime type if (paymentPeriod instanceof RatePaymentPeriod) { return ratePaymentPeriodPricer.currentCash((RatePaymentPeriod) paymentPeriod, provider); } else if (paymentPeriod instanceof KnownAmountSwapPaymentPeriod) { return knownAmountPaymentPeriodPricer.currentCash((KnownAmountSwapPaymentPeriod) paymentPeriod, provider); } else { throw new IllegalArgumentException("Unknown PaymentEvent type: " + paymentPeriod.getClass().getSimpleName()); } } }