public void positivityClampedMultiTest() {
    final double[] xValues = new double[] {1., 2., 3., 4., 5.};
    final double[][] yValues =
        new double[][] {{0., 0.1, 1., 1., 20., 5., 0.}, {-10., 0.1, 1., 1., 20., 5., 0.}};

    PiecewisePolynomialInterpolator interp = new CubicSplineInterpolator();
    PiecewisePolynomialResult result = interp.interpolate(xValues, yValues);

    PiecewisePolynomialFunction1D function = new PiecewisePolynomialFunction1D();

    PiecewisePolynomialInterpolator interpPos =
        new NonnegativityPreservingCubicSplineInterpolator(interp);
    PiecewisePolynomialResult resultPos = interpPos.interpolate(xValues, yValues);

    assertEquals(resultPos.getDimensions(), result.getDimensions());
    assertEquals(resultPos.getNumberOfIntervals(), result.getNumberOfIntervals());
    assertEquals(resultPos.getOrder(), result.getOrder());

    final int nPts = 101;
    for (int i = 0; i < 101; ++i) {
      final double key = 1. + 4. / (nPts - 1) * i;
      assertTrue(function.evaluate(resultPos, key).get(0) >= 0.);
    }

    int dim = yValues.length;
    int nData = xValues.length;
    for (int j = 0; j < dim; ++j) {
      for (int i = 1; i < nData - 2; ++i) {
        DoubleMatrix coefMatrix = resultPos.getCoefMatrix();
        double tau = Math.signum(coefMatrix.get(dim * i + j, 3));
        assertTrue(
            coefMatrix.get(dim * i + j, 2) * tau
                >= -3. * yValues[j][i + 1] * tau / (xValues[i + 1] - xValues[i]));
        assertTrue(
            coefMatrix.get(dim * i + j, 2) * tau
                <= 3. * yValues[j][i + 1] * tau / (xValues[i] - xValues[i - 1]));
      }
    }
  }
/** Test {@link BlackFxVanillaOptionTradePricer}. */
@Test
public class BlackFxVanillaOptionTradePricerTest {

  private static final LocalDate VAL_DATE = RatesProviderDataSets.VAL_DATE_2014_01_22;
  private static final LocalTime VAL_TIME = LocalTime.of(13, 45);
  private static final ZoneId ZONE = ZoneId.of("Z");
  private static final ZonedDateTime VAL_DATE_TIME = VAL_DATE.atTime(VAL_TIME).atZone(ZONE);
  private static final ZonedDateTime EXPIRY = ZonedDateTime.of(2014, 5, 9, 13, 10, 0, 0, ZONE);

  private static final FxMatrix FX_MATRIX = RatesProviderFxDataSets.fxMatrix();
  private static final RatesProvider RATES_PROVIDER =
      RatesProviderFxDataSets.createProviderEURUSD(VAL_DATE);

  private static final DoubleArray TIME_TO_EXPIRY =
      DoubleArray.of(0.01, 0.252, 0.501, 1.0, 2.0, 5.0);
  private static final DoubleArray ATM = DoubleArray.of(0.175, 0.185, 0.18, 0.17, 0.16, 0.16);
  private static final DoubleArray DELTA = DoubleArray.of(0.10, 0.25);
  private static final DoubleMatrix RISK_REVERSAL =
      DoubleMatrix.ofUnsafe(
          new double[][] {
            {-0.010, -0.0050}, {-0.011, -0.0060}, {-0.012, -0.0070},
            {-0.013, -0.0080}, {-0.014, -0.0090}, {-0.014, -0.0090}
          });
  private static final DoubleMatrix STRANGLE =
      DoubleMatrix.ofUnsafe(
          new double[][] {
            {0.0300, 0.0100},
            {0.0310, 0.0110},
            {0.0320, 0.0120},
            {0.0330, 0.0130},
            {0.0340, 0.0140},
            {0.0340, 0.0140}
          });
  private static final InterpolatedStrikeSmileDeltaTermStructure SMILE_TERM =
      InterpolatedStrikeSmileDeltaTermStructure.of(
          TIME_TO_EXPIRY, DELTA, ATM, RISK_REVERSAL, STRANGLE, ACT_365F);
  private static final CurrencyPair CURRENCY_PAIR = CurrencyPair.of(EUR, USD);
  private static final BlackFxOptionSmileVolatilities VOLS =
      BlackFxOptionSmileVolatilities.of(
          FxOptionVolatilitiesName.of("Test"), CURRENCY_PAIR, VAL_DATE_TIME, SMILE_TERM);

  private static final LocalDate PAYMENT_DATE = LocalDate.of(2014, 5, 13);
  private static final double NOTIONAL = 1.0e6;
  private static final CurrencyAmount EUR_AMOUNT = CurrencyAmount.of(EUR, NOTIONAL);
  private static final CurrencyAmount USD_AMOUNT =
      CurrencyAmount.of(USD, -NOTIONAL * FX_MATRIX.fxRate(EUR, USD));
  private static final ResolvedFxSingle FX_PRODUCT =
      ResolvedFxSingle.of(EUR_AMOUNT, USD_AMOUNT, PAYMENT_DATE);
  private static final ResolvedFxVanillaOption OPTION_PRODUCT =
      ResolvedFxVanillaOption.builder()
          .longShort(SHORT)
          .expiry(EXPIRY)
          .underlying(FX_PRODUCT)
          .build();
  private static final TradeInfo TRADE_INFO = TradeInfo.builder().tradeDate(VAL_DATE).build();
  private static final LocalDate CASH_SETTLE_DATE = LocalDate.of(2014, 1, 25);
  private static final Payment PREMIUM = Payment.of(EUR, NOTIONAL * 0.027, CASH_SETTLE_DATE);
  private static final ResolvedFxVanillaOptionTrade OPTION_TRADE =
      ResolvedFxVanillaOptionTrade.builder()
          .premium(PREMIUM)
          .product(OPTION_PRODUCT)
          .info(TRADE_INFO)
          .build();

  private static final BlackFxVanillaOptionProductPricer PRICER_PRODUCT =
      BlackFxVanillaOptionProductPricer.DEFAULT;
  private static final BlackFxVanillaOptionTradePricer PRICER_TRADE =
      BlackFxVanillaOptionTradePricer.DEFAULT;
  private static final DiscountingPaymentPricer PRICER_PAYMENT = DiscountingPaymentPricer.DEFAULT;
  private static final double TOL = 1.0e-13;

  public void test_presentValue() {
    MultiCurrencyAmount pvSensiTrade =
        PRICER_TRADE.presentValue(OPTION_TRADE, RATES_PROVIDER, VOLS);
    CurrencyAmount pvSensiProduct =
        PRICER_PRODUCT.presentValue(OPTION_PRODUCT, RATES_PROVIDER, VOLS);
    CurrencyAmount pvSensiPremium = PRICER_PAYMENT.presentValue(PREMIUM, RATES_PROVIDER);
    assertEquals(pvSensiTrade, MultiCurrencyAmount.of(pvSensiProduct, pvSensiPremium));
  }

  public void test_presentValueSensitivity() {
    PointSensitivities pvSensiTrade =
        PRICER_TRADE.presentValueSensitivityRates(OPTION_TRADE, RATES_PROVIDER, VOLS);
    PointSensitivities pvSensiProduct =
        PRICER_PRODUCT.presentValueSensitivityRates(OPTION_PRODUCT, RATES_PROVIDER, VOLS);
    PointSensitivities pvSensiPremium =
        PRICER_PAYMENT.presentValueSensitivity(PREMIUM, RATES_PROVIDER).build();
    assertEquals(pvSensiTrade, pvSensiProduct.combinedWith(pvSensiPremium));
  }

  public void test_presentValueSensitivityBlackVolatility() {
    PointSensitivities pvSensiTrade =
        PRICER_TRADE.presentValueSensitivityModelParamsVolatility(
            OPTION_TRADE, RATES_PROVIDER, VOLS);
    PointSensitivities pvSensiProduct =
        PRICER_PRODUCT
            .presentValueSensitivityModelParamsVolatility(OPTION_PRODUCT, RATES_PROVIDER, VOLS)
            .build();
    assertEquals(pvSensiTrade, pvSensiProduct);
  }

  public void test_currencyExposure() {
    MultiCurrencyAmount ceComputed =
        PRICER_TRADE.currencyExposure(OPTION_TRADE, RATES_PROVIDER, VOLS);
    PointSensitivities point =
        PRICER_TRADE.presentValueSensitivityRates(OPTION_TRADE, RATES_PROVIDER, VOLS);
    MultiCurrencyAmount pv = PRICER_TRADE.presentValue(OPTION_TRADE, RATES_PROVIDER, VOLS);
    MultiCurrencyAmount ceExpected = RATES_PROVIDER.currencyExposure(point).plus(pv);
    assertEquals(ceComputed.size(), 2);
    assertEquals(
        ceComputed.getAmount(EUR).getAmount(),
        ceExpected.getAmount(EUR).getAmount(),
        TOL * NOTIONAL);
    assertEquals(
        ceComputed.getAmount(USD).getAmount(),
        ceExpected.getAmount(USD).getAmount(),
        TOL * NOTIONAL);
  }

  public void test_currentCash_zero() {
    assertEquals(
        PRICER_TRADE.currentCash(OPTION_TRADE, VAL_DATE),
        CurrencyAmount.zero(PREMIUM.getCurrency()));
  }

  public void test_currentCash_onSettle() {
    assertEquals(PRICER_TRADE.currentCash(OPTION_TRADE, CASH_SETTLE_DATE), PREMIUM.getValue());
  }
}
Example #3
0
 /**
  * Transposes the matrix.
  *
  * <p>This converts a matrix of {@code m x n} into a matrix of {@code n x m}. Each element is
  * moved to the opposite position.
  *
  * @return the transposed matrix
  */
 public DoubleMatrix transpose() {
   return DoubleMatrix.of(columns, rows, (i, j) -> array[j][i]);
 }