/// <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_builder_noRepoRate() { ImmutableLegalEntityDiscountingProvider test = ImmutableLegalEntityDiscountingProvider.builder().issuerCurveGroups(ImmutableMap.of(ID_ISSUER, GROUP_ISSUER)).issuerCurves(ImmutableMap.of(Pair.of(GROUP_ISSUER, GBP), DSC_FACTORS_ISSUER)).build(); assertEquals(test.issuerCurveDiscountFactors(ID_ISSUER, GBP), IssuerCurveDiscountFactors.of(DSC_FACTORS_ISSUER, GROUP_ISSUER)); assertEquals(test.ValuationDate, DATE); }
/// <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))); }
public virtual void test_zeroRatePointSensitivity_USD() { IssuerCurveDiscountFactors @base = IssuerCurveDiscountFactors.of(DSC_FACTORS, GROUP); IssuerCurveZeroRateSensitivity expected = IssuerCurveZeroRateSensitivity.of(DSC_FACTORS.zeroRatePointSensitivity(DATE_AFTER, USD), GROUP); IssuerCurveZeroRateSensitivity computed = @base.zeroRatePointSensitivity(DATE_AFTER, USD); assertEquals(computed, expected); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the forecast value of a single fixed coupon payment period. /// <para> /// The amount is expressed in the currency of the period. /// This returns the value of the period with discounting. /// </para> /// <para> /// 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. /// </para> /// <para> /// The forecast value is z-spread independent. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="discountFactors"> the discount factor provider </param> /// <returns> the present value of the period </returns> public virtual double forecastValue(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors) { if (period.PaymentDate.isBefore(discountFactors.ValuationDate)) { return(0d); } return(period.FixedRate * period.Notional * period.YearFraction); }
public virtual void test_of() { IssuerCurveDiscountFactors test = IssuerCurveDiscountFactors.of(DSC_FACTORS, GROUP); assertEquals(test.LegalEntityGroup, GROUP); assertEquals(test.Currency, GBP); assertEquals(test.ValuationDate, DATE); assertEquals(test.discountFactor(DATE_AFTER), DSC_FACTORS.discountFactor(DATE_AFTER)); }
public virtual void test_parameterSensitivity() { IssuerCurveDiscountFactors @base = IssuerCurveDiscountFactors.of(DSC_FACTORS, GROUP); IssuerCurveZeroRateSensitivity 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); }
//------------------------------------------------------------------------- public virtual void coverage() { IssuerCurveDiscountFactors test1 = IssuerCurveDiscountFactors.of(DSC_FACTORS, GROUP); coverImmutableBean(test1); IssuerCurveDiscountFactors test2 = IssuerCurveDiscountFactors.of(ZeroRateDiscountFactors.of(USD, DATE, CURVE), LegalEntityGroup.of("ISSUER2")); coverBeanEquals(test1, test2); }
//------------------------------------------------------------------------- public virtual void test_builder() { 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_SECURITY, GBP), DSC_FACTORS_REPO)).repoCurveSecurityGroups(ImmutableMap.of(ID_SECURITY, GROUP_REPO_SECURITY)).valuationDate(DATE).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_SECURITY)); assertThrowsIllegalArg(() => test.repoCurveDiscountFactors(ID_ISSUER, GBP)); assertEquals(test.ValuationDate, DATE); }
// lookup the discount factors for the legal entity group private IssuerCurveDiscountFactors issuerCurveDiscountFactors(LegalEntityGroup legalEntityGroup, Currency currency) { DiscountFactors discountFactors = issuerCurves.get(Pair.of(legalEntityGroup, currency)); if (discountFactors == null) { throw new System.ArgumentException("Unable to find issuer curve: " + legalEntityGroup + ", " + currency); } return(IssuerCurveDiscountFactors.of(discountFactors, legalEntityGroup)); }
/// <summary> /// Calculates the present value of a bill product 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> /// </summary> /// <param name="bill"> the product </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 of the bill product </returns> public virtual CurrencyAmount presentValueWithZSpread(ResolvedBill bill, LegalEntityDiscountingProvider provider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { if (provider.ValuationDate.isAfter(bill.Notional.Date)) { return(CurrencyAmount.of(bill.Currency, 0.0d)); } IssuerCurveDiscountFactors issuerDf = issuerCurveDf(bill, provider); double dfMaturity = issuerDf.DiscountFactors.discountFactorWithSpread(bill.Notional.Date, zSpread, compoundedRateType, periodsPerYear); return(bill.Notional.Value.multipliedBy(dfMaturity)); }
//------------------------------------------------------------------------- public virtual void presentValueSensitivity() { PointSensitivities sensiComputed = PRICER.presentValueSensitivity(BILL, PROVIDER); PointSensitivities sensiExpected = IssuerCurveDiscountFactors.of(DSC_FACTORS_ISSUER, GROUP_ISSUER).zeroRatePointSensitivity(MATURITY_DATE).multipliedBy(NOTIONAL.Amount).build(); assertTrue(sensiComputed.equalWithTolerance(sensiExpected, TOLERANCE_PV)); CurrencyParameterSensitivities paramSensiComputed = PROVIDER.parameterSensitivity(sensiComputed); CurrencyParameterSensitivities paramSensiExpected = FD_CALC.sensitivity(PROVIDER, p => PRICER.presentValue(BILL, p)); assertTrue(paramSensiComputed.equalWithTolerance(paramSensiExpected, EPS * NOTIONAL_AMOUNT)); }
/// <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 present value of the bill product. /// <para> /// The present value of the product is the value on the valuation date. /// The result is expressed using the payment currency of the bill. /// </para> /// <para> /// Coupon payments of the product are considered based on the valuation date. /// /// </para> /// </summary> /// <param name="bill"> the product </param> /// <param name="provider"> the discounting provider </param> /// <returns> the present value of the bill product </returns> public virtual CurrencyAmount presentValue(ResolvedBill bill, LegalEntityDiscountingProvider provider) { if (provider.ValuationDate.isAfter(bill.Notional.Date)) { return(CurrencyAmount.of(bill.Currency, 0.0d)); } IssuerCurveDiscountFactors issuerDf = issuerCurveDf(bill, provider); double dfMaturity = issuerDf.discountFactor(bill.Notional.Date); return(bill.Notional.Value.multipliedBy(dfMaturity)); }
//------------------------------------------------------------------------- /// <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); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of the bill product. /// <para> /// The present value sensitivity of the product is the sensitivity of the present value to /// the underlying curves. /// /// </para> /// </summary> /// <param name="bill"> the product </param> /// <param name="provider"> the discounting provider </param> /// <returns> the present value curve sensitivity of the product </returns> public virtual PointSensitivities presentValueSensitivity(ResolvedBill bill, LegalEntityDiscountingProvider provider) { if (provider.ValuationDate.isAfter(bill.Notional.Date)) { return(PointSensitivities.empty()); } IssuerCurveDiscountFactors issuerDf = issuerCurveDf(bill, provider); double dfEndBar = bill.Notional.Amount; PointSensitivityBuilder sensMaturity = issuerDf.zeroRatePointSensitivity(bill.Notional.Date).multipliedBy(dfEndBar); return(sensMaturity.build()); }
/// <summary> /// Calculates the present value sensitivity of the bill product with z-spread. /// <para> /// The present value sensitivity of the product is the sensitivity of the present value to /// the underlying curves. /// </para> /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or /// periodic compounded rates of the issuer discounting curve. /// /// </para> /// </summary> /// <param name="bill"> the product </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 curve sensitivity of the product </returns> public virtual PointSensitivities presentValueSensitivityWithZSpread(ResolvedBill bill, LegalEntityDiscountingProvider provider, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { if (provider.ValuationDate.isAfter(bill.Notional.Date)) { return(PointSensitivities.empty()); } IssuerCurveDiscountFactors issuerDf = issuerCurveDf(bill, provider); double dfEndBar = bill.Notional.Amount; ZeroRateSensitivity zeroSensMaturity = issuerDf.DiscountFactors.zeroRatePointSensitivityWithSpread(bill.Notional.Date, zSpread, compoundedRateType, periodsPerYear); IssuerCurveZeroRateSensitivity dscSensMaturity = IssuerCurveZeroRateSensitivity.of(zeroSensMaturity, issuerDf.LegalEntityGroup).multipliedBy(dfEndBar); return(dscSensMaturity.build()); }
//----------------------------------------------------------------------- public override bool Equals(object obj) { if (obj == this) { return(true); } if (obj != null && obj.GetType() == this.GetType()) { IssuerCurveDiscountFactors other = (IssuerCurveDiscountFactors)obj; return(JodaBeanUtils.equal(discountFactors, other.discountFactors) && JodaBeanUtils.equal(legalEntityGroup, other.legalEntityGroup)); } return(false); }
public virtual void test_presentValueWithZSpread_periodic_noExcoupon() { CurrencyAmount computed = PRICER.presentValueWithZSpread(PRODUCT_NO_EXCOUPON, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); CurrencyAmount expected = PRICER_NOMINAL.presentValueWithSpread(PRODUCT.NominalPayment, DSC_FACTORS_ISSUER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); int size = PRODUCT.PeriodicPayments.size(); double pvcCupon = 0d; for (int i = 2; i < size; ++i) { FixedCouponBondPaymentPeriod payment = PRODUCT.PeriodicPayments.get(i); pvcCupon += PRICER_COUPON.presentValueWithSpread(payment, IssuerCurveDiscountFactors.of(DSC_FACTORS_ISSUER, GROUP_ISSUER), Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); } expected = expected.plus(pvcCupon); assertEquals(computed.Currency, EUR); assertEquals(computed.Amount, expected.Amount, NOTIONAL * TOL); }
//------------------------------------------------------------------------- /// <summary> /// Explains the present value of a single fixed coupon payment period. /// <para> /// This adds information to the <seealso cref="ExplainMapBuilder"/> to aid understanding of the calculation. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="discountFactors"> the discount factor provider </param> /// <param name="builder"> the builder to populate </param> public virtual void explainPresentValue(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors, ExplainMapBuilder builder) { Currency currency = period.Currency; LocalDate paymentDate = period.PaymentDate; explainBasics(period, builder, currency, paymentDate); if (paymentDate.isBefore(discountFactors.ValuationDate)) { builder.put(ExplainKey.COMPLETED, 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))); } }
//------------------------------------------------------------------------- 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); }
/// <summary> /// Obtains issuer curve discount factors form valuation date. /// </summary> /// <param name="valuationDate"> the valuation date </param> /// <returns> the discount factors </returns> public static IssuerCurveDiscountFactors getIssuerCurveDiscountFactors(LocalDate valuationDate) { DiscountFactors dscIssuer = ZeroRateDiscountFactors.of(USD, valuationDate, ISSUER_CURVE); return(IssuerCurveDiscountFactors.of(dscIssuer, GROUP_ISSUER)); }
/// <summary> /// Explains the present value of a single payment period with z-spread. /// <para> /// This adds information to the <seealso cref="ExplainMapBuilder"/> to aid understanding of the calculation. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="issuerDiscountFactors"> the discount factor 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="builder"> the builder to populate </param> public virtual void explainPresentValueWithZSpread(CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors, ExplainMapBuilder builder, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { Currency currency = period.Currency; LocalDate paymentDate = period.PaymentDate; builder.put(ExplainKey.ENTRY_TYPE, "CapitalIndexedBondPaymentPeriod"); builder.put(ExplainKey.PAYMENT_DATE, paymentDate); builder.put(ExplainKey.PAYMENT_CURRENCY, currency); builder.put(ExplainKey.START_DATE, period.StartDate); builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate); builder.put(ExplainKey.END_DATE, period.EndDate); builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate); builder.put(ExplainKey.DAYS, (int)DAYS.between(period.UnadjustedStartDate, period.UnadjustedEndDate)); if (paymentDate.isBefore(ratesProvider.ValuationDate)) { builder.put(ExplainKey.COMPLETED, true); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency)); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency)); } else { builder.put(ExplainKey.DISCOUNT_FACTOR, issuerDiscountFactors.discountFactor(paymentDate)); builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, ratesProvider))); builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValueWithZSpread(period, ratesProvider, issuerDiscountFactors, zSpread, compoundedRateType, periodsPerYear))); } }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value of a single payment period. /// <para> /// This returns the value of the period with discounting. /// If the payment date of the period is in the past, zero is returned. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="issuerDiscountFactors"> the discount factor provider </param> /// <returns> the present value of the period </returns> public virtual double presentValue(CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors) { double df = issuerDiscountFactors.discountFactor(period.PaymentDate); return(df * forecastValue(period, ratesProvider)); }
/// <summary> /// Calculates the present value of a single payment period with z-spread. /// <para> /// This returns the value of the period with discounting. /// If the payment date of the period is in the past, zero is returned. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="ratesProvider"> the rates provider, used to determine price index values </param> /// <param name="issuerDiscountFactors"> the discount factor 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 of the period </returns> public virtual double presentValueWithZSpread(CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { double df = issuerDiscountFactors.DiscountFactors.discountFactorWithSpread(period.PaymentDate, zSpread, compoundedRateType, periodsPerYear); return(df * forecastValue(period, ratesProvider)); }
/// <summary> /// Calculates the present value of a single fixed coupon payment period with z-spread. /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic /// compounded rates of the discounting curve. /// </para> /// <para> /// The amount is expressed in the currency of the period. /// This returns the value of the period with discounting. /// </para> /// <para> /// 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. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="discountFactors"> the discount factor 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 of the period </returns> public virtual double presentValueWithSpread(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { if (period.PaymentDate.isBefore(discountFactors.ValuationDate)) { return(0d); } double df = discountFactors.DiscountFactors.discountFactorWithSpread(period.PaymentDate, zSpread, compoundedRateType, periodsPerYear); return(period.FixedRate * period.Notional * period.YearFraction * df); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the forecast value sensitivity of a single fixed coupon payment period. /// <para> /// The forecast value sensitivity of the period is the sensitivity of the forecast value to /// the underlying curves. /// </para> /// <para> /// The forecast value sensitivity is zero and z-spread independent for the fixed payment. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="discountFactors"> the discount factor provider </param> /// <returns> the forecast value curve sensitivity of the period </returns> public virtual PointSensitivityBuilder forecastValueSensitivity(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors) { return(PointSensitivityBuilder.none()); }
/// <summary> /// Calculates the present value sensitivity of a single fixed coupon payment period with z-spread. /// <para> /// The z-spread is a parallel shift applied to continuously compounded rates or periodic /// compounded rates of the discounting curve. /// </para> /// <para> /// The present value sensitivity of the period is the sensitivity of the present value to /// the underlying curves. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="discountFactors"> the discount factor 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 curve sensitivity of the period </returns> public virtual PointSensitivityBuilder presentValueSensitivityWithSpread(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { if (period.PaymentDate.isBefore(discountFactors.ValuationDate)) { return(PointSensitivityBuilder.none()); } ZeroRateSensitivity zeroSensi = discountFactors.DiscountFactors.zeroRatePointSensitivityWithSpread(period.PaymentDate, zSpread, compoundedRateType, periodsPerYear); IssuerCurveZeroRateSensitivity dscSensi = IssuerCurveZeroRateSensitivity.of(zeroSensi, discountFactors.LegalEntityGroup); return(dscSensi.multipliedBy(period.FixedRate * period.Notional * period.YearFraction)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the present value sensitivity of a single fixed coupon payment period. /// <para> /// The present value sensitivity of the period is the sensitivity of the present value to /// the underlying curves. /// /// </para> /// </summary> /// <param name="period"> the period to price </param> /// <param name="discountFactors"> the discount factor provider </param> /// <returns> the present value curve sensitivity of the period </returns> public virtual PointSensitivityBuilder presentValueSensitivity(FixedCouponBondPaymentPeriod period, IssuerCurveDiscountFactors discountFactors) { if (period.PaymentDate.isBefore(discountFactors.ValuationDate)) { return(PointSensitivityBuilder.none()); } IssuerCurveZeroRateSensitivity dscSensi = discountFactors.zeroRatePointSensitivity(period.PaymentDate); return(dscSensi.multipliedBy(period.FixedRate * period.Notional * period.YearFraction)); }