All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.opengamma.strata.pricer.bond.DiscountingCapitalIndexedBondTradePricer Maven / Gradle / Ivy

There is a newer version: 2.12.46
Show newest version
/*
 * Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.strata.pricer.bond;

import java.time.LocalDate;

import com.opengamma.strata.basics.ReferenceData;
import com.opengamma.strata.basics.currency.CurrencyAmount;
import com.opengamma.strata.basics.currency.MultiCurrencyAmount;
import com.opengamma.strata.basics.currency.Payment;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.market.sensitivity.PointSensitivities;
import com.opengamma.strata.market.sensitivity.PointSensitivityBuilder;
import com.opengamma.strata.pricer.CompoundedRateType;
import com.opengamma.strata.pricer.rate.RatesProvider;
import com.opengamma.strata.product.bond.BondPaymentPeriod;
import com.opengamma.strata.product.bond.CapitalIndexedBondPaymentPeriod;
import com.opengamma.strata.product.bond.CapitalIndexedBondYieldConvention;
import com.opengamma.strata.product.bond.KnownAmountBondPaymentPeriod;
import com.opengamma.strata.product.bond.ResolvedCapitalIndexedBond;
import com.opengamma.strata.product.bond.ResolvedCapitalIndexedBondSettlement;
import com.opengamma.strata.product.bond.ResolvedCapitalIndexedBondTrade;

/**
 * Pricer for for capital index bond trades.
 * 

* This function provides the ability to price a {@link ResolvedCapitalIndexedBondTrade}. * *

Price

* Strata uses decimal prices for bonds in the trade model, pricers and market data. * For example, a price of 99.32% is represented in Strata by 0.9932. */ public class DiscountingCapitalIndexedBondTradePricer { /** * Default implementation. */ public static final DiscountingCapitalIndexedBondTradePricer DEFAULT = new DiscountingCapitalIndexedBondTradePricer(DiscountingCapitalIndexedBondProductPricer.DEFAULT); /** * Pricer for {@link ResolvedCapitalIndexedBond}. */ private final DiscountingCapitalIndexedBondProductPricer productPricer; /** * Creates an instance. * * @param productPricer pricer for {@link ResolvedCapitalIndexedBond} */ public DiscountingCapitalIndexedBondTradePricer(DiscountingCapitalIndexedBondProductPricer productPricer) { this.productPricer = ArgChecker.notNull(productPricer, "productPricer"); } //------------------------------------------------------------------------- /** * Gets the capital indexed bond product pricer. * * @return the product pricer */ public DiscountingCapitalIndexedBondProductPricer getProductPricer() { return productPricer; } //------------------------------------------------------------------------- /** * Calculates the present value of the bond trade. *

* The present value of the trade is the value on the valuation date. * The result is expressed using the payment currency of the bond. *

* Coupon payments of the underlying product are considered based on the settlement date of the trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @return the present value of the bond trade */ public CurrencyAmount presentValue( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { validate(ratesProvider, discountingProvider); LocalDate settlementDate = settlementDate(trade, ratesProvider.getValuationDate()); CurrencyAmount pvProduct = productPricer.presentValue(trade.getProduct(), ratesProvider, discountingProvider, settlementDate); return presentValueFromProductPresentValue(trade, ratesProvider, discountingProvider, pvProduct); } /** * Calculates the present value of the bond trade with z-spread. *

* The present value of the trade is the value on the valuation date. * The result is expressed using the payment currency of the bond. *

* The z-spread is a parallel shift applied to continuously compounded rates or periodic * compounded rates of the discounting curve. *

* Coupon payments of the underlying product are considered based on the settlement date of the trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors 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 bond trade */ public CurrencyAmount presentValueWithZSpread( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate settlementDate = settlementDate(trade, ratesProvider.getValuationDate()); CurrencyAmount pvProduct = productPricer.presentValueWithZSpread( trade.getProduct(), ratesProvider, discountingProvider, settlementDate, zSpread, compoundedRateType, periodsPerYear); return presentValueFromProductPresentValue(trade, ratesProvider, discountingProvider, pvProduct); } //------------------------------------------------------------------------- /** * Calculates the present value sensitivity of the bond trade. *

* The present value sensitivity of the trade is the sensitivity of the present value to * the underlying curves. *

* Coupon payments of the underlying product are considered based on the settlement date of the trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @return the present value sensitivity of the bond trade */ public PointSensitivities presentValueSensitivity( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { validate(ratesProvider, discountingProvider); LocalDate settlementDate = settlementDate(trade, ratesProvider.getValuationDate()); PointSensitivityBuilder productSensi = productPricer.presentValueSensitivity(trade.getProduct(), ratesProvider, discountingProvider, settlementDate); return presentValueSensitivityFromProductPresentValueSensitivity( trade, ratesProvider, discountingProvider, productSensi).build(); } /** * Calculates the present value sensitivity of the bond trade with z-spread. *

* The present value sensitivity of the trade is the sensitivity of the present value to * the underlying curves. *

* Coupon payments of the underlying product are considered based on the settlement date of the trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodsPerYear the number of periods per year * @return the present value sensitivity of the bond trade */ public PointSensitivities presentValueSensitivityWithZSpread( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate settlementDate = settlementDate(trade, ratesProvider.getValuationDate()); PointSensitivityBuilder productSensi = productPricer.presentValueSensitivityWithZSpread(trade.getProduct(), ratesProvider, discountingProvider, settlementDate, zSpread, compoundedRateType, periodsPerYear); return presentValueSensitivityFromProductPresentValueSensitivity( trade, ratesProvider, discountingProvider, productSensi).build(); } //------------------------------------------------------------------------- /** * Calculates the present value of the bond trade from the clean price. *

* Since the sign of the settlement notional is opposite to that of the product, negative amount will be returned * for positive quantity of trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param refData the reference data used to calculate the settlement date * @param discountingProvider the discount factors provider * @param cleanRealPrice the clean real price * @return the present value of the settlement */ public CurrencyAmount presentValueFromCleanPrice( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice) { validate(ratesProvider, discountingProvider); LocalDate valuationDate = ratesProvider.getValuationDate(); ResolvedCapitalIndexedBond bond = trade.getProduct(); LocalDate standardSettlementDate = bond.calculateSettlementDateFromValuation(valuationDate, refData); LocalDate tradeSettlementDate = settlementDate(trade, valuationDate); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(bond, discountingProvider); double df = repoDf.discountFactor(standardSettlementDate); CurrencyAmount pvStandard = forecastValueStandardFromCleanPrice( bond, ratesProvider, standardSettlementDate, cleanRealPrice).multipliedBy(df); if (standardSettlementDate.isEqual(tradeSettlementDate)) { return presentValueFromProductPresentValue(trade, ratesProvider, discountingProvider, pvStandard); } // check coupon payment between two settlement dates IssuerCurveDiscountFactors issuerDf = DiscountingCapitalIndexedBondProductPricer.issuerCurveDf(bond, discountingProvider); double pvDiff = 0d; if (standardSettlementDate.isAfter(tradeSettlementDate)) { pvDiff = -productPricer.presentValueCoupon(bond, ratesProvider, issuerDf, tradeSettlementDate, standardSettlementDate); } else { pvDiff = productPricer.presentValueCoupon(bond, ratesProvider, issuerDf, standardSettlementDate, tradeSettlementDate); } return presentValueFromProductPresentValue( trade, ratesProvider, discountingProvider, pvStandard.plus(pvDiff)); } /** * Calculates the present value of the settlement of the bond trade from the clean price with z-spread. *

* Since the sign of the settlement notional is opposite to that of the product, negative amount will be returned * for positive quantity of trade. *

* The z-spread is a parallel shift applied to continuously compounded rates or periodic * compounded rates of the discounting curve. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @param refData the reference data used to calculate the settlement date * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodsPerYear the number of periods per year * @param cleanRealPrice the clean real price * @return the present value of the settlement */ public CurrencyAmount presentValueFromCleanPriceWithZSpread( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate valuationDate = ratesProvider.getValuationDate(); ResolvedCapitalIndexedBond bond = trade.getProduct(); LocalDate standardSettlementDate = bond.calculateSettlementDateFromValuation(valuationDate, refData); LocalDate tradeSettlementDate = settlementDate(trade, valuationDate); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(bond, discountingProvider); double df = repoDf.discountFactor(standardSettlementDate); CurrencyAmount pvStandard = forecastValueStandardFromCleanPrice( bond, ratesProvider, standardSettlementDate, cleanRealPrice).multipliedBy(df); if (standardSettlementDate.isEqual(tradeSettlementDate)) { return presentValueFromProductPresentValue(trade, ratesProvider, discountingProvider, pvStandard); } // check coupon payment between two settlement dates IssuerCurveDiscountFactors issuerDf = DiscountingCapitalIndexedBondProductPricer.issuerCurveDf(bond, discountingProvider); double pvDiff = 0d; if (standardSettlementDate.isAfter(tradeSettlementDate)) { pvDiff = -productPricer.presentValueCouponWithZSpread( bond, ratesProvider, issuerDf, tradeSettlementDate, standardSettlementDate, zSpread, compoundedRateType, periodsPerYear); } else { pvDiff = productPricer.presentValueCouponWithZSpread( bond, ratesProvider, issuerDf, standardSettlementDate, tradeSettlementDate, zSpread, compoundedRateType, periodsPerYear); } return presentValueFromProductPresentValue( trade, ratesProvider, discountingProvider, pvStandard.plus(pvDiff)); } //------------------------------------------------------------------------- /** * Calculates the present value sensitivity of the settlement of the bond trade from the real clean price. *

* The present value sensitivity of the settlement is the sensitivity of the present value to * the underlying curves. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param refData the reference data used to calculate the settlement date * @param discountingProvider the discount factors provider * @param cleanRealPrice the clean real price * @return the present value sensitivity of the settlement */ public PointSensitivities presentValueSensitivityFromCleanPrice( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice) { validate(ratesProvider, discountingProvider); LocalDate valuationDate = ratesProvider.getValuationDate(); ResolvedCapitalIndexedBond bond = trade.getProduct(); LocalDate standardSettlementDate = bond.calculateSettlementDateFromValuation(valuationDate, refData); LocalDate tradeSettlementDate = settlementDate(trade, valuationDate); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(bond, discountingProvider); double df = repoDf.discountFactor(standardSettlementDate); PointSensitivityBuilder dfSensi = repoDf.zeroRatePointSensitivity(standardSettlementDate); PointSensitivityBuilder pvSensiStandard = forecastValueSensitivityStandardFromCleanPrice(bond, ratesProvider, standardSettlementDate, cleanRealPrice).multipliedBy(df).combinedWith(dfSensi.multipliedBy( forecastValueStandardFromCleanPrice(bond, ratesProvider, standardSettlementDate, cleanRealPrice) .getAmount())); if (standardSettlementDate.isEqual(tradeSettlementDate)) { return presentValueSensitivityFromProductPresentValueSensitivity( trade, ratesProvider, discountingProvider, pvSensiStandard).build(); } // check coupon payment between two settlement dates IssuerCurveDiscountFactors issuerDf = DiscountingCapitalIndexedBondProductPricer.issuerCurveDf(bond, discountingProvider); PointSensitivityBuilder pvSensiDiff = PointSensitivityBuilder.none(); if (standardSettlementDate.isAfter(tradeSettlementDate)) { pvSensiDiff = pvSensiDiff.combinedWith(productPricer.presentValueSensitivityCoupon(bond, ratesProvider, issuerDf, tradeSettlementDate, standardSettlementDate).multipliedBy(-1d)); } else { pvSensiDiff = pvSensiDiff.combinedWith(productPricer.presentValueSensitivityCoupon(bond, ratesProvider, issuerDf, standardSettlementDate, tradeSettlementDate)); } return presentValueSensitivityFromProductPresentValueSensitivity( trade, ratesProvider, discountingProvider, pvSensiStandard.combinedWith(pvSensiDiff)).build(); } /** * Calculates the present value sensitivity of the settlement of the bond trade from the real clean price * with z-spread. *

* The present value sensitivity of the settlement is the sensitivity of the present value to * the underlying curves. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param refData the reference data used to calculate the settlement date * @param discountingProvider the discount factors provider * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodsPerYear the number of periods per year * @param cleanRealPrice the clean real price * @return the present value sensitivity of the settlement */ public PointSensitivities presentValueSensitivityFromCleanPriceWithZSpread( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate valuationDate = ratesProvider.getValuationDate(); ResolvedCapitalIndexedBond bond = trade.getProduct(); LocalDate standardSettlementDate = bond.calculateSettlementDateFromValuation(valuationDate, refData); LocalDate tradeSettlementDate = settlementDate(trade, valuationDate); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(bond, discountingProvider); double df = repoDf.discountFactor(standardSettlementDate); PointSensitivityBuilder dfSensi = repoDf.zeroRatePointSensitivity(standardSettlementDate); PointSensitivityBuilder pvSensiStandard = forecastValueSensitivityStandardFromCleanPrice(bond, ratesProvider, standardSettlementDate, cleanRealPrice).multipliedBy(df).combinedWith(dfSensi.multipliedBy( forecastValueStandardFromCleanPrice(bond, ratesProvider, standardSettlementDate, cleanRealPrice) .getAmount())); if (standardSettlementDate.isEqual(tradeSettlementDate)) { return presentValueSensitivityFromProductPresentValueSensitivity( trade, ratesProvider, discountingProvider, pvSensiStandard).build(); } // check coupon payment between two settlement dates IssuerCurveDiscountFactors issuerDf = DiscountingCapitalIndexedBondProductPricer.issuerCurveDf(bond, discountingProvider); PointSensitivityBuilder pvSensiDiff = PointSensitivityBuilder.none(); if (standardSettlementDate.isAfter(tradeSettlementDate)) { pvSensiDiff = pvSensiDiff.combinedWith(productPricer.presentValueSensitivityCouponWithZSpread( bond, ratesProvider, issuerDf, tradeSettlementDate, standardSettlementDate, zSpread, compoundedRateType, periodsPerYear) .multipliedBy(-1d)); } else { pvSensiDiff = pvSensiDiff.combinedWith(productPricer.presentValueSensitivityCouponWithZSpread( bond, ratesProvider, issuerDf, standardSettlementDate, tradeSettlementDate, zSpread, compoundedRateType, periodsPerYear)); } return presentValueSensitivityFromProductPresentValueSensitivity( trade, ratesProvider, discountingProvider, pvSensiStandard.combinedWith(pvSensiDiff)).build(); } //------------------------------------------------------------------------- /** * Calculates the currency exposure of the bond trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @param refData the reference data used to calculate the settlement date * @param cleanRealPrice the clean real price * @return the currency exposure of the trade */ public MultiCurrencyAmount currencyExposureFromCleanPrice( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice) { CurrencyAmount pv = presentValueFromCleanPrice( trade, ratesProvider, discountingProvider, refData, cleanRealPrice); return MultiCurrencyAmount.of(pv); } /** * Calculates the currency exposure of the bond trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @return the currency exposure of the trade */ public MultiCurrencyAmount currencyExposure( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { CurrencyAmount pv = presentValue(trade, ratesProvider, discountingProvider); return MultiCurrencyAmount.of(pv); } /** * Calculates the currency exposure of the bond trade with z-spread. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @param refData the reference data used to calculate the settlement date * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodsPerYear the number of periods per year * @param cleanRealPrice the clean real price * @return the currency exposure of the trade */ public MultiCurrencyAmount currencyExposureFromCleanPriceWithZSpread( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { CurrencyAmount pv = presentValueFromCleanPriceWithZSpread( trade, ratesProvider, discountingProvider, refData, cleanRealPrice, zSpread, compoundedRateType, periodsPerYear); return MultiCurrencyAmount.of(pv); } /** * Calculates the currency exposure of the bond trade with z-spread. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @param discountingProvider the discount factors provider * @param zSpread the z-spread * @param compoundedRateType the compounded rate type * @param periodsPerYear the number of periods per year * @return the currency exposure of the trade */ public MultiCurrencyAmount currencyExposureWithZSpread( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { CurrencyAmount pv = presentValueWithZSpread( trade, ratesProvider, discountingProvider, zSpread, compoundedRateType, periodsPerYear); return MultiCurrencyAmount.of(pv); } /** * Calculates the current cash of the bond trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @return the current cash */ public CurrencyAmount currentCash( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider) { LocalDate valuationDate = ratesProvider.getValuationDate(); LocalDate settlementDate = settlementDate(trade, valuationDate); CurrencyAmount cashProduct = productPricer.currentCash(trade.getProduct(), ratesProvider, settlementDate); if (!trade.getSettlement().isPresent()) { return cashProduct; } BondPaymentPeriod settlePeriod = trade.getSettlement().get().getPayment(); double cashSettle = settlePeriod.getPaymentDate().isEqual(valuationDate) ? netAmount(trade, ratesProvider).getAmount() : 0d; return cashProduct.plus(cashSettle); } //------------------------------------------------------------------------- /** * Calculates the net amount of the settlement of the bond trade. *

* Since the sign of the settlement notional is opposite to that of the product, negative amount will be returned * for positive quantity of trade. * * @param trade the trade * @param ratesProvider the rates provider, used to determine price index values * @return the net amount */ public CurrencyAmount netAmount( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider) { if (!trade.getSettlement().isPresent()) { // position has no settlement, thus it has no value return CurrencyAmount.zero(trade.getProduct().getCurrency()); } BondPaymentPeriod settlePeriod = trade.getSettlement().get().getPayment(); if (settlePeriod instanceof KnownAmountBondPaymentPeriod) { Payment payment = ((KnownAmountBondPaymentPeriod) settlePeriod).getPayment(); return payment.getValue(); } else if (settlePeriod instanceof CapitalIndexedBondPaymentPeriod) { CapitalIndexedBondPaymentPeriod casted = (CapitalIndexedBondPaymentPeriod) settlePeriod; double netAmount = productPricer.getPeriodPricer().forecastValue(casted, ratesProvider); return CurrencyAmount.of(casted.getCurrency(), netAmount); } throw new UnsupportedOperationException("unsupported settlement type"); } //------------------------------------------------------------------------- private CurrencyAmount presentValueSettlement( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { if (!trade.getSettlement().isPresent()) { // position has no settlement, thus it has no value return CurrencyAmount.zero(trade.getProduct().getCurrency()); } BondPaymentPeriod settlePeriod = trade.getSettlement().get().getPayment(); ResolvedCapitalIndexedBond product = trade.getProduct(); CurrencyAmount netAmount = netAmount(trade, ratesProvider); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(product, discountingProvider); return netAmount.multipliedBy(repoDf.discountFactor(settlePeriod.getPaymentDate())); } private CurrencyAmount presentValueFromProductPresentValue( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, CurrencyAmount productPresentValue) { CurrencyAmount pvProduct = productPresentValue.multipliedBy(trade.getQuantity()); CurrencyAmount pvPayment = presentValueSettlement(trade, ratesProvider, discountingProvider); return pvProduct.plus(pvPayment); } CurrencyAmount forecastValueStandardFromCleanPrice( ResolvedCapitalIndexedBond product, RatesProvider ratesProvider, LocalDate standardSettlementDate, double realCleanPrice) { double notional = product.getNotional(); double netAmountReal = realCleanPrice * notional + product.accruedInterest(standardSettlementDate); double indexRatio = product.getYieldConvention().equals(CapitalIndexedBondYieldConvention.GB_IL_FLOAT) ? 1d : productPricer.indexRatio(product, ratesProvider, standardSettlementDate); return CurrencyAmount.of(product.getCurrency(), indexRatio * netAmountReal); } //------------------------------------------------------------------------- // the sensitivity of the product plus settlement private PointSensitivityBuilder presentValueSensitivityFromProductPresentValueSensitivity( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, PointSensitivityBuilder productPresnetValueSensitivity) { PointSensitivityBuilder sensiProduct = productPresnetValueSensitivity.multipliedBy(trade.getQuantity()); PointSensitivityBuilder sensiPayment = presentValueSensitivitySettlement(trade, ratesProvider, discountingProvider); return sensiProduct.combinedWith(sensiPayment); } // the sensitivity of the present value of the settlement private PointSensitivityBuilder presentValueSensitivitySettlement( ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { if (!trade.getSettlement().isPresent()) { // position has no settlement, thus it has no sensitivity return PointSensitivityBuilder.none(); } ResolvedCapitalIndexedBondSettlement settlement = trade.getSettlement().get(); BondPaymentPeriod settlePeriod = settlement.getPayment(); ResolvedCapitalIndexedBond product = trade.getProduct(); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(product, discountingProvider); double df = repoDf.discountFactor(settlePeriod.getPaymentDate()); double netAmount = netAmount(trade, ratesProvider).getAmount(); PointSensitivityBuilder dfSensi = repoDf.zeroRatePointSensitivity(settlePeriod.getPaymentDate()).multipliedBy(netAmount); PointSensitivityBuilder naSensi = netAmountSensitivity(settlement, ratesProvider).multipliedBy(df); return dfSensi.combinedWith(naSensi); } // the sensitivity of the net amount of the settlement private PointSensitivityBuilder netAmountSensitivity( ResolvedCapitalIndexedBondSettlement settlement, RatesProvider ratesProvider) { BondPaymentPeriod settlePeriod = settlement.getPayment(); if (settlePeriod instanceof KnownAmountBondPaymentPeriod) { return PointSensitivityBuilder.none(); } else if (settlePeriod instanceof CapitalIndexedBondPaymentPeriod) { CapitalIndexedBondPaymentPeriod casted = (CapitalIndexedBondPaymentPeriod) settlePeriod; return productPricer.getPeriodPricer().forecastValueSensitivity(casted, ratesProvider); } throw new UnsupportedOperationException("unsupported settlement type"); } // the sensitivity of the forecast value given the clean price PointSensitivityBuilder forecastValueSensitivityStandardFromCleanPrice( ResolvedCapitalIndexedBond product, RatesProvider ratesProvider, LocalDate standardSettlementDate, double realCleanPrice) { if (product.getYieldConvention().equals(CapitalIndexedBondYieldConvention.GB_IL_FLOAT)) { return PointSensitivityBuilder.none(); } double notional = product.getNotional(); double netAmountReal = realCleanPrice * notional + product.accruedInterest(standardSettlementDate); PointSensitivityBuilder indexRatioSensi = productPricer.indexRatioSensitivity(product, ratesProvider, standardSettlementDate); return indexRatioSensi.multipliedBy(netAmountReal); } //------------------------------------------------------------------------- /** * Calculates the settlement date. *

* The valuation date is returned if the settlement details are not stored. * * @param trade the trade * @param valuationDate the valuation date * @return the settlement date */ public LocalDate settlementDate(ResolvedCapitalIndexedBondTrade trade, LocalDate valuationDate) { return trade.getSettlement() .map(settle -> settle.getSettlementDate()) .orElse(valuationDate); } //------------------------------------------------------------------------- private void validate(RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { ArgChecker.isTrue(ratesProvider.getValuationDate().isEqual(discountingProvider.getValuationDate()), "the rates providers should be for the same date"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy