//------------------------------------------------------------------------- public virtual void test_price_presentValue() { for (int i = 0; i < NB_STRIKES; ++i) { ResolvedFxVanillaOption call = CALLS[i]; ResolvedFxVanillaOptionTrade callTrade = ResolvedFxVanillaOptionTrade.builder().product(call).premium(Payment.of(EUR, 0, VAL_DATE)).build(); double computedPriceCall = PRICER.price(call, RATES_PROVIDER, VOLS); CurrencyAmount computedCall = PRICER.presentValue(call, RATES_PROVIDER, VOLS); double timeToExpiry = VOLS.relativeTime(EXPIRY); FxRate forward = FX_PRICER.forwardFxRate(UNDERLYING[i], RATES_PROVIDER); double forwardRate = forward.fxRate(CURRENCY_PAIR); double strikeRate = call.Strike; SmileDeltaParameters smileAtTime = VOLS.Smile.smileForExpiry(timeToExpiry); double[] strikes = smileAtTime.strike(forwardRate).toArray(); double[] vols = smileAtTime.Volatility.toArray(); double df = RATES_PROVIDER.discountFactor(USD, PAY); double[] weights = this.weights(forwardRate, strikeRate, strikes, timeToExpiry, vols[1]); double expectedPriceCall = BlackFormulaRepository.price(forwardRate, strikeRate, timeToExpiry, vols[1], true); for (int j = 0; j < 3; ++j) { expectedPriceCall += weights[j] * (BlackFormulaRepository.price(forwardRate, strikes[j], timeToExpiry, vols[j], true) - BlackFormulaRepository.price(forwardRate, strikes[j], timeToExpiry, vols[1], true)); } expectedPriceCall *= df; assertEquals(computedPriceCall, expectedPriceCall, TOL); assertEquals(computedCall.Amount, expectedPriceCall * NOTIONAL, TOL * NOTIONAL); // test against trade pricer assertEquals(computedCall, TRADE_PRICER.presentValue(callTrade, RATES_PROVIDER, VOLS).getAmount(USD)); } }
// Present Value public virtual void presentValue_beforeFixing_coupon() { CurrencyAmount pv = PRICER_CMS.presentValue(COUPON, RATES_PROVIDER); double df = RATES_PROVIDER.discountFactor(EUR, END); double forward = PRICER_SWAP.parRate(COUPON.UnderlyingSwap, RATES_PROVIDER); assertEquals(pv.Amount, forward * df * NOTIONAL * ACC_FACTOR, TOLERANCE_PV); }
public virtual void presentValue_onFix_nots() { CurrencyAmount pv = PRICER_CMS.presentValue(COUPON, RATES_PROVIDER_ON_FIX); double factor = RATES_PROVIDER_ON_FIX.discountFactor(EUR, PAYMENT) * NOTIONAL * COUPON.YearFraction; double forward = PRICER_SWAP.parRate(COUPON.UnderlyingSwap, RATES_PROVIDER_ON_FIX); assertEquals(pv.Amount, forward * factor, TOLERANCE_PV); }
//------------------------------------------------------------------------- public virtual void test_presentValue_formula() { CurrencyAmount computedCaplet = PRICER.presentValue(CAPLET_LONG, RATES, VOLS); CurrencyAmount computedFloorlet = PRICER.presentValue(FLOORLET_SHORT, RATES, VOLS); double forward = RATES.iborIndexRates(EUR_EURIBOR_3M).rate(RATE_COMP.Observation); double expiry = VOLS.relativeTime(CAPLET_LONG.FixingDateTime); double volatility = VOLS.volatility(expiry, STRIKE, forward); double df = RATES.discountFactor(EUR, CAPLET_LONG.PaymentDate); double expectedCaplet = NOTIONAL * df * CAPLET_LONG.YearFraction * NormalFormulaRepository.price(forward, STRIKE, expiry, volatility, CALL); double expectedFloorlet = -NOTIONAL *df *CAPLET_LONG.YearFraction *NormalFormulaRepository.price(forward, STRIKE, expiry, volatility, PUT); assertEquals(computedCaplet.Currency, EUR); assertEquals(computedCaplet.Amount, expectedCaplet, NOTIONAL * TOL); assertEquals(computedFloorlet.Currency, EUR); assertEquals(computedFloorlet.Amount, expectedFloorlet, NOTIONAL * TOL); }
//------------------------------------------------------------------------- public virtual void test_presentValue_noFixing() { double discountFactor = IMM_PROV_NOFIX.discountFactor(EUR, END_DATE); double forwardRate = IMM_PROV_NOFIX.iborIndexRates(EUR_EURIBOR_6M).rate(RDEPOSIT.FloatingRate.Observation); CurrencyAmount computed = PRICER.presentValue(RDEPOSIT, IMM_PROV_NOFIX); double expected = NOTIONAL * discountFactor * (RATE - forwardRate) * RDEPOSIT.YearFraction; assertEquals(computed.Currency, EUR); assertEquals(computed.Amount, expected, TOLERANCE_PV); }
//------------------------------------------------------------------------- public virtual void test_presentValue_formula() { CurrencyAmount computedCaplet = PRICER.presentValue(CAPLET_LONG, RATES, VOLS); CurrencyAmount computedFloorlet = PRICER.presentValue(FLOORLET_SHORT, RATES, VOLS); double forward = RATES.iborIndexRates(EUR_EURIBOR_3M).rate(RATE_COMP.Observation); double expiry = VOLS.relativeTime(CAPLET_LONG.FixingDateTime); double volatility = VOLS.volatility(expiry, STRIKE, forward); double df = RATES.discountFactor(EUR, CAPLET_LONG.PaymentDate); double expectedCaplet = NOTIONAL * df * CAPLET_LONG.YearFraction * BlackFormulaRepository.price(forward + SHIFT, STRIKE + SHIFT, expiry, volatility, CALL.Call); double expectedFloorlet = -NOTIONAL *df *FLOORLET_SHORT.YearFraction *BlackFormulaRepository.price(forward + SHIFT, STRIKE + SHIFT, expiry, volatility, PUT.Call); assertEquals(computedCaplet.Currency, EUR); assertEquals(computedCaplet.Amount, expectedCaplet, NOTIONAL * TOL); assertEquals(computedFloorlet.Currency, EUR); assertEquals(computedFloorlet.Amount, expectedFloorlet, NOTIONAL * TOL); // consistency with shifted Black ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities vols = ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities.of(EUR_EURIBOR_3M, VALUATION, ConstantSurface.of("constVol", volatility).withMetadata(Surfaces.blackVolatilityByExpiryStrike("costVol", DayCounts.ACT_ACT_ISDA)), IborCapletFloorletSabrRateVolatilityDataSet.CURVE_CONST_SHIFT); CurrencyAmount computedCapletBlack = PRICER_BASE.presentValue(CAPLET_LONG, RATES, vols); CurrencyAmount computedFloorletBlack = PRICER_BASE.presentValue(FLOORLET_SHORT, RATES, vols); assertEquals(computedCaplet.Amount, computedCapletBlack.Amount, NOTIONAL * TOL); assertEquals(computedFloorlet.Amount, computedFloorletBlack.Amount, NOTIONAL * TOL); }
public virtual void presentValue_afterFix() { CurrencyAmount pv = PRICER_CMS.presentValue(COUPON, RATES_PROVIDER_AFTER_FIX); CurrencyAmount pvCapletOtm = PRICER_CMS.presentValue(CAPLET, RATES_PROVIDER_AFTER_FIX); CurrencyAmount pvCapletItm = PRICER_CMS.presentValue(CAPLET_NEGATIVE, RATES_PROVIDER_AFTER_FIX); CurrencyAmount pvFloorletItm = PRICER_CMS.presentValue(FLOORLET, RATES_PROVIDER_AFTER_FIX); CurrencyAmount pvFloorletOtm = PRICER_CMS.presentValue(FLOORLET_NEGATIVE, RATES_PROVIDER_AFTER_FIX); double factor = RATES_PROVIDER_AFTER_FIX.discountFactor(EUR, PAYMENT) * NOTIONAL * COUPON.YearFraction; assertEquals(pv.Amount, OBS_INDEX * factor, TOLERANCE_PV); assertEquals(pvCapletOtm.Amount, 0d, TOLERANCE_PV); assertEquals(pvCapletItm.Amount, (OBS_INDEX - STRIKE_NEGATIVE) * factor, TOLERANCE_PV); assertEquals(pvFloorletItm.Amount, (STRIKE - OBS_INDEX) * factor, TOLERANCE_PV); assertEquals(pvFloorletOtm.Amount, 0d, TOLERANCE_PV); }
public virtual void test_presentValue_after() { CurrencyAmount capComputed = PRICER.presentValue(CAP, RATES_AFTER, VOLS_AFTER); CurrencyAmount floorComputed = PRICER.presentValue(FLOOR, RATES_AFTER, VOLS_AFTER); double capExpected = 0d; IborCapletFloorletPeriod period = FLOOR.CapletFloorletPeriods.get(1); double floorExpected = -(STRIKE - OBS_INDEX_2) * NOTIONAL_VALUE * period.YearFraction * RATES_AFTER.discountFactor(EUR, period.PaymentDate); int nPeriods = CAP.CapletFloorletPeriods.size(); for (int i = 2; i < nPeriods; ++i) { capExpected += PRICER_PERIOD.presentValue(CAP.CapletFloorletPeriods.get(i), RATES_AFTER, VOLS_AFTER).Amount; floorExpected += PRICER_PERIOD.presentValue(FLOOR.CapletFloorletPeriods.get(i), RATES_AFTER, VOLS_AFTER).Amount; } assertEquals(capComputed.Currency, EUR); assertEquals(capComputed.Amount, capExpected, TOL * NOTIONAL_VALUE); assertEquals(floorComputed.Currency, EUR); assertEquals(floorComputed.Amount, floorExpected, TOL * NOTIONAL_VALUE); }
public virtual void test_cashFlowEquivalent() { ResolvedSwap swap = ResolvedSwap.of(IBOR_LEG, FIXED_LEG); ResolvedSwapLeg computed = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, PROVIDER); ResolvedSwapLeg computedIborLeg = CashFlowEquivalentCalculator.cashFlowEquivalentIborLeg(IBOR_LEG, PROVIDER); ResolvedSwapLeg computedFixedLeg = CashFlowEquivalentCalculator.cashFlowEquivalentFixedLeg(FIXED_LEG, PROVIDER); assertEquals(computedFixedLeg.PaymentEvents, computed.PaymentEvents.subList(0, 2)); assertEquals(computedIborLeg.PaymentEvents, computed.PaymentEvents.subList(2, 6)); // expected payments from fixed leg NotionalExchange fixedPayment1 = NotionalExchange.of(CurrencyAmount.of(GBP, NOTIONAL * RATE * PAY_YC1), PAYMENT1); NotionalExchange fixedPayment2 = NotionalExchange.of(CurrencyAmount.of(GBP, NOTIONAL * RATE * PAY_YC2), PAYMENT2); // expected payments from ibor leg LocalDate fixingSTART1 = GBP_LIBOR_3M.calculateEffectiveFromFixing(FIXING1, REF_DATA); double fixedYearFraction1 = GBP_LIBOR_3M.DayCount.relativeYearFraction(fixingSTART1, GBP_LIBOR_3M.calculateMaturityFromEffective(fixingSTART1, REF_DATA)); double beta1 = (1d + fixedYearFraction1 * PROVIDER.iborIndexRates(GBP_LIBOR_3M).rate(GBP_LIBOR_3M_COMP1.Observation)) * PROVIDER.discountFactor(GBP, PAYMENT1) / PROVIDER.discountFactor(GBP, fixingSTART1); NotionalExchange iborPayment11 = NotionalExchange.of(CurrencyAmount.of(GBP, -NOTIONAL * beta1 * PAY_YC1 / fixedYearFraction1), fixingSTART1); NotionalExchange iborPayment12 = NotionalExchange.of(CurrencyAmount.of(GBP, NOTIONAL * PAY_YC1 / fixedYearFraction1), PAYMENT1); LocalDate fixingSTART2 = GBP_LIBOR_3M.calculateEffectiveFromFixing(FIXING2, REF_DATA); double fixedYearFraction2 = GBP_LIBOR_3M.DayCount.relativeYearFraction(fixingSTART2, GBP_LIBOR_3M.calculateMaturityFromEffective(fixingSTART2, REF_DATA)); double beta2 = (1d + fixedYearFraction2 * PROVIDER.iborIndexRates(GBP_LIBOR_3M).rate(GBP_LIBOR_3M_COMP2.Observation)) * PROVIDER.discountFactor(GBP, PAYMENT2) / PROVIDER.discountFactor(GBP, fixingSTART2); NotionalExchange iborPayment21 = NotionalExchange.of(CurrencyAmount.of(GBP, -NOTIONAL * beta2 * PAY_YC2 / fixedYearFraction2), fixingSTART2); NotionalExchange iborPayment22 = NotionalExchange.of(CurrencyAmount.of(GBP, NOTIONAL * PAY_YC2 / fixedYearFraction2), PAYMENT2); ResolvedSwapLeg expected = ResolvedSwapLeg.builder().type(OTHER).payReceive(RECEIVE).paymentEvents(fixedPayment1, fixedPayment2, iborPayment11, iborPayment12, iborPayment21, iborPayment22).build(); double eps = 1.0e-12; assertEquals(computed.PaymentEvents.size(), expected.PaymentEvents.size()); for (int i = 0; i < 6; ++i) { NotionalExchange payCmp = (NotionalExchange)computed.PaymentEvents.get(i); NotionalExchange payExp = (NotionalExchange)expected.PaymentEvents.get(i); assertEquals(payCmp.Currency, payExp.Currency); assertEquals(payCmp.PaymentDate, payExp.PaymentDate); assertTrue(DoubleMath.fuzzyEquals(payCmp.PaymentAmount.Amount, payExp.PaymentAmount.Amount, NOTIONAL * eps)); } }