//------------------------------------------------------------------------- private CurrencyAmount presentValuePayment(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider) { RepoCurveDiscountFactors repoDf = DiscountingFixedCouponBondProductPricer.repoCurveDf(trade.Product, provider); Payment upfrontPayment = this.upfrontPayment(trade); return(paymentPricer.presentValue(upfrontPayment, repoDf.DiscountFactors)); }
/// <summary> /// Calculates the present value of the settlement of the bond trade from the clean price with z-spread. /// <para> /// Since the sign of the settlement notional is opposite to that of the product, negative amount will be returned /// for positive quantity of trade. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic /// compounded rates of the discounting curve. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="discountingProvider"> the discount factors provider </param> /// <param name="refData"> the reference data used to calculate the settlement date </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <param name="cleanRealPrice"> the clean real price </param> /// <returns> the present value of the settlement </returns> public virtual CurrencyAmount presentValueFromCleanPriceWithZSpread(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate valuationDate = ratesProvider.ValuationDate; ResolvedCapitalIndexedBond bond = trade.Product; 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))); }
/// <summary> /// Calculates the present value of the fixed coupon bond trade with z-spread from the /// clean price of the underlying product. /// <para> /// The present value of the trade is the value on the valuation date. /// The result is expressed using the payment currency of the bond. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic /// compounded rates of the discounting curve. /// </para> /// <para> /// Coupon payments of the underlying product are considered based on the settlement date of the trade. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="provider"> the discounting provider </param> /// <param name="refData"> the reference data used to calculate the settlement date </param> /// <param name="cleanPrice"> the clean price </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <returns> the present value of the fixed coupon bond trade </returns> public virtual CurrencyAmount presentValueFromCleanPriceWithZSpread(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider, ReferenceData refData, double cleanPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { ResolvedFixedCouponBond product = trade.Product; LocalDate standardSettlementDate = this.standardSettlementDate(product, provider, refData); LocalDate tradeSettlementDate = settlementDate(trade, provider.ValuationDate); Currency currency = product.Currency; RepoCurveDiscountFactors repoDf = DiscountingFixedCouponBondProductPricer.repoCurveDf(product, provider); double df = repoDf.discountFactor(standardSettlementDate); double pvStandard = (cleanPrice * product.Notional + productPricer.accruedInterest(product, standardSettlementDate)) * df; if (standardSettlementDate.isEqual(tradeSettlementDate)) { return(presentValueFromProductPresentValue(trade, provider, CurrencyAmount.of(currency, pvStandard))); } // check coupon payment between two settlement dates IssuerCurveDiscountFactors issuerDf = DiscountingFixedCouponBondProductPricer.issuerCurveDf(product, provider); double pvDiff = 0d; if (standardSettlementDate.isAfter(tradeSettlementDate)) { pvDiff = productPricer.presentValueCouponWithZSpread(product, issuerDf, tradeSettlementDate, standardSettlementDate, zSpread, compoundedRateType, periodsPerYear); } else { pvDiff = -productPricer.presentValueCouponWithZSpread(product, issuerDf, standardSettlementDate, tradeSettlementDate, zSpread, compoundedRateType, periodsPerYear); } return(presentValueFromProductPresentValue(trade, provider, CurrencyAmount.of(currency, pvStandard + pvDiff))); }
/// <summary> /// Calculates the present value sensitivity of the settlement of the bond trade from the real clean price /// with z-spread. /// <para> /// The present value sensitivity of the settlement is the sensitivity of the present value to /// the underlying curves. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="refData"> the reference data used to calculate the settlement date </param> /// <param name="discountingProvider"> the discount factors provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <param name="cleanRealPrice"> the clean real price </param> /// <returns> the present value sensitivity of the settlement </returns> public virtual PointSensitivities presentValueSensitivityFromCleanPriceWithZSpread(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider, ReferenceData refData, double cleanRealPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { validate(ratesProvider, discountingProvider); LocalDate valuationDate = ratesProvider.ValuationDate; ResolvedCapitalIndexedBond bond = trade.Product; 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).Amount)); 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()); }
public virtual void test_zeroRatePointSensitivity_USD() { RepoCurveDiscountFactors @base = RepoCurveDiscountFactors.of(DSC_FACTORS, GROUP); RepoCurveZeroRateSensitivity expected = RepoCurveZeroRateSensitivity.of(DSC_FACTORS.zeroRatePointSensitivity(DATE_AFTER, USD), GROUP); RepoCurveZeroRateSensitivity computed = @base.zeroRatePointSensitivity(DATE_AFTER, USD); assertEquals(computed, expected); }
public virtual void test_of() { RepoCurveDiscountFactors test = RepoCurveDiscountFactors.of(DSC_FACTORS, GROUP); assertEquals(test.RepoGroup, GROUP); assertEquals(test.Currency, GBP); assertEquals(test.ValuationDate, DATE); assertEquals(test.discountFactor(DATE_AFTER), DSC_FACTORS.discountFactor(DATE_AFTER)); }
//------------------------------------------------------------------------- public virtual void coverage() { RepoCurveDiscountFactors test1 = RepoCurveDiscountFactors.of(DSC_FACTORS, GROUP); coverImmutableBean(test1); RepoCurveDiscountFactors test2 = RepoCurveDiscountFactors.of(ZeroRateDiscountFactors.of(USD, DATE, CURVE), RepoGroup.of("ISSUER2")); coverBeanEquals(test1, test2); }
public virtual void test_builder_noValuationDate() { ImmutableLegalEntityDiscountingProvider test = ImmutableLegalEntityDiscountingProvider.builder().issuerCurves(ImmutableMap.of(Pair.of(GROUP_ISSUER, GBP), DSC_FACTORS_ISSUER)).issuerCurveGroups(ImmutableMap.of(ID_ISSUER, GROUP_ISSUER)).repoCurves(ImmutableMap.of(Pair.of(GROUP_REPO_ISSUER, GBP), DSC_FACTORS_REPO)).repoCurveGroups(ImmutableMap.of(ID_ISSUER, GROUP_REPO_ISSUER)).build(); assertEquals(test.issuerCurveDiscountFactors(ID_ISSUER, GBP), IssuerCurveDiscountFactors.of(DSC_FACTORS_ISSUER, GROUP_ISSUER)); assertEquals(test.repoCurveDiscountFactors(ID_SECURITY, ID_ISSUER, GBP), RepoCurveDiscountFactors.of(DSC_FACTORS_REPO, GROUP_REPO_ISSUER)); assertEquals(test.repoCurveDiscountFactors(ID_ISSUER, GBP), RepoCurveDiscountFactors.of(DSC_FACTORS_REPO, GROUP_REPO_ISSUER)); assertEquals(test.ValuationDate, DATE); }
public virtual void test_parameterSensitivity() { RepoCurveDiscountFactors @base = RepoCurveDiscountFactors.of(DSC_FACTORS, GROUP); RepoCurveZeroRateSensitivity sensi = @base.zeroRatePointSensitivity(DATE_AFTER, USD); CurrencyParameterSensitivities computed = @base.parameterSensitivity(sensi); CurrencyParameterSensitivities expected = DSC_FACTORS.parameterSensitivity(DSC_FACTORS.zeroRatePointSensitivity(DATE_AFTER, USD)); assertEquals(computed, expected); }
// lookup the discount factors for the repo group private RepoCurveDiscountFactors repoCurveDiscountFactors(RepoGroup repoGroup, Currency currency) { DiscountFactors discountFactors = repoCurves.get(Pair.of(repoGroup, currency)); if (discountFactors == null) { throw new System.ArgumentException("Unable to find repo curve: " + repoGroup + ", " + currency); } return(RepoCurveDiscountFactors.of(discountFactors, repoGroup)); }
/// <summary> /// Calculates the price for settlement at a given settlement date using curves with z-spread. /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or /// periodic compounded rates of the issuer discounting curve. /// </para> /// <para> /// The z-spread is applied only on the legal entity curve, not on the repo curve. /// /// </para> /// </summary> /// <param name="bill"> the bill </param> /// <param name="provider"> the discounting provider </param> /// <param name="settlementDate"> the settlement date </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <returns> the price </returns> public virtual double priceFromCurvesWithZSpread(ResolvedBill bill, LegalEntityDiscountingProvider provider, LocalDate settlementDate, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { ArgChecker.inOrderNotEqual(settlementDate, bill.Notional.Date, "settlementDate", "endDate"); ArgChecker.inOrderOrEqual(provider.ValuationDate, settlementDate, "valuationDate", "settlementDate"); IssuerCurveDiscountFactors issuerDf = issuerCurveDf(bill, provider); double dfMaturity = issuerDf.DiscountFactors.discountFactorWithSpread(bill.Notional.Date, zSpread, compoundedRateType, periodsPerYear); RepoCurveDiscountFactors repoDf = repoCurveDf(bill, provider); double dfRepoSettle = repoDf.discountFactor(settlementDate); return(dfMaturity / dfRepoSettle); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the price for settlement at a given settlement date using curves. /// </summary> /// <param name="bill"> the bill </param> /// <param name="provider"> the discounting provider </param> /// <param name="settlementDate"> the settlement date </param> /// <returns> the price </returns> public virtual double priceFromCurves(ResolvedBill bill, LegalEntityDiscountingProvider provider, LocalDate settlementDate) { ArgChecker.inOrderNotEqual(settlementDate, bill.Notional.Date, "settlementDate", "endDate"); ArgChecker.inOrderOrEqual(provider.ValuationDate, settlementDate, "valuationDate", "settlementDate"); IssuerCurveDiscountFactors issuerDf = issuerCurveDf(bill, provider); double dfMaturity = issuerDf.discountFactor(bill.Notional.Date); RepoCurveDiscountFactors repoDf = repoCurveDf(bill, provider); double dfRepoSettle = repoDf.discountFactor(settlementDate); return(dfMaturity / dfRepoSettle); }
private PointSensitivityBuilder presentValueSensitivityPayment(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider) { RepoCurveDiscountFactors repoDf = DiscountingFixedCouponBondProductPricer.repoCurveDf(trade.Product, provider); Payment upfrontPayment = this.upfrontPayment(trade); PointSensitivityBuilder pt = paymentPricer.presentValueSensitivity(upfrontPayment, repoDf.DiscountFactors); if (pt is ZeroRateSensitivity) { return(RepoCurveZeroRateSensitivity.of((ZeroRateSensitivity)pt, repoDf.RepoGroup)); } return(pt); // NoPointSensitivity }
//----------------------------------------------------------------------- public override bool Equals(object obj) { if (obj == this) { return(true); } if (obj != null && obj.GetType() == this.GetType()) { RepoCurveDiscountFactors other = (RepoCurveDiscountFactors)obj; return(JodaBeanUtils.equal(discountFactors, other.discountFactors) && JodaBeanUtils.equal(repoGroup, other.repoGroup)); } return(false); }
//------------------------------------------------------------------------- private CurrencyAmount presentValueSettlement(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { if (!trade.Settlement.Present) { // position has no settlement, thus it has no value return(CurrencyAmount.zero(trade.Product.Currency)); } BondPaymentPeriod settlePeriod = trade.Settlement.get().Payment; ResolvedCapitalIndexedBond product = trade.Product; CurrencyAmount netAmount = this.netAmount(trade, ratesProvider); RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(product, discountingProvider); return(netAmount.multipliedBy(repoDf.discountFactor(settlePeriod.PaymentDate))); }
/// <summary> /// Calculates the present value of a bill trade with z-spread. /// <para> /// If the settlement details are provided, the present value is the sum of the underlying product's present value /// multiplied by the quantity and the present value of the settlement payment if still due at the valuation date. /// If not it is the underlying product's present value multiplied by the quantity. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates of /// the issuer discounting curve. The z-spread is applied only on the legal entity curve, not on the repo curve used /// for the settlement amount. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="provider"> the discounting provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <returns> the present value </returns> public virtual CurrencyAmount presentValueWithZSpread(ResolvedBillTrade trade, LegalEntityDiscountingProvider provider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { if (provider.ValuationDate.isAfter(trade.Product.Notional.Date)) { return(CurrencyAmount.of(trade.Product.Currency, 0.0d)); } CurrencyAmount pvProduct = productPricer.presentValueWithZSpread(trade.Product, provider, zSpread, compoundedRateType, periodsPerYear).multipliedBy(trade.Quantity); if (trade.Settlement.Present) { RepoCurveDiscountFactors repoDf = DiscountingBillProductPricer.repoCurveDf(trade.Product, provider); CurrencyAmount pvSettle = paymentPricer.presentValue(trade.Settlement.get(), repoDf.DiscountFactors); return(pvProduct.plus(pvSettle)); } return(pvProduct); }
// the sensitivity of the present value of the settlement private PointSensitivityBuilder presentValueSensitivitySettlement(ResolvedCapitalIndexedBondTrade trade, RatesProvider ratesProvider, LegalEntityDiscountingProvider discountingProvider) { if (!trade.Settlement.Present) { // position has no settlement, thus it has no sensitivity return(PointSensitivityBuilder.none()); } ResolvedCapitalIndexedBondSettlement settlement = trade.Settlement.get(); BondPaymentPeriod settlePeriod = settlement.Payment; ResolvedCapitalIndexedBond product = trade.Product; RepoCurveDiscountFactors repoDf = DiscountingCapitalIndexedBondProductPricer.repoCurveDf(product, discountingProvider); double df = repoDf.discountFactor(settlePeriod.PaymentDate); double netAmount = this.netAmount(trade, ratesProvider).Amount; PointSensitivityBuilder dfSensi = repoDf.zeroRatePointSensitivity(settlePeriod.PaymentDate).multipliedBy(netAmount); PointSensitivityBuilder naSensi = netAmountSensitivity(settlement, ratesProvider).multipliedBy(df); return(dfSensi.combinedWith(naSensi)); }
/// <summary> /// Calculates the present value sensitivity of a bill trade with z-spread. /// <para> /// If the settlement details are provided, the sensitivity is the sum of the underlying product's sensitivity /// multiplied by the quantity and the sensitivity of the settlement payment if still due at the valuation date. /// If not it is the underlying product's sensitivity multiplied by the quantity. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic compounded rates of /// the issuer discounting curve. The z-spread is applied only on the legal entity curve, not on the repo curve used /// for the settlement amount. /// /// </para> /// </summary> /// <param name="trade"> the trade </param> /// <param name="provider"> the discounting provider </param> /// <param name="zSpread"> the z-spread </param> /// <param name="compoundedRateType"> the compounded rate type </param> /// <param name="periodsPerYear"> the number of periods per year </param> /// <returns> the present value sensitivity </returns> public virtual PointSensitivities presentValueSensitivityWithZSpread(ResolvedBillTrade trade, LegalEntityDiscountingProvider provider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { if (provider.ValuationDate.isAfter(trade.Product.Notional.Date)) { return(PointSensitivities.empty()); } PointSensitivities sensiProduct = productPricer.presentValueSensitivityWithZSpread(trade.Product, provider, zSpread, compoundedRateType, periodsPerYear).multipliedBy(trade.Quantity); if (!trade.Settlement.Present) { return(sensiProduct); } Payment settlement = trade.Settlement.get(); RepoCurveDiscountFactors repoDf = DiscountingBillProductPricer.repoCurveDf(trade.Product, provider); PointSensitivities sensiSettle = presentValueSensitivitySettlement(settlement, repoDf); return(sensiProduct.combinedWith(sensiSettle)); }
//------------------------------------------------------------------------- public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities) { CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty(); foreach (PointSensitivity point in pointSensitivities.Sensitivities) { if (point is RepoCurveZeroRateSensitivity) { RepoCurveZeroRateSensitivity pt = (RepoCurveZeroRateSensitivity)point; RepoCurveDiscountFactors factors = repoCurveDiscountFactors(pt.RepoGroup, pt.CurveCurrency); sens = sens.combinedWith(factors.parameterSensitivity(pt)); } else if (point is IssuerCurveZeroRateSensitivity) { IssuerCurveZeroRateSensitivity pt = (IssuerCurveZeroRateSensitivity)point; IssuerCurveDiscountFactors factors = issuerCurveDiscountFactors(pt.LegalEntityGroup, pt.CurveCurrency); sens = sens.combinedWith(factors.parameterSensitivity(pt)); } } return(sens); }
//------------------------------------------------------------------------- private PointSensitivities presentValueSensitivitySettlement(Payment settlement, RepoCurveDiscountFactors repoDf) { PointSensitivityBuilder pointSettle = paymentPricer.presentValueSensitivity(settlement, repoDf.DiscountFactors); if (pointSettle is ZeroRateSensitivity) { return(RepoCurveZeroRateSensitivity.of((ZeroRateSensitivity)pointSettle, repoDf.RepoGroup).build()); } return(pointSettle.build()); // NoPointSensitivity }