com.opengamma.strata.pricer.bond.DiscountingFixedCouponBondPaymentPeriodPricer 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.bond;
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.market.explain.ExplainKey;
import com.opengamma.strata.market.explain.ExplainMapBuilder;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.CompoundedRateType;
import com.opengamma.strata.pricer.ZeroRateSensitivity;
import com.opengamma.strata.product.bond.FixedCouponBondPaymentPeriod;
/**
* Pricer implementation for bond payment periods based on a fixed coupon.
*
* This pricer performs discounting of the fixed coupon payment.
*/
public class DiscountingFixedCouponBondPaymentPeriodPricer {
/**
* Default implementation.
*/
public static final DiscountingFixedCouponBondPaymentPeriodPricer DEFAULT =
new DiscountingFixedCouponBondPaymentPeriodPricer();
/**
* Creates an instance.
*/
public DiscountingFixedCouponBondPaymentPeriodPricer() {
}
//-------------------------------------------------------------------------
/**
* Calculates the present value of a single fixed coupon payment period.
*
* The amount is expressed in the currency of the period.
* This returns the value of the period with discounting.
*
* The payment date of the period should not be in the past.
* The result of this method for payment dates in the past is undefined.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @return the present value of the period
*/
public double presentValue(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors) {
if (period.getPaymentDate().isBefore(discountFactors.getValuationDate())) {
return 0d;
}
double df = discountFactors.discountFactor(period.getPaymentDate());
return period.getFixedRate() * period.getNotional() * period.getYearFraction() * df;
}
/**
* Calculates the present value of a single fixed coupon payment period with z-spread.
*
* The z-spread is a parallel shift applied to continuously compounded rates or periodic
* compounded rates of the discounting curve.
*
* The amount is expressed in the currency of the period.
* This returns the value of the period with discounting.
*
* The payment date of the period should not be in the past.
* The result of this method for payment dates in the past is undefined.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @param zSpread the z-spread
* @param compoundedRateType the compounded rate type
* @param periodsPerYear the number of periods per year
* @return the present value of the period
*/
public double presentValueWithSpread(
FixedCouponBondPaymentPeriod period,
IssuerCurveDiscountFactors discountFactors,
double zSpread,
CompoundedRateType compoundedRateType,
int periodsPerYear) {
if (period.getPaymentDate().isBefore(discountFactors.getValuationDate())) {
return 0d;
}
double df = discountFactors.getDiscountFactors()
.discountFactorWithSpread(period.getPaymentDate(), zSpread, compoundedRateType, periodsPerYear);
return period.getFixedRate() * period.getNotional() * period.getYearFraction() * df;
}
//-------------------------------------------------------------------------
/**
* Calculates the forecast value of a single fixed coupon payment period.
*
* The amount is expressed in the currency of the period.
* This returns the value of the period with discounting.
*
* The payment date of the period should not be in the past.
* The result of this method for payment dates in the past is undefined.
*
* The forecast value is z-spread independent.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @return the present value of the period
*/
public double forecastValue(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors) {
if (period.getPaymentDate().isBefore(discountFactors.getValuationDate())) {
return 0d;
}
return period.getFixedRate() * period.getNotional() * period.getYearFraction();
}
//-------------------------------------------------------------------------
/**
* Calculates the present value sensitivity of a single fixed coupon payment period.
*
* The present value sensitivity of the period is the sensitivity of the present value to
* the underlying curves.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @return the present value curve sensitivity of the period
*/
public PointSensitivityBuilder presentValueSensitivity(
FixedCouponBondPaymentPeriod period,
IssuerCurveDiscountFactors discountFactors) {
if (period.getPaymentDate().isBefore(discountFactors.getValuationDate())) {
return PointSensitivityBuilder.none();
}
IssuerCurveZeroRateSensitivity dscSensi = discountFactors.zeroRatePointSensitivity(period.getPaymentDate());
return dscSensi.multipliedBy(period.getFixedRate() * period.getNotional() * period.getYearFraction());
}
/**
* Calculates the present value sensitivity of a single fixed coupon payment period with z-spread.
*
* The z-spread is a parallel shift applied to continuously compounded rates or periodic
* compounded rates of the discounting curve.
*
* The present value sensitivity of the period is the sensitivity of the present value to
* the underlying curves.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @param zSpread the z-spread
* @param compoundedRateType the compounded rate type
* @param periodsPerYear the number of periods per year
* @return the present value curve sensitivity of the period
*/
public PointSensitivityBuilder presentValueSensitivityWithSpread(
FixedCouponBondPaymentPeriod period,
IssuerCurveDiscountFactors discountFactors,
double zSpread,
CompoundedRateType compoundedRateType,
int periodsPerYear) {
if (period.getPaymentDate().isBefore(discountFactors.getValuationDate())) {
return PointSensitivityBuilder.none();
}
ZeroRateSensitivity zeroSensi = discountFactors.getDiscountFactors().zeroRatePointSensitivityWithSpread(
period.getPaymentDate(), zSpread, compoundedRateType, periodsPerYear);
IssuerCurveZeroRateSensitivity dscSensi =
IssuerCurveZeroRateSensitivity.of(zeroSensi, discountFactors.getLegalEntityGroup());
return dscSensi.multipliedBy(period.getFixedRate() * period.getNotional() * period.getYearFraction());
}
//-------------------------------------------------------------------------
/**
* Calculates the forecast value sensitivity of a single fixed coupon payment period.
*
* The forecast value sensitivity of the period is the sensitivity of the forecast value to
* the underlying curves.
*
* The forecast value sensitivity is zero and z-spread independent for the fixed payment.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @return the forecast value curve sensitivity of the period
*/
public PointSensitivityBuilder forecastValueSensitivity(
FixedCouponBondPaymentPeriod period,
IssuerCurveDiscountFactors discountFactors) {
return PointSensitivityBuilder.none();
}
//-------------------------------------------------------------------------
/**
* Explains the present value of a single fixed coupon payment period.
*
* This adds information to the {@link ExplainMapBuilder} to aid understanding of the calculation.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @param builder the builder to populate
*/
public void explainPresentValue(
FixedCouponBondPaymentPeriod period,
IssuerCurveDiscountFactors discountFactors,
ExplainMapBuilder builder) {
Currency currency = period.getCurrency();
LocalDate paymentDate = period.getPaymentDate();
explainBasics(period, builder, currency, paymentDate);
if (paymentDate.isBefore(discountFactors.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, discountFactors.discountFactor(paymentDate));
builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, discountFactors)));
builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(period, discountFactors)));
}
}
/**
* Explains the present value of a single fixed coupon payment period with z-spread.
*
* This adds information to the {@link ExplainMapBuilder} to aid understanding of the calculation.
*
* The z-spread is a parallel shift applied to continuously compounded rates or periodic
* compounded rates of the discounting curve.
*
* @param period the period to price
* @param discountFactors the discount factor provider
* @param zSpread the z-spread
* @param compoundedRateType the compounded rate type
* @param periodsPerYear the number of periods per year
* @param builder the builder to populate
*/
public void explainPresentValueWithSpread(
FixedCouponBondPaymentPeriod period,
IssuerCurveDiscountFactors discountFactors,
ExplainMapBuilder builder,
double zSpread,
CompoundedRateType compoundedRateType,
int periodsPerYear) {
Currency currency = period.getCurrency();
LocalDate paymentDate = period.getPaymentDate();
explainBasics(period, builder, currency, paymentDate);
if (paymentDate.isBefore(discountFactors.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, discountFactors.getDiscountFactors()
.discountFactorWithSpread(paymentDate, zSpread, compoundedRateType, periodsPerYear));
builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, discountFactors)));
builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency,
presentValueWithSpread(period, discountFactors, zSpread, compoundedRateType, periodsPerYear)));
}
}
// common parts of explain
private void explainBasics(FixedCouponBondPaymentPeriod period, ExplainMapBuilder builder, Currency currency,
LocalDate paymentDate) {
builder.put(ExplainKey.ENTRY_TYPE, "FixedCouponBondPaymentPeriod");
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.ACCRUAL_YEAR_FRACTION, period.getYearFraction());
builder.put(ExplainKey.DAYS, (int) DAYS.between(period.getStartDate(), period.getEndDate()));
}
}