// ------------------------------------------------------------------------- public void test_dirtyPriceFromCurves() { double computed = PRICER.dirtyPriceFromCurves(BOND_SECURITY, PROVIDER); CurrencyAmount pv = PRICER.presentValue(PRODUCT, PROVIDER); LocalDate settlement = DATE_OFFSET.adjust(VAL_DATE); double df = DSC_FACTORS_REPO.discountFactor(settlement); assertEquals(computed, pv.getAmount() / df / NOTIONAL); }
/** * Gets the notional amount, positive if receiving, negative if paying. * * <p>This is the notional amount applicable during the period. The currency of the notional is * specified by {@code currency} unless there is the {@code fxReset} property is present. * * @return the notional as a {@code CurrencyAmount} */ @Override public CurrencyAmount getNotionalAmount() { if (fxReset != null) { return CurrencyAmount.of(fxReset.getReferenceCurrency(), notional); } return CurrencyAmount.of(currency, notional); }
/** * Calculates the present value of the swaption product. * * <p>The result is expressed using the currency of the swapion. * * @param swaption the product to price * @param ratesProvider the rates provider * @param volatilityProvider the normal volatility provider * @return the present value of the swaption product */ public CurrencyAmount presentValue( SwaptionProduct swaption, RatesProvider ratesProvider, NormalVolatilitySwaptionProvider volatilityProvider) { ExpandedSwaption expanded = swaption.expand(); validate(ratesProvider, expanded, volatilityProvider); ZonedDateTime expiryDateTime = expanded.getExpiryDateTime(); double expiry = volatilityProvider.relativeTime(expiryDateTime); ExpandedSwap underlying = expanded.getUnderlying(); ExpandedSwapLeg fixedLeg = fixedLeg(underlying); if (expiry < 0.0d) { // Option has expired already return CurrencyAmount.of(fixedLeg.getCurrency(), 0.0d); } double forward = swapPricer.parRate(underlying, ratesProvider); double pvbp = swapPricer.getLegPricer().pvbp(fixedLeg, ratesProvider); double strike = swapPricer.getLegPricer().couponEquivalent(fixedLeg, ratesProvider, pvbp); double tenor = volatilityProvider.tenor(fixedLeg.getStartDate(), fixedLeg.getEndDate()); double volatility = volatilityProvider.getVolatility(expiryDateTime, tenor, strike, forward); NormalFunctionData normalData = NormalFunctionData.of(forward, Math.abs(pvbp), volatility); boolean isCall = (fixedLeg.getPayReceive() == PayReceive.PAY); // Payer at strike is exercise when rate > strike, i.e. call on rate EuropeanVanillaOption option = EuropeanVanillaOption.of(strike, expiry, isCall ? PutCall.CALL : PutCall.PUT); // option required to pass the strike (in case the swap has non-constant coupon). Function1D<NormalFunctionData, Double> func = NORMAL.getPriceFunction(option); double pv = func.evaluate(normalData) * ((expanded.getLongShort() == LongShort.LONG) ? 1.0 : -1.0); return CurrencyAmount.of(fixedLeg.getCurrency(), pv); }
private void assertPresentValue(ImmutableRatesProvider result) { // Test PV USD; List<Trade> usdTrades = new ArrayList<>(); for (int i = 0; i < USD_DSC_NODES.length; i++) { usdTrades.add(USD_DSC_NODES[i].trade(VAL_DATE, ALL_QUOTES)); } // Depo for (int i = 0; i < USD_DSC_NB_DEPO_NODES; i++) { CurrencyAmount pvDep = DEPO_PRICER.presentValue(((TermDepositTrade) usdTrades.get(i)).getProduct(), result); assertEquals(pvDep.getAmount(), 0.0, TOLERANCE_PV); } // OIS for (int i = 0; i < USD_DSC_NB_OIS_NODES; i++) { MultiCurrencyAmount pvOis = SWAP_PRICER.presentValue( ((SwapTrade) usdTrades.get(USD_DSC_NB_DEPO_NODES + i)).getProduct(), result); assertEquals(pvOis.getAmount(USD).getAmount(), 0.0, TOLERANCE_PV); } // Test PV EUR; List<Trade> eurTrades = new ArrayList<>(); for (int i = 0; i < EUR_DSC_NODES.length; i++) { eurTrades.add(EUR_DSC_NODES[i].trade(VAL_DATE, ALL_QUOTES)); } // Depo for (int i = 0; i < EUR_DSC_NB_FX_NODES; i++) { MultiCurrencyAmount pvFx = FX_PRICER.presentValue(((FxSwapTrade) eurTrades.get(i)).getProduct(), result); assertEquals(pvFx.convertedTo(USD, result).getAmount(), 0.0, TOLERANCE_PV); } }
public void convertCurrencyAmount() { List<FxRate> rates = ImmutableList.of( FxRate.of(Currency.GBP, Currency.USD, 1.61), FxRate.of(Currency.GBP, Currency.USD, 1.62), FxRate.of(Currency.GBP, Currency.USD, 1.63)); CalculationEnvironment marketData = MarketEnvironment.builder() .valuationDate(date(2011, 3, 8)) .addValue(FxRateId.of(Currency.GBP, Currency.USD), rates) .build(); MarketDataMappings mappings = MarketDataMappings.of(MarketDataFeed.NONE); DefaultCalculationMarketData calculationMarketData = DefaultCalculationMarketData.of(marketData, mappings); SingleScenarioResult<CurrencyAmount> test = SingleScenarioResult.of(3, CurrencyAmount.of(Currency.GBP, 2)); ScenarioResult<?> convertedList = test.convertedTo(Currency.USD, calculationMarketData); List<CurrencyAmount> expectedValues = ImmutableList.of( CurrencyAmount.of(Currency.USD, 2 * 1.61), CurrencyAmount.of(Currency.USD, 2 * 1.62), CurrencyAmount.of(Currency.USD, 2 * 1.63)); DefaultScenarioResult<CurrencyAmount> expectedList = DefaultScenarioResult.of(expectedValues); assertThat(convertedList).isEqualTo(expectedList); }
/** Test FRA paying in the past. */ public void test_presentValue_inPast() { ExpandedFra fraExp = FRA.expand().toBuilder().paymentDate(VAL_DATE.minusDays(1)).build(); SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.presentValue(fraExp, prov); assertEquals(computed.getAmount(), 0d, TOLERANCE); }
/** Test present value for ISDA FRA Discounting method. */ public void test_presentValue_AFMA() { ExpandedFra fraExp = FRA_AFMA.expand(); SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount pvComputed = test.presentValue(fraExp, prov); CurrencyAmount pvExpected = test.forecastValue(fraExp, prov).multipliedBy(DISCOUNT_FACTOR); assertEquals(pvComputed.getAmount(), pvExpected.getAmount(), TOLERANCE); }
// ------------------------------------------------------------------------- @ImmutableValidator private void validate() { if (rebate != null) { ArgChecker.isTrue(rebate.getAmount() > 0d, "rebate must be positive"); ArgChecker.isTrue( underlyingOption.getUnderlying().getCurrencyPair().contains(rebate.getCurrency()), "The rebate currency must be one of underlying currency pair"); } }
/** Test par spread for AFMA FRA Discounting method. */ public void test_parSpread_AFMA() { ExpandedFra fraExp = FRA_AFMA.expand(); SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; double parSpread = test.parSpread(fraExp, prov); Fra fra = createNewFra(FRA_AFMA, FRA_AFMA.getFixedRate() + parSpread); CurrencyAmount pv = test.presentValue(fra, prov); assertEquals(pv.getAmount(), 0.0, TOLERANCE); }
public void test_dirtyPriceFromCurvesWithZSpread_periodic() { double computed = PRICER.dirtyPriceFromCurvesWithZSpread( BOND_SECURITY, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); CurrencyAmount pv = PRICER.presentValueWithZSpread(PRODUCT, PROVIDER, Z_SPREAD, PERIODIC, PERIOD_PER_YEAR); LocalDate settlement = DATE_OFFSET.adjust(VAL_DATE); double df = DSC_FACTORS_REPO.discountFactor(settlement); assertEquals(computed, pv.getAmount() / df / NOTIONAL); }
public void test_cashFlowEquivalent_pv() { Swap swap = Swap.builder().legs(IBOR_LEG, FIXED_LEG).build(); ExpandedSwapLeg cfe = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap.expand(), PROVIDER); DiscountingSwapLegPricer pricerLeg = DiscountingSwapLegPricer.DEFAULT; DiscountingSwapProductPricer pricerSwap = DiscountingSwapProductPricer.DEFAULT; CurrencyAmount pvCfe = pricerLeg.presentValue(cfe, PROVIDER); MultiCurrencyAmount pvSwap = pricerSwap.presentValue(swap, PROVIDER); assertEquals(pvCfe.getAmount(), pvSwap.getAmount(GBP).getAmount(), TOLERANCE_PV); }
/** Test par rate for NONE FRA Discounting method. */ public void test_parRate_NONE() { ExpandedFra fraExp = FRA_NONE.expand(); SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; double parRate = test.parRate(fraExp, prov); assertEquals(parRate, FORWARD_RATE); Fra fra = createNewFra(FRA_NONE, parRate); CurrencyAmount pv = test.presentValue(fra, prov); assertEquals(pv.getAmount(), 0.0, TOLERANCE); }
/** Test forecast value for NONE FRA Discounting method. */ public void test_forecastValue_NONE() { ExpandedFra fraExp = FRA_NONE.expand(); SimpleRatesProvider prov = createProvider(fraExp); double fixedRate = FRA_NONE.getFixedRate(); double yearFraction = fraExp.getYearFraction(); double notional = fraExp.getNotional(); double expected = notional * yearFraction * (FORWARD_RATE - fixedRate); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.forecastValue(fraExp, prov); assertEquals(computed.getAmount(), expected, TOLERANCE); }
// ------------------------------------------------------------------------- private double forecastValueFwdSensitivity(Fra fra, double forwardRate, double eps) { RateObservationFn<RateObservation> obsFuncNew = mock(RateObservationFn.class); RatesProvider provNew = mock(RatesProvider.class); when(provNew.getValuationDate()).thenReturn(VAL_DATE); ExpandedFra fraExp = fra.expand(); when(obsFuncNew.rate(fraExp.getFloatingRate(), fra.getStartDate(), fra.getEndDate(), provNew)) .thenReturn(forwardRate + eps); CurrencyAmount upValue = new DiscountingFraProductPricer(obsFuncNew).forecastValue(fraExp, provNew); when(obsFuncNew.rate(fraExp.getFloatingRate(), fra.getStartDate(), fra.getEndDate(), provNew)) .thenReturn(forwardRate - eps); CurrencyAmount downValue = new DiscountingFraProductPricer(obsFuncNew).forecastValue(fraExp, provNew); return upValue.minus(downValue).multipliedBy(0.5 / eps).getAmount(); }
public void test_presentValue() { Currency ccy1 = TRADE.getProduct().getNonDeliverableCurrency(); Currency ccy2 = TRADE.getProduct().getSettlementCurrency(); LocalDate valDate = TRADE.getProduct().getPaymentDate().plusDays(7); FunctionConfig<FxNdfTrade> config = FxNdfFunctionGroups.discounting().functionConfig(TRADE, Measure.PRESENT_VALUE).get(); CalculationSingleFunction<FxNdfTrade, ?> function = config.createFunction(); FunctionRequirements reqs = function.requirements(TRADE); assertThat(reqs.getOutputCurrencies()).containsOnly(ccy1, ccy2); assertThat(reqs.getSingleValueRequirements()) .isEqualTo(ImmutableSet.of(DiscountCurveKey.of(ccy1), DiscountCurveKey.of(ccy2))); assertThat(reqs.getTimeSeriesRequirements()).isEqualTo(ImmutableSet.of()); assertThat(function.defaultReportingCurrency(TRADE)).hasValue(GBP); DiscountFactors df1 = SimpleDiscountFactors.of( ccy1, valDate, ConstantNodalCurve.of(Curves.discountFactors("Test", ACT_360), 0.99)); DiscountFactors df2 = SimpleDiscountFactors.of( ccy2, valDate, ConstantNodalCurve.of(Curves.discountFactors("Test", ACT_360), 0.99)); TestMarketDataMap md = new TestMarketDataMap( valDate, ImmutableMap.of(DiscountCurveKey.of(ccy1), df1, DiscountCurveKey.of(ccy2), df2), ImmutableMap.of()); assertThat(function.execute(TRADE, md)) .isEqualTo(FxConvertibleList.of(ImmutableList.of(CurrencyAmount.zero(GBP)))); }
// ------------------------------------------------------------------------- public void test_priceSensitivity() { PointSensitivities point = OPTION_PRICER.priceSensitivityStickyStrike( FUTURE_OPTION_PRODUCT, RATE_PROVIDER, VOL_PROVIDER); CurveCurrencyParameterSensitivities computed = RATE_PROVIDER.curveParameterSensitivity(point); CurveCurrencyParameterSensitivities expected = FD_CAL.sensitivity( RATE_PROVIDER, (p) -> CurrencyAmount.of( EUR, OPTION_PRICER.price(FUTURE_OPTION_PRODUCT, (p), VOL_PROVIDER))); double futurePrice = FUTURE_PRICER.price(FUTURE_OPTION_PRODUCT.getUnderlying(), RATE_PROVIDER); double strike = FUTURE_OPTION_PRODUCT.getStrikePrice(); double expiryTime = ACT_365F.relativeYearFraction(VALUATION_DATE, FUTURE_OPTION_PRODUCT.getExpiryDate()); double logMoneyness = Math.log(strike / futurePrice); double logMoneynessUp = Math.log(strike / (futurePrice + EPS)); double logMoneynessDw = Math.log(strike / (futurePrice - EPS)); double vol = SURFACE.zValue(expiryTime, logMoneyness); double volUp = SURFACE.zValue(expiryTime, logMoneynessUp); double volDw = SURFACE.zValue(expiryTime, logMoneynessDw); double volSensi = 0.5 * (volUp - volDw) / EPS; double vega = BlackFormulaRepository.vega(futurePrice, strike, expiryTime, vol); CurveCurrencyParameterSensitivities sensiVol = RATE_PROVIDER .curveParameterSensitivity( FUTURE_PRICER.priceSensitivity( FUTURE_OPTION_PRODUCT.getUnderlying(), RATE_PROVIDER)) .multipliedBy(-vega * volSensi); expected = expected.combinedWith(sensiVol); assertTrue(computed.equalWithTolerance(expected, 30d * EPS)); }
/** Test explain. */ public void test_explainPresentValue_ISDA() { ExpandedFra fraExp = FRA.expand(); SimpleRatesProvider prov = createProvider(fraExp); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount fvExpected = test.forecastValue(fraExp, prov); CurrencyAmount pvExpected = test.presentValue(fraExp, prov); ExplainMap explain = test.explainPresentValue(fraExp, prov); Currency currency = fraExp.getCurrency(); int daysBetween = (int) DAYS.between(fraExp.getStartDate(), fraExp.getEndDate()); assertEquals(explain.get(ExplainKey.ENTRY_TYPE).get(), "FRA"); assertEquals(explain.get(ExplainKey.PAYMENT_DATE).get(), fraExp.getPaymentDate()); assertEquals(explain.get(ExplainKey.START_DATE).get(), fraExp.getStartDate()); assertEquals(explain.get(ExplainKey.END_DATE).get(), fraExp.getEndDate()); assertEquals(explain.get(ExplainKey.ACCRUAL_YEAR_FRACTION).get(), fraExp.getYearFraction()); assertEquals(explain.get(ExplainKey.ACCRUAL_DAYS).get(), (Integer) (int) daysBetween); assertEquals(explain.get(ExplainKey.PAYMENT_CURRENCY).get(), currency); assertEquals( explain.get(ExplainKey.NOTIONAL).get().getAmount(), fraExp.getNotional(), TOLERANCE); assertEquals( explain.get(ExplainKey.TRADE_NOTIONAL).get().getAmount(), fraExp.getNotional(), TOLERANCE); assertEquals(explain.get(ExplainKey.OBSERVATIONS).get().size(), 1); ExplainMap explainObs = explain.get(ExplainKey.OBSERVATIONS).get().get(0); IborRateObservation floatingRate = (IborRateObservation) fraExp.getFloatingRate(); assertEquals(explainObs.get(ExplainKey.INDEX).get(), floatingRate.getIndex()); assertEquals(explainObs.get(ExplainKey.FIXING_DATE).get(), floatingRate.getFixingDate()); assertEquals(explainObs.get(ExplainKey.INDEX_VALUE).get(), FORWARD_RATE, TOLERANCE); assertEquals(explain.get(ExplainKey.DISCOUNT_FACTOR).get(), DISCOUNT_FACTOR, TOLERANCE); assertEquals(explain.get(ExplainKey.FIXED_RATE).get(), fraExp.getFixedRate(), TOLERANCE); assertEquals(explain.get(ExplainKey.PAY_OFF_RATE).get(), FORWARD_RATE, TOLERANCE); assertEquals(explain.get(ExplainKey.COMBINED_RATE).get(), FORWARD_RATE, TOLERANCE); assertEquals( explain.get(ExplainKey.UNIT_AMOUNT).get(), fvExpected.getAmount() / fraExp.getNotional(), TOLERANCE); assertEquals(explain.get(ExplainKey.FORECAST_VALUE).get().getCurrency(), currency); assertEquals( explain.get(ExplainKey.FORECAST_VALUE).get().getAmount(), fvExpected.getAmount(), TOLERANCE); assertEquals(explain.get(ExplainKey.PRESENT_VALUE).get().getCurrency(), currency); assertEquals( explain.get(ExplainKey.PRESENT_VALUE).get().getAmount(), pvExpected.getAmount(), TOLERANCE); }
// ------------------------------------------------------------------------- public void test_priceSensitivity() { PointSensitivities point = FUTURE_PRICER.priceSensitivity(FUTURE_PRODUCT, PROVIDER); CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point); CurrencyParameterSensitivities expected = FD_CAL.sensitivity( PROVIDER, (p) -> CurrencyAmount.of(USD, FUTURE_PRICER.price(FUTURE_PRODUCT, (p)))); assertTrue(computed.equalWithTolerance(expected, EPS * 10.0)); }
/** Test par spread sensitivity for ISDA FRA Discounting method. */ public void test_parSpreadSensitivity_ISDA() { PointSensitivities sensi = DEFAULT_PRICER.parSpreadSensitivity(FRA, IMM_PROV); CurveCurrencyParameterSensitivities sensiComputed = IMM_PROV.curveParameterSensitivity(sensi); CurveCurrencyParameterSensitivities sensiExpected = CAL_FD.sensitivity( IMM_PROV, (p) -> CurrencyAmount.of(FRA.getCurrency(), DEFAULT_PRICER.parSpread(FRA, (p)))); assertTrue(sensiComputed.equalWithTolerance(sensiExpected, EPS_FD)); }
/** Test forecast value for ISDA FRA Discounting method. */ public void test_forecastValue_ISDA() { ExpandedFra fraExp = FRA.expand(); SimpleRatesProvider prov = createProvider(fraExp); double fixedRate = FRA.getFixedRate(); double yearFraction = fraExp.getYearFraction(); double notional = fraExp.getNotional(); double expected = notional * yearFraction * (FORWARD_RATE - fixedRate) / (1.0 + yearFraction * FORWARD_RATE); DiscountingFraProductPricer test = DiscountingFraProductPricer.DEFAULT; CurrencyAmount computed = test.forecastValue(fraExp, prov); assertEquals(computed.getAmount(), expected, TOLERANCE); // test via FraTrade DiscountingFraTradePricer testTrade = new DiscountingFraTradePricer(test); assertEquals(testTrade.forecastValue(FRA_TRADE, prov), test.forecastValue(fraExp, prov)); }
private double dscSensitivity( Fra fra, double forwardRate, double discountFactor, double paymentTime, double eps) { RatesProvider provNew = mock(RatesProvider.class); when(provNew.getValuationDate()).thenReturn(VAL_DATE); RateObservationFn<RateObservation> obsFuncNew = mock(RateObservationFn.class); ExpandedFra fraExp = fra.expand(); when(obsFuncNew.rate(fraExp.getFloatingRate(), fra.getStartDate(), fra.getEndDate(), provNew)) .thenReturn(forwardRate); when(provNew.discountFactor(fra.getCurrency(), fraExp.getPaymentDate())) .thenReturn(discountFactor * Math.exp(-eps * paymentTime)); CurrencyAmount upDscValue = new DiscountingFraProductPricer(obsFuncNew).presentValue(fraExp, provNew); when(provNew.discountFactor(fra.getCurrency(), fraExp.getPaymentDate())) .thenReturn(discountFactor * Math.exp(eps * paymentTime)); CurrencyAmount downDscValue = new DiscountingFraProductPricer(obsFuncNew).presentValue(fraExp, provNew); return upDscValue.minus(downDscValue).multipliedBy(0.5 / eps).getAmount(); }
public void test_dirtyPriceSensitivity() { PointSensitivityBuilder point = PRICER.dirtyPriceSensitivity(BOND_SECURITY, PROVIDER); CurveCurrencyParameterSensitivities computed = PROVIDER.curveParameterSensitivity(point.build()); CurveCurrencyParameterSensitivities expected = FD_CAL.sensitivity( PROVIDER, (p) -> CurrencyAmount.of(EUR, PRICER.dirtyPriceFromCurves(BOND_SECURITY, (p)))); assertTrue(computed.equalWithTolerance(expected, NOTIONAL * EPS)); }
/** * Totals all the sensitivity values. * * <p>The result is the total of all values, as converted to the specified currency. Any FX * conversion that is required will use rates from the provider. * * @param resultCurrency the currency of the result * @param rateProvider the provider of FX rates * @return the total sensitivity * @throws RuntimeException if no FX rate could be found */ public CurrencyAmount total(Currency resultCurrency, FxRateProvider rateProvider) { CurveCurrencyParameterSensitivities converted = convertedTo(resultCurrency, rateProvider); double total = converted .sensitivities .stream() .map(CurveCurrencyParameterSensitivity::getSensitivity) .flatMapToDouble(DoubleStream::of) .sum(); return CurrencyAmount.of(resultCurrency, total); }
/** Test {@link FxSingleTrade}. */ @Test public class FxSingleTradeTest { private static final CurrencyAmount GBP_P1000 = CurrencyAmount.of(GBP, 1_000); private static final CurrencyAmount GBP_M1000 = CurrencyAmount.of(GBP, -1_000); private static final CurrencyAmount USD_P1600 = CurrencyAmount.of(USD, 1_600); private static final CurrencyAmount USD_M1600 = CurrencyAmount.of(USD, -1_600); private static final LocalDate DATE_2015_06_30 = date(2015, 6, 30); private static final FxSingle FWD1 = FxSingle.of(GBP_P1000, USD_M1600, DATE_2015_06_30); private static final FxSingle FWD2 = FxSingle.of(GBP_M1000, USD_P1600, DATE_2015_06_30); // ------------------------------------------------------------------------- public void test_builder() { FxSingleTrade test = FxSingleTrade.builder().product(FWD1).build(); assertEquals(test.getTradeInfo(), TradeInfo.EMPTY); assertEquals(test.getProduct(), FWD1); } // ------------------------------------------------------------------------- public void coverage() { FxSingleTrade test = FxSingleTrade.builder() .tradeInfo(TradeInfo.builder().tradeDate(date(2014, 6, 30)).build()) .product(FWD1) .build(); coverImmutableBean(test); FxSingleTrade test2 = FxSingleTrade.builder().product(FWD2).build(); coverBeanEquals(test, test2); } public void test_serialization() { FxSingleTrade test = FxSingleTrade.builder() .tradeInfo(TradeInfo.builder().tradeDate(date(2014, 6, 30)).build()) .product(FWD1) .build(); assertSerialization(test); } }
public void test_priceSensitivityWithZSpread_continuous() { PointSensitivities point = FUTURE_PRICER.priceSensitivityWithZSpread( FUTURE_PRODUCT, PROVIDER, Z_SPREAD, CONTINUOUS, 0); CurrencyParameterSensitivities computed = PROVIDER.parameterSensitivity(point); CurrencyParameterSensitivities expected = FD_CAL.sensitivity( PROVIDER, (p) -> CurrencyAmount.of( USD, FUTURE_PRICER.priceWithZSpread(FUTURE_PRODUCT, (p), Z_SPREAD, CONTINUOUS, 0))); assertTrue(computed.equalWithTolerance(expected, EPS * 10.0)); }
public void test_dirtyPriceSensitivityWithZspread_continuous() { PointSensitivityBuilder point = PRICER.dirtyPriceSensitivityWithZspread(BOND_SECURITY, PROVIDER, Z_SPREAD, CONTINUOUS, 0); CurveCurrencyParameterSensitivities computed = PROVIDER.curveParameterSensitivity(point.build()); CurveCurrencyParameterSensitivities expected = FD_CAL.sensitivity( PROVIDER, (p) -> CurrencyAmount.of( EUR, PRICER.dirtyPriceFromCurvesWithZSpread( BOND_SECURITY, (p), Z_SPREAD, CONTINUOUS, 0))); assertTrue(computed.equalWithTolerance(expected, NOTIONAL * EPS)); }
public void test_presentValue_noExcoupon() { CurrencyAmount computed = PRICER.presentValue(PRODUCT_NO_EXCOUPON, PROVIDER); ExpandedFixedCouponBond expanded = PRODUCT.expand(); CurrencyAmount expected = PRICER_NOMINAL.presentValue(expanded.getNominalPayment(), DSC_FACTORS_ISSUER); int size = expanded.getPeriodicPayments().size(); double pvcCupon = 0d; for (int i = 2; i < size; ++i) { FixedCouponBondPaymentPeriod payment = expanded.getPeriodicPayments().get(i); pvcCupon += PRICER_COUPON.presentValue( payment, IssuerCurveDiscountFactors.of(DSC_FACTORS_ISSUER, GROUP_ISSUER)); } expected = expected.plus(pvcCupon); assertEquals(computed.getCurrency(), EUR); assertEquals(computed.getAmount(), expected.getAmount(), NOTIONAL * TOL); }
/** Test parameter sensitivity with finite difference sensitivity calculator. No cutoff period. */ public void rateChfNoCutOffParameterSensitivity() { LocalDate[] valuationDate = {date(2015, 1, 1), date(2015, 1, 8)}; double[] time = new double[] {0.0, 0.5, 1.0, 2.0, 5.0, 10.0}; double[] rate = new double[] {0.0100, 0.0110, 0.0115, 0.0130, 0.0135, 0.0135}; for (int loopvaldate = 0; loopvaldate < 2; loopvaldate++) { Curve onCurve = InterpolatedNodalCurve.of(Curves.zeroRates("ON", ACT_ACT_ISDA), time, rate, INTERPOLATOR); ImmutableRatesProvider prov = ImmutableRatesProvider.builder() .valuationDate(valuationDate[loopvaldate]) .indexCurves(ImmutableMap.of(CHF_TOIS, onCurve)) .timeSeries(ImmutableMap.of(CHF_TOIS, TIME_SERIES_BUILDER.build())) .build(); OvernightAveragedRateObservation ro = OvernightAveragedRateObservation.of(CHF_TOIS, FIXING_START_DATE, FIXING_END_DATE, 0); ForwardOvernightAveragedRateObservationFn obsFn = ForwardOvernightAveragedRateObservationFn.DEFAULT; PointSensitivityBuilder sensitivityBuilderComputed = obsFn.rateSensitivity(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, prov); CurveCurrencyParameterSensitivities parameterSensitivityComputed = prov.curveParameterSensitivity(sensitivityBuilderComputed.build()); CurveCurrencyParameterSensitivities parameterSensitivityExpected = CAL_FD.sensitivity( prov, (p) -> CurrencyAmount.of( CHF_TOIS.getCurrency(), obsFn.rate(ro, DUMMY_ACCRUAL_START_DATE, DUMMY_ACCRUAL_END_DATE, (p)))); assertTrue( parameterSensitivityComputed.equalWithTolerance( parameterSensitivityExpected, EPS_FD * 10.0)); } }
private FxSingle parseLeg( XmlElement legEl, FpmlDocument document, TradeInfo.Builder tradeInfoBuilder) { // supported elements: // 'exchangedCurrency1/paymentAmount' // 'exchangedCurrency2/paymentAmount' // 'valueDate' // ignored elements: // 'dealtCurrency?' // 'exchangeRate' // rejected elements: // 'nonDeliverableSettlement?' // 'currency1ValueDate' // 'currency2ValueDate' document.validateNotPresent(legEl, "currency1ValueDate"); document.validateNotPresent(legEl, "currency2ValueDate"); document.validateNotPresent(legEl, "nonDeliverableSettlement"); XmlElement curr1El = legEl.getChild("exchangedCurrency1"); XmlElement curr2El = legEl.getChild("exchangedCurrency2"); // pay/receive and counterparty PayReceive curr1PayReceive = document.parsePayerReceiver(curr1El, tradeInfoBuilder); PayReceive curr2PayReceive = document.parsePayerReceiver(curr2El, tradeInfoBuilder); if (curr1PayReceive == curr2PayReceive) { throw new FpmlParseException( "FX single leg currencies must not have same Pay/Receive direction"); } // amount CurrencyAmount curr1Amount = document.parseCurrencyAmount(curr1El.getChild("paymentAmount")); CurrencyAmount curr2Amount = document.parseCurrencyAmount(curr2El.getChild("paymentAmount")); if (curr1PayReceive == PayReceive.PAY) { curr1Amount = curr1Amount.negative(); curr2Amount = curr2Amount.positive(); } else { curr1Amount = curr1Amount.positive(); curr2Amount = curr2Amount.negative(); } // payment date LocalDate valueDate = document.parseDate(legEl.getChild("valueDate")); // result return FxSingle.of(curr1Amount, curr2Amount, valueDate); }
/** Test {@link FxNdfFunctionGroups}. */ @Test public class FxNdfFunctionGroupsTest { private static final FxRate FX_RATE = FxRate.of(GBP, USD, 1.5d); private static final CurrencyAmount NOTIONAL = CurrencyAmount.of(GBP, (double) 100_000_000); private static final FxNdf PRODUCT = FxNdf.builder() .agreedFxRate(FX_RATE) .settlementCurrencyNotional(NOTIONAL) .index(GBP_USD_WM) .paymentDate(date(2015, 3, 19)) .build(); public static final FxNdfTrade TRADE = FxNdfTrade.builder() .tradeInfo(TradeInfo.builder().tradeDate(date(2015, 6, 1)).build()) .product(PRODUCT) .build(); public void test_discounting() { FunctionGroup<FxNdfTrade> test = FxNdfFunctionGroups.discounting(); assertThat(test.configuredMeasures(TRADE)) .contains( Measure.PRESENT_VALUE, Measure.PV01, Measure.BUCKETED_PV01, Measure.CURRENCY_EXPOSURE, Measure.FORWARD_FX_RATE); } public void test_presentValue() { Currency ccy1 = TRADE.getProduct().getNonDeliverableCurrency(); Currency ccy2 = TRADE.getProduct().getSettlementCurrency(); LocalDate valDate = TRADE.getProduct().getPaymentDate().plusDays(7); FunctionConfig<FxNdfTrade> config = FxNdfFunctionGroups.discounting().functionConfig(TRADE, Measure.PRESENT_VALUE).get(); CalculationSingleFunction<FxNdfTrade, ?> function = config.createFunction(); FunctionRequirements reqs = function.requirements(TRADE); assertThat(reqs.getOutputCurrencies()).containsOnly(ccy1, ccy2); assertThat(reqs.getSingleValueRequirements()) .isEqualTo(ImmutableSet.of(DiscountCurveKey.of(ccy1), DiscountCurveKey.of(ccy2))); assertThat(reqs.getTimeSeriesRequirements()).isEqualTo(ImmutableSet.of()); assertThat(function.defaultReportingCurrency(TRADE)).hasValue(GBP); DiscountFactors df1 = SimpleDiscountFactors.of( ccy1, valDate, ConstantNodalCurve.of(Curves.discountFactors("Test", ACT_360), 0.99)); DiscountFactors df2 = SimpleDiscountFactors.of( ccy2, valDate, ConstantNodalCurve.of(Curves.discountFactors("Test", ACT_360), 0.99)); TestMarketDataMap md = new TestMarketDataMap( valDate, ImmutableMap.of(DiscountCurveKey.of(ccy1), df1, DiscountCurveKey.of(ccy2), df2), ImmutableMap.of()); assertThat(function.execute(TRADE, md)) .isEqualTo(FxConvertibleList.of(ImmutableList.of(CurrencyAmount.zero(GBP)))); } // ------------------------------------------------------------------------- public void coverage() { coverPrivateConstructor(FxNdfFunctionGroups.class); } public void coverage_functions() { Currency ccy1 = TRADE.getProduct().getNonDeliverableCurrency(); Currency ccy2 = TRADE.getProduct().getSettlementCurrency(); LocalDate valDate = TRADE.getProduct().getPaymentDate().plusDays(7); Curve df = ConstantNodalCurve.of(Curves.discountFactors("Test", ACT_360), 0.99); FxRate fxRate = FxRate.of(ccy1, ccy2, 1.6d); TestMarketDataMap md = new TestMarketDataMap( valDate, ImmutableMap.of( DiscountCurveKey.of(ccy1), df, DiscountCurveKey.of(ccy2), df, FxRateKey.of(ccy1, ccy2), fxRate), ImmutableMap.of( IndexRateKey.of(GBP_USD_WM), LocalDateDoubleTimeSeries.of(date(2015, 3, 17), 1.45d))); assertNotNull(new FxNdfBucketedPv01Function().execute(TRADE, md)); assertNotNull(new FxNdfCurrencyExposureFunction().execute(TRADE, md)); assertNotNull(new FxNdfForwardFxRateFunction().execute(TRADE, md)); assertNotNull(new FxNdfPv01Function().execute(TRADE, md)); assertNotNull(new FxNdfPvFunction().execute(TRADE, md)); } }