com.opengamma.strata.pricer.impl.swap.DiscountingKnownAmountPaymentPeriodPricer Maven / Gradle / Ivy
/*
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.impl.swap;
import static java.time.temporal.ChronoUnit.DAYS;
import java.time.LocalDate;
import com.opengamma.strata.basics.currency.Currency;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.market.explain.ExplainKey;
import com.opengamma.strata.market.explain.ExplainMapBuilder;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.DiscountingPaymentPricer;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.pricer.swap.SwapPaymentPeriodPricer;
import com.opengamma.strata.product.swap.KnownAmountSwapPaymentPeriod;
/**
* Pricer implementation for swap payment periods based on a known amount.
*
* This pricer performs discounting of the known amount.
*/
public class DiscountingKnownAmountPaymentPeriodPricer
implements SwapPaymentPeriodPricer {
/**
* Default implementation.
*/
public static final DiscountingKnownAmountPaymentPeriodPricer DEFAULT = new DiscountingKnownAmountPaymentPeriodPricer(
DiscountingPaymentPricer.DEFAULT);
/**
* Payment pricer.
*/
private final DiscountingPaymentPricer paymentPricer;
/**
* Creates an instance.
*
* @param paymentPricer the payment pricer
*/
public DiscountingKnownAmountPaymentPeriodPricer(DiscountingPaymentPricer paymentPricer) {
this.paymentPricer = ArgChecker.notNull(paymentPricer, "paymentPricer");
}
//-------------------------------------------------------------------------
@Override
public double presentValue(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
return paymentPricer.presentValueAmount(period.getPayment(), provider);
}
@Override
public double forecastValue(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
return paymentPricer.forecastValueAmount(period.getPayment(), provider);
}
@Override
public double accruedInterest(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
// no day count available, so return the simple day-based fraction
LocalDate valDate = provider.getValuationDate();
if (valDate.compareTo(period.getStartDate()) <= 0 || valDate.compareTo(period.getEndDate()) > 0) {
return 0d;
}
double fv = forecastValue(period, provider);
double totalDays = period.getStartDate().until(period.getEndDate(), DAYS);
double partialDays = period.getStartDate().until(valDate, DAYS);
return fv * (partialDays / totalDays);
}
@Override
public double pvbp(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
throw new UnsupportedOperationException("Unable to calculate PVBP for KnownAmountPaymentPeriod");
}
//-------------------------------------------------------------------------
@Override
public PointSensitivityBuilder presentValueSensitivity(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
return paymentPricer.presentValueSensitivity(period.getPayment(), provider);
}
@Override
public PointSensitivityBuilder forecastValueSensitivity(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
return PointSensitivityBuilder.none();
}
@Override
public PointSensitivityBuilder pvbpSensitivity(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
throw new UnsupportedOperationException("Unable to calculate PVBP for KnownAmountPaymentPeriod");
}
//-------------------------------------------------------------------------
@Override
public void explainPresentValue(KnownAmountSwapPaymentPeriod period, RatesProvider provider, ExplainMapBuilder builder) {
Currency currency = period.getCurrency();
LocalDate paymentDate = period.getPaymentDate();
builder.put(ExplainKey.ENTRY_TYPE, "KnownAmountPaymentPeriod");
builder.put(ExplainKey.PAYMENT_DATE, paymentDate);
builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
builder.put(ExplainKey.START_DATE, period.getStartDate());
builder.put(ExplainKey.UNADJUSTED_START_DATE, period.getUnadjustedStartDate());
builder.put(ExplainKey.END_DATE, period.getEndDate());
builder.put(ExplainKey.UNADJUSTED_END_DATE, period.getUnadjustedEndDate());
builder.put(ExplainKey.DAYS, (int) DAYS.between(period.getStartDate(), period.getEndDate()));
if (paymentDate.isBefore(provider.getValuationDate())) {
builder.put(ExplainKey.COMPLETED, Boolean.TRUE);
builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
} else {
builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate));
builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, provider)));
builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(period, provider)));
}
}
//-------------------------------------------------------------------------
@Override
public MultiCurrencyAmount currencyExposure(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
return MultiCurrencyAmount.of(CurrencyAmount.of(period.getCurrency(), presentValue(period, provider)));
}
@Override
public double currentCash(KnownAmountSwapPaymentPeriod period, RatesProvider provider) {
if (provider.getValuationDate().isEqual(period.getPaymentDate())) {
return forecastValue(period, provider);
}
return 0d;
}
}