/** * Calculates the present value of a single payment period. * <p> * This returns the value of the period with discounting. * If the payment date of the period is in the past, zero is returned. * * @param period the period to price * @param ratesProvider the rates provider, used to determine price index values * @param issuerDiscountFactors the discount factor provider * @return the present value of the period */ public double presentValue( CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors) { double df = issuerDiscountFactors.discountFactor(period.getPaymentDate()); return df * forecastValue(period, ratesProvider); }
public void test_forecastValueSensitivity_afterFix() { PointSensitivityBuilder pointInterp = PRICER.forecastValueSensitivity(PERIOD_INTERP, IRP_AFTER_FIX); CurrencyParameterSensitivities computedInterp = IRP_AFTER_FIX.parameterSensitivity(pointInterp.build()); PointSensitivityBuilder pointMonthly = PRICER.forecastValueSensitivity(PERIOD_MONTHLY, IRP_AFTER_FIX); CurrencyParameterSensitivities computedMonthly = IRP_AFTER_FIX.parameterSensitivity(pointMonthly.build()); CurrencyParameterSensitivities expectedInterp = FD_CAL.sensitivity(IRP_AFTER_FIX, p -> CurrencyAmount.of(USD, PRICER.forecastValue(PERIOD_INTERP, p))); CurrencyParameterSensitivities expectedMonthly = FD_CAL.sensitivity(IRP_AFTER_FIX, p -> CurrencyAmount.of(USD, PRICER.forecastValue(PERIOD_MONTHLY, p))); assertTrue(computedInterp.equalWithTolerance(expectedInterp, NOTIONAL * FD_EPS)); assertTrue(computedMonthly.equalWithTolerance(expectedMonthly, NOTIONAL * FD_EPS)); }
private double currentCashPayment( ResolvedCapitalIndexedBond bond, RatesProvider ratesProvider, LocalDate valuationDate) { double cash = 0d; for (CapitalIndexedBondPaymentPeriod period : bond.getPeriodicPayments()) { if (period.getPaymentDate().isEqual(valuationDate)) { cash += periodPricer.forecastValue(period, ratesProvider); } } return cash; }
public void test_forecastValueSensitivity_onFix() { PointSensitivityBuilder pointInterp = PRICER.forecastValueSensitivity(PERIOD_INTERP, IRP_ON_FIX); CurrencyParameterSensitivities computedInterp = IRP_ON_FIX.parameterSensitivity(pointInterp.build()); PointSensitivityBuilder pointMonthly = PRICER.forecastValueSensitivity(PERIOD_MONTHLY, IRP_ON_FIX); CurrencyParameterSensitivities computedMonthly = IRP_ON_FIX.parameterSensitivity(pointMonthly.build()); CurrencyParameterSensitivities expectedInterp = FD_CAL.sensitivity(IRP_ON_FIX, p -> CurrencyAmount.of(USD, PRICER.forecastValue(PERIOD_INTERP, p))); CurrencyParameterSensitivities expectedMonthly = FD_CAL.sensitivity(IRP_ON_FIX, p -> CurrencyAmount.of(USD, PRICER.forecastValue(PERIOD_MONTHLY, p))); assertTrue(computedInterp.equalWithTolerance(expectedInterp, NOTIONAL * FD_EPS)); assertTrue(computedMonthly.equalWithTolerance(expectedMonthly, NOTIONAL * FD_EPS)); }
public void test_netAmount_standard() { CurrencyAmount computed = PRICER.netAmount(TRADE_STANDARD, RATES_PROVIDER); double expected = PERIOD_PRICER.forecastValue(SETTLE_PERIOD_STANDARD, RATES_PROVIDER); assertEquals(computed.getAmount(), expected, QUANTITY * NOTIONAL * TOL); }
public void test_forecastValueSensitivity_beforeStart() { PointSensitivityBuilder pointInterp = PRICER.forecastValueSensitivity(PERIOD_INTERP, IRP_BEFORE_START); CurrencyParameterSensitivities computedInterp = IRP_BEFORE_START.parameterSensitivity(pointInterp.build()); PointSensitivityBuilder pointMonthly = PRICER.forecastValueSensitivity(PERIOD_MONTHLY, IRP_BEFORE_START); CurrencyParameterSensitivities computedMonthly = IRP_BEFORE_START.parameterSensitivity(pointMonthly.build()); CurrencyParameterSensitivities expectedInterp = FD_CAL.sensitivity(IRP_BEFORE_START, p -> CurrencyAmount.of(USD, PRICER.forecastValue(PERIOD_INTERP, p))); CurrencyParameterSensitivities expectedMonthly = FD_CAL.sensitivity(IRP_BEFORE_START, p -> CurrencyAmount.of(USD, PRICER.forecastValue(PERIOD_MONTHLY, p))); assertTrue(computedInterp.equalWithTolerance(expectedInterp, NOTIONAL * FD_EPS)); assertTrue(computedMonthly.equalWithTolerance(expectedMonthly, NOTIONAL * FD_EPS)); }
public void test_netAmount_late() { CurrencyAmount computed = PRICER.netAmount(TRADE_LATE, RATES_PROVIDER); double expected = PERIOD_PRICER.forecastValue(SETTLE_PERIOD_LATE, RATES_PROVIDER); assertEquals(computed.getAmount(), expected, QUANTITY * NOTIONAL * TOL); }
/** * Calculates the present value of a single payment period with z-spread. * <p> * This returns the value of the period with discounting. * If the payment date of the period is in the past, zero is returned. * * @param period the period to price * @param ratesProvider the rates provider, used to determine price index values * @param issuerDiscountFactors 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 presentValueWithZSpread( CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear) { double df = issuerDiscountFactors.getDiscountFactors() .discountFactorWithSpread(period.getPaymentDate(), zSpread, compoundedRateType, periodsPerYear); return df * forecastValue(period, ratesProvider); }
public void test_currentCash_onPayment() { CurrencyAmount computed = PRICER.currentCash(PRODUCT, RATES_PROVIDER_ON_PAY, VALUATION_ON_PAY.minusDays(7)); double expected = PERIOD_PRICER.forecastValue(PRODUCT.getPeriodicPayments().get(15), RATES_PROVIDER_ON_PAY); assertEquals(computed.getAmount(), expected); }
public void test_presentValue_beforeStart() { double computedInterp = PRICER.presentValue(PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START); double computedMonthly = PRICER.presentValue(PERIOD_MONTHLY, IRP_BEFORE_START, ICDF_BEFORE_START); double computedFvInterp = PRICER.forecastValue(PERIOD_INTERP, IRP_BEFORE_START); double computedFvMonthly = PRICER.forecastValue(PERIOD_MONTHLY, IRP_BEFORE_START); double index1 = IRP_BEFORE_START.priceIndexValues(US_CPI_U).value(OBS); double index2 = IRP_BEFORE_START.priceIndexValues(US_CPI_U).value(OBS_PLUS1); double df = ICDF_BEFORE_START.discountFactor(END); double expectedFvInterp = (index1 * WEIGHT + (1d - WEIGHT) * index2) / START_INDEX * REAL_COUPON * NOTIONAL; double expectedFvMonthly = index1 / START_INDEX * REAL_COUPON * NOTIONAL; assertEquals(computedFvInterp, expectedFvInterp, TOL * expectedFvInterp); assertEquals(computedFvMonthly, expectedFvMonthly, TOL * expectedFvMonthly); assertEquals(computedInterp, expectedFvInterp * df, TOL * expectedFvInterp * df); assertEquals(computedMonthly, expectedFvMonthly * df, TOL * expectedFvMonthly * df); }
/** * Calculates the net amount of the settlement of the bond trade. * <p> * 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"); }
public void test_explainPresentValue() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValue(PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START, builder); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "CapitalIndexedBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_INTERP.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_INTERP.getCurrency()); assertEquals(explain.get(ExplainKey.START_DATE).get(), START); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START_UNADJ); assertEquals(explain.get(ExplainKey.END_DATE).get(), END); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END_UNADJ); assertEquals(explain.get(ExplainKey.DAYS).get().intValue(), (int) DAYS.between(START_UNADJ, END_UNADJ)); assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).get(), ICDF_BEFORE_START.discountFactor(END)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), PRICER.forecastValue(PERIOD_INTERP, IRP_BEFORE_START), NOTIONAL * TOL); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), PRICER.presentValue(PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START), NOTIONAL * TOL); }
public void test_explainPresentValueWithZSpread() { ExplainMapBuilder builder = ExplainMap.builder(); PRICER.explainPresentValueWithZSpread( PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START, builder, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); ExplainMap explain = builder.build(); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "CapitalIndexedBondPaymentPeriod"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), PERIOD_INTERP.getPaymentDate()); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), PERIOD_INTERP.getCurrency()); assertEquals(explain.get(ExplainKey.START_DATE).get(), START); assertEquals(explain.get(ExplainKey.UNADJUSTED_START_DATE).get(), START_UNADJ); assertEquals(explain.get(ExplainKey.END_DATE).get(), END); assertEquals(explain.get(ExplainKey.UNADJUSTED_END_DATE).get(), END_UNADJ); assertEquals(explain.get(ExplainKey.DAYS).get().intValue(), (int) DAYS.between(START_UNADJ, END_UNADJ)); assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).get(), ICDF_BEFORE_START.discountFactor(END)); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), PRICER.forecastValue(PERIOD_INTERP, IRP_BEFORE_START), NOTIONAL * TOL); assertEquals( explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), PRICER.presentValueWithZSpread( PERIOD_INTERP, IRP_BEFORE_START, ICDF_BEFORE_START, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR), NOTIONAL * TOL); }
public void test_presentValueWithZSpread_late() { CurrencyAmount computed = PRICER.presentValueWithZSpread( TRADE_LATE, RATES_PROVIDER, ISSUER_RATES_PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); double expected1 = QUANTITY * PRODUCT_PRICER.presentValueWithZSpread( RPRODUCT, RATES_PROVIDER, ISSUER_RATES_PROVIDER, SETTLEMENT_LATE, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR).getAmount(); double df = ISSUER_RATES_PROVIDER.repoCurveDiscountFactors(SECURITY_ID, LEGAL_ENTITY, USD) .discountFactor(SETTLEMENT_LATE); double expected2 = df * PERIOD_PRICER.forecastValue(SETTLE_PERIOD_LATE, RATES_PROVIDER); assertEquals(computed.getAmount(), expected1 + expected2, NOTIONAL * QUANTITY * TOL); }
public void test_presentValue_standard() { CurrencyAmount computed = PRICER.presentValue(TRADE_STANDARD, RATES_PROVIDER, ISSUER_RATES_PROVIDER); double expected1 = PRODUCT_PRICER.presentValue( RPRODUCT, RATES_PROVIDER, ISSUER_RATES_PROVIDER, SETTLEMENT_STANDARD).getAmount() * QUANTITY; double df = ISSUER_RATES_PROVIDER.repoCurveDiscountFactors(SECURITY_ID, LEGAL_ENTITY, USD) .discountFactor(SETTLEMENT_STANDARD); double expected2 = df * PERIOD_PRICER.forecastValue(SETTLE_PERIOD_STANDARD, RATES_PROVIDER); assertEquals(computed.getAmount(), expected1 + expected2, NOTIONAL * QUANTITY * TOL); }
public void test_presentValueWithZSpread_standard() { CurrencyAmount computed = PRICER.presentValueWithZSpread( TRADE_STANDARD, RATES_PROVIDER, ISSUER_RATES_PROVIDER, Z_SPREAD, CONTINUOUS, 0); double expected1 = QUANTITY * PRODUCT_PRICER.presentValueWithZSpread( RPRODUCT, RATES_PROVIDER, ISSUER_RATES_PROVIDER, SETTLEMENT_STANDARD, Z_SPREAD, CONTINUOUS, 0).getAmount(); double df = ISSUER_RATES_PROVIDER.repoCurveDiscountFactors(SECURITY_ID, LEGAL_ENTITY, USD) .discountFactor(SETTLEMENT_STANDARD); double expected2 = df * PERIOD_PRICER.forecastValue(SETTLE_PERIOD_STANDARD, RATES_PROVIDER); assertEquals(computed.getAmount(), expected1 + expected2, NOTIONAL * QUANTITY * TOL); }
public void test_presentValue_late() { CurrencyAmount computed = PRICER.presentValue(TRADE_LATE, RATES_PROVIDER, ISSUER_RATES_PROVIDER); double expected1 = PRODUCT_PRICER.presentValue( RPRODUCT, RATES_PROVIDER, ISSUER_RATES_PROVIDER, SETTLEMENT_LATE).getAmount() * QUANTITY; double df = ISSUER_RATES_PROVIDER.repoCurveDiscountFactors(SECURITY_ID, LEGAL_ENTITY, USD) .discountFactor(SETTLEMENT_LATE); double expected2 = df * PERIOD_PRICER.forecastValue(SETTLE_PERIOD_LATE, RATES_PROVIDER); assertEquals(computed.getAmount(), expected1 + expected2, NOTIONAL * QUANTITY * TOL); }
/** * Calculates the current cash of the bond product. * * @param bond the product * @param ratesProvider the rates provider, used to determine price index values * @param settlementDate the settlement date * @return the current cash of the product */ public CurrencyAmount currentCash( ResolvedCapitalIndexedBond bond, RatesProvider ratesProvider, LocalDate settlementDate) { LocalDate valuationDate = ratesProvider.getValuationDate(); Currency currency = bond.getCurrency(); CurrencyAmount currentCash = CurrencyAmount.zero(currency); if (settlementDate.isBefore(valuationDate)) { double cashCoupon = bond.hasExCouponPeriod() ? 0d : currentCashPayment(bond, ratesProvider, valuationDate); CapitalIndexedBondPaymentPeriod nominal = bond.getNominalPayment(); double cashNominal = nominal.getPaymentDate().isEqual(valuationDate) ? periodPricer.forecastValue(nominal, ratesProvider) : 0d; currentCash = currentCash.plus(CurrencyAmount.of(currency, cashCoupon + cashNominal)); } return currentCash; }
} 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, presentValue(period, ratesProvider, issuerDiscountFactors)));
} 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)));