// -------------------------------------------------------------------------
 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);
 }
Example #2
0
 /**
  * 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);
 }
Example #24
0
/** 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));
    }
  }
Example #29
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));
  }
}