@Test /** Test the present value using the method with the direct formula with extrapolation. */ public void presentValueAboveCutOff() { CurrencyAmount methodPrice = METHOD.presentValue(CAP_HIGH_LONG, SABR_BUNDLE); final double df = CURVES.getCurve(FUNDING_CURVE_NAME).getDiscountFactor(CAP_HIGH_LONG.getPaymentTime()); final double forward = CAP_HIGH_LONG.accept(PRC, CURVES); final double maturity = CAP_HIGH_LONG.getFixingPeriodEndTime() - CAP_LONG.getFixingPeriodStartTime(); final DoublesPair expiryMaturity = new DoublesPair(CAP_HIGH_LONG.getFixingTime(), maturity); final double alpha = SABR_PARAMETERS.getAlpha(expiryMaturity); final double beta = SABR_PARAMETERS.getBeta(expiryMaturity); final double rho = SABR_PARAMETERS.getRho(expiryMaturity); final double nu = SABR_PARAMETERS.getNu(expiryMaturity); final SABRFormulaData sabrParam = new SABRFormulaData(alpha, beta, rho, nu); final SABRExtrapolationRightFunction sabrExtrapolation = new SABRExtrapolationRightFunction( forward, sabrParam, CUT_OFF_STRIKE, CAP_HIGH_LONG.getFixingTime(), MU); final EuropeanVanillaOption option = new EuropeanVanillaOption( CAP_HIGH_LONG.getStrike(), CAP_HIGH_LONG.getFixingTime(), CAP_HIGH_LONG.isCap()); final double expectedPrice = sabrExtrapolation.price(option) * CAP_HIGH_LONG.getNotional() * CAP_HIGH_LONG.getPaymentYearFraction() * df; assertEquals( "Cap/floor: SABR with extrapolation pricing", expectedPrice, methodPrice.getAmount(), 1E-2); methodPrice = METHOD.presentValue(CAP_HIGH_LONG, SABR_BUNDLE); assertEquals( "Cap/floor: SABR with extrapolation pricing", expectedPrice, methodPrice.getAmount(), 1E-2); }
@Test(enabled = false) /** Tests of performance. "enabled = false" for the standard testing. */ public void performance() { long startTime, endTime; final int nbTest = 1000; CurrencyAmount pvPayerLongExplicit = CurrencyAmount.of(CUR, 0.0); CurrencyAmount pvPayerLongIntegration = CurrencyAmount.of(CUR, 0.0); startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { pvPayerLongExplicit = METHOD_HW_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_HW); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " pv swaption Hull-White approximation method: " + (endTime - startTime) + " ms"); // Performance note: HW price: 8-Jul-11: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: 330 ms for // 10000 swaptions. startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { METHOD_HW_APPROXIMATION.presentValueHullWhiteSensitivity(SWAPTION_PAYER_LONG, BUNDLE_HW); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " HW sensitivity swaption Hull-White approximation method: " + (endTime - startTime) + " ms"); // Performance note: HW parameters sensitivity: 8-Jul-11: On Mac Pro 3.2 GHz Quad-Core Intel // Xeon: 525 ms for 10000 swaptions. startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { METHOD_HW_APPROXIMATION.presentValueCurveSensitivity(SWAPTION_PAYER_LONG, BUNDLE_HW); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " curve sensitivity swaption Hull-White approximation method: " + (endTime - startTime) + " ms"); // Performance note: HW curve sensitivity: 8-Jul-11: On Mac Pro 3.2 GHz Quad-Core Intel Xeon: // 550 ms for 10000 swaptions. startTime = System.currentTimeMillis(); for (int looptest = 0; looptest < nbTest; looptest++) { pvPayerLongIntegration = METHOD_HW_INTEGRATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_HW); } endTime = System.currentTimeMillis(); System.out.println( nbTest + " cash swaption Hull-White numerical integration method: " + (endTime - startTime) + " ms"); // Performance note: HW numerical integration: 8-Jul-11: On Mac Pro 3.2 GHz Quad-Core Intel // Xeon: 1300 ms for 10000 swaptions. double difference = 0.0; difference = pvPayerLongExplicit.getAmount() - pvPayerLongIntegration.getAmount(); System.out.println("Difference: " + difference); }
@Test public void presentValueApproximation() { CurrencyAmount pvNumericalIntegration = METHOD_NI.presentValue(CPN_CMS, BUNDLE_HW); CurrencyAmount pvApproximation = METHOD_APP.presentValue(CPN_CMS, BUNDLE_HW); assertEquals( "Coupon CMS - Hull-White - present value - approximation", pvApproximation.getAmount(), pvNumericalIntegration.getAmount(), TOLERANCE_PRICE_APP); }
@Test /** Test the present value using the method with the direct formula with extrapolation. */ public void presentValueLongShortParityAboveCutOff() { final CurrencyAmount priceLong = METHOD.presentValue(CAP_HIGH_LONG, SABR_BUNDLE); final CurrencyAmount priceShort = METHOD.presentValue(CAP_HIGH_SHORT, SABR_BUNDLE); assertEquals( "Cap/floor: SABR with extrapolation pricing: long/short parity", priceLong.getAmount(), -priceShort.getAmount(), 1E-2); }
@Test /** Tests long/short parity. */ public void longShortParity() { CurrencyAmount pvLong = METHOD_HW_INTEGRATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_HW); CurrencyAmount pvShort = METHOD_HW_INTEGRATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_HW); assertEquals( "Swaption cash - Hull-White - present value - long/short parity", pvLong.getAmount(), -pvShort.getAmount(), 1E-2); }
@Test /** Test the present value by approximation vs by numerical integration. */ public void approximationNumericalIntegration() { CurrencyAmount pvApproximation = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); CurrencyAmount pvNI = METHOD_G2PP_NI.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - approximation vs Numerical integration", pvApproximation.getAmount(), pvNI.getAmount(), 2.0E+3); }
@Test /** Test the cap/floor/forward parity above the cut-off strike. */ public void presentValueCapFloorParityAboveCutOff() { final CurrencyAmount priceCap = METHOD.presentValue(CAP_HIGH_LONG, SABR_BUNDLE); final CurrencyAmount priceFloor = METHOD.presentValue(FLOOR_HIGH_SHORT, SABR_BUNDLE); final double priceCouponStrike = COUPON_STRIKE_HIGH.accept(PVC, CURVES); final double priceCouponIbor = COUPON_IBOR.accept(PVC, CURVES); assertEquals( "Cap/floor: SABR with extrapolation pricing: cap/floor parity", priceCouponIbor - priceCouponStrike, priceCap.getAmount() + priceFloor.getAmount(), 1E-2); }
@Test /** Tests payer/receiver/swap parity. */ public void payerReceiverParity() { CurrencyAmount pvReceiverLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_G2PP); CurrencyAmount pvPayerShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_G2PP); double pvSwap = PVC.visit(SWAP_RECEIVER, CURVES); assertEquals( "Swaption physical - G2++ - present value - payer/receiver/swap parity", pvReceiverLong.getAmount() + pvPayerShort.getAmount(), pvSwap, 1E-2); }
@Override protected Set<ComputedValue> getResult( final ForexDerivative fxOption, final SmileDeltaTermStructureDataBundle data, final FunctionInputs inputs, final ComputationTarget target) { final MultipleCurrencyAmount result = CALCULATOR.visit(fxOption, data); final int n = result.size(); final Currency[] keys = new Currency[n]; final double[] values = new double[n]; int i = 0; for (final CurrencyAmount ca : result) { keys[i] = ca.getCurrency(); values[i++] = ca.getAmount(); } final ValueProperties properties = createValueProperties() .with(ValuePropertyNames.PAY_CURVE, getPutCurveName()) .with(ValuePropertyNames.RECEIVE_CURVE, getCallCurveName()) .with(ValuePropertyNames.SURFACE, getSurfaceName()) .get(); final ValueSpecification spec = new ValueSpecification(getValueRequirementName(), target.toSpecification(), properties); return Collections.singleton( new ComputedValue(spec, new CurrencyLabelledMatrix1D(keys, values))); }
@Test public void presentValueNumericalIntegration() { CurrencyAmount pvNumericalIntegration = METHOD_NI.presentValue(CPN_CMS, BUNDLE_HW); double pvPrevious = 1124760.482; // From previous run assertEquals( "Coupon CMS - Hull-White - present value - numerical integration", pvPrevious, pvNumericalIntegration.getAmount(), TOLERANCE_PRICE); // Comparison with non-adjusted figures: to have the right order of magnitude CurrencyAmount pvDiscounting = METHOD_DSC.presentValue(CPN_CMS, BUNDLE_HW); assertEquals( "Coupon CMS - Hull-White - present value - numerical integration", 1.0, pvDiscounting.getAmount() / pvNumericalIntegration.getAmount(), 0.20); }
@Test /** Tests long/short parity. */ public void scaling() { double scale = 12.3; SwapFixedIborDefinition scaledSwapDefinition = SwapFixedIborDefinition.from( SETTLEMENT_DATE, CMS_INDEX, scale * NOTIONAL, RATE, FIXED_IS_PAYER); SwaptionCashFixedIborDefinition scaledSwaptionDefinition = SwaptionCashFixedIborDefinition.from(EXPIRY_DATE, scaledSwapDefinition, IS_LONG); SwaptionCashFixedIbor scaledSwaption = scaledSwaptionDefinition.toDerivative(REFERENCE_DATE, CURVES_NAME); CurrencyAmount pvOriginal = METHOD_HW_INTEGRATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_HW); CurrencyAmount pvScaled = METHOD_HW_INTEGRATION.presentValue(scaledSwaption, BUNDLE_HW); assertEquals( "Swaption cash - Hull-White - present value - scaling", scale * pvOriginal.getAmount(), pvScaled.getAmount(), 1E-1); }
@Override public Set<ComputedValue> execute( final FunctionExecutionContext executionContext, final FunctionInputs inputs, final ComputationTarget target, final Set<ValueRequirement> desiredValues) { final FXFutureSecurity security = (FXFutureSecurity) target.getSecurity(); final Clock snapshotClock = executionContext.getValuationClock(); final ZonedDateTime now = ZonedDateTime.now(snapshotClock); final Currency payCurrency = security.getNumerator(); final Object payCurveObject = inputs.getValue( YieldCurveFunction.getCurveRequirement(payCurrency, _payCurveName, null, null)); if (payCurveObject == null) { throw new OpenGammaRuntimeException("Could not get " + _payCurveName + " curve"); } final Currency receiveCurrency = security.getDenominator(); final Object receiveCurveObject = inputs.getValue( YieldCurveFunction.getCurveRequirement(receiveCurrency, _receiveCurveName, null, null)); if (receiveCurveObject == null) { throw new OpenGammaRuntimeException("Could not get " + _receiveCurveName + " curve"); } // TODO: The convention is only looked up here so that we can convert the spot rate; would be // better to request the spot rate using the correct currency pair in the first place final CurrencyPairs currencyPairs = OpenGammaExecutionContext.getCurrencyPairsSource(executionContext) .getCurrencyPairs(CurrencyPairs.DEFAULT_CURRENCY_PAIRS); final CurrencyPair currencyPair = currencyPairs.getCurrencyPair(payCurrency, receiveCurrency); final Currency currencyBase = currencyPair.getBase(); final Object spotObject = inputs.getValue(ValueRequirementNames.SPOT_RATE); if (spotObject == null) { throw new OpenGammaRuntimeException("Could not get market data for spot rate"); } double spot = (Double) spotObject; if (!receiveCurrency.equals(currencyBase) && receiveCurrency.equals(security.getCurrency())) { spot = 1. / spot; } final YieldAndDiscountCurve payCurve = (YieldAndDiscountCurve) payCurveObject; final YieldAndDiscountCurve receiveCurve = (YieldAndDiscountCurve) receiveCurveObject; final SimpleFXFutureDataBundle data = new SimpleFXFutureDataBundle(payCurve, receiveCurve, spot); final SimpleInstrument instrument = security.accept(CONVERTER).toDerivative(now); final CurrencyAmount pv = instrument.accept(CALCULATOR, data); final ValueProperties properties = createValueProperties() .with(ValuePropertyNames.PAY_CURVE, _payCurveName) .with(ValuePropertyNames.RECEIVE_CURVE, _receiveCurveName) .with(ValuePropertyNames.CURRENCY, pv.getCurrency().getCode()) .get(); final ValueSpecification spec = new ValueSpecification( ValueRequirementNames.PRESENT_VALUE, target.toSpecification(), properties); return Collections.singleton(new ComputedValue(spec, pv.getAmount())); }
@Test /** Tests the present value: Method vs Calculator */ public void presentValueMethodVsCalculator() { final CurrencyAmount pvMethod = METHOD_SECURITY.presentValue(BILL_IAM_SEC, CURVE_BUNDLE); final double pvCalculator = BILL_IAM_SEC.accept(PVC, CURVE_BUNDLE); assertEquals( "Bill Security: discounting method - present value", pvMethod.getAmount(), pvCalculator, TOLERANCE_PV); }
@Test(enabled = true) /** Test the present value vs a hard-coded value. */ public void presentValue() { CurrencyAmount pv = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); double pvExpected = 4893110.87; assertEquals( "Swaption physical - G2++ - present value - hard coded value", pvExpected, pv.getAmount(), 1E-2); }
@Test /** Tests the present value against explicit computation. */ public void presentValue() { final CurrencyAmount pvComputed = METHOD_SECURITY.presentValue(BILL_IAM_SEC, CURVE_BUNDLE); final double pvExpected = NOTIONAL * CURVE_BUNDLE.getCurve(NAME_CURVES[1]).getDiscountFactor(BILL_IAM_SEC.getEndTime()); assertEquals( "Bill Security: discounting method - present value", pvExpected, pvComputed.getAmount(), TOLERANCE_PV); }
@Test public void priceFromCurves() { final double priceComputed = METHOD_SECURITY.priceFromCurves(BILL_IAM_SEC, CURVE_BUNDLE); final CurrencyAmount pvComputed = METHOD_SECURITY.presentValue(BILL_IAM_SEC, CURVE_BUNDLE); final double priceExpected = pvComputed.getAmount() / (NOTIONAL * CURVE_BUNDLE .getCurve(NAME_CURVES[0]) .getDiscountFactor(BILL_IAM_SEC.getSettlementTime())); assertEquals( "Bill Security: discounting method - price", priceExpected, priceComputed, TOLERANCE_PRICE); }
public static CurrencyLabelledMatrix1D getMultipleCurrencyAmountAsMatrix( final MultipleCurrencyAmount mca) { ArgumentChecker.notNull(mca, "multiple currency amount"); final int n = mca.size(); final Currency[] keys = new Currency[n]; final double[] values = new double[n]; int i = 0; for (final CurrencyAmount ca : mca) { keys[i] = ca.getCurrency(); values[i++] = ca.getAmount(); } return new CurrencyLabelledMatrix1D(keys, values); }
@Test /** Tests long/short parity. */ public void longShortParity() { CurrencyAmount pvPayerLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_G2PP); CurrencyAmount pvPayerShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - long/short parity", pvPayerLong.getAmount(), -pvPayerShort.getAmount(), 1E-2); CurrencyAmount pvReceiverLong = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_G2PP); CurrencyAmount pvReceiverShort = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_RECEIVER_SHORT, BUNDLE_G2PP); assertEquals( "Swaption physical - G2++ - present value - long/short parity", pvReceiverLong.getAmount(), -pvReceiverShort.getAmount(), 1E-2); }
@Test /** Test the present value using the method with the direct formula with extrapolation. */ public void presentValueMethodVsCalculator() { final SABRInterestRateDataBundle sabrExtraBundle = new SABRInterestRateDataBundle(SABR_PARAMETERS, CURVES); final CurrencyAmount pvMethod = METHOD.presentValue(CAP_LONG, SABR_BUNDLE); final PresentValueSABRExtrapolationCalculator pvc = new PresentValueSABRExtrapolationCalculator(CUT_OFF_STRIKE, MU); final double pvCalculator = CAP_LONG.accept(pvc, sabrExtraBundle); assertEquals( "Cap/floor: SABR with extrapolation pricing - Method vs Calculator", pvMethod.getAmount(), pvCalculator, 1E-2); }
@Test public void testPayCashFlowsNoNetting() { for (final InstrumentDefinition<?> definition : NO_NETTING_PAY_INSTRUMENTS) { final TreeMap<LocalDate, MultipleCurrencyAmount> pay = new TreeMap<LocalDate, MultipleCurrencyAmount>(definition.accept(PAY_CASH_FLOWS)); final TreeMap<LocalDate, MultipleCurrencyAmount> netted = new TreeMap<LocalDate, MultipleCurrencyAmount>(definition.accept(VISITOR)); assertEquals(pay.size(), netted.size()); assertEquals(pay.keySet(), netted.keySet()); final Iterator<Map.Entry<LocalDate, MultipleCurrencyAmount>> nettedIterator = netted.entrySet().iterator(); for (final Map.Entry<LocalDate, MultipleCurrencyAmount> payEntry : pay.entrySet()) { final Map.Entry<LocalDate, MultipleCurrencyAmount> nettedEntry = nettedIterator.next(); assertEquals(payEntry.getKey(), nettedEntry.getKey()); assertEquals(payEntry.getValue().size(), nettedEntry.getValue().size()); final Iterator<CurrencyAmount> nettedMCAIterator = nettedEntry.getValue().iterator(); for (final CurrencyAmount payCA : payEntry.getValue()) { final CurrencyAmount nettedCA = nettedMCAIterator.next(); assertEquals(payCA.getCurrency(), nettedCA.getCurrency()); assertEquals(payCA.getAmount(), -nettedCA.getAmount()); } } } }
@Test public void presentValueFromYield() { final CurrencyAmount pvComputed = METHOD_SECURITY.presentValueFromYield(BILL_IAM_SEC, YIELD, CURVE_BUNDLE); final double price = METHOD_SECURITY.priceFromYield(BILL_IAM_SEC, YIELD); final double pvExpected = NOTIONAL * price * CURVE_BUNDLE .getCurve(NAME_CURVES[0]) .getDiscountFactor(BILL_IAM_SEC.getSettlementTime()); assertEquals( "Bill Security: discounting method - present value", pvExpected, pvComputed.getAmount(), TOLERANCE_PV); }
@Test /** Check the conversion of a multiple currency amount. */ public void convert() { final FXMatrix fxMatrix = new FXMatrix(); fxMatrix.addCurrency(EUR, USD, EUR_USD); fxMatrix.addCurrency(GBP, EUR, GBP_EUR); final double amountGBP = 1.0; final double amountEUR = 2.0; final double amountUSD = 3.0; MultipleCurrencyAmount amount = MultipleCurrencyAmount.of(GBP, amountGBP); amount = amount.plus(EUR, amountEUR); amount = amount.plus(USD, amountUSD); final CurrencyAmount totalUSDCalculated = fxMatrix.convert(amount, USD); final double totalUSDExpected = amountUSD + amountEUR * EUR_USD + amountGBP * GBP_EUR * EUR_USD; assertEquals("FXMatrix - convert", totalUSDExpected, totalUSDCalculated.getAmount(), 1.0E-10); assertEquals("FXMatrix - convert", USD, totalUSDCalculated.getCurrency()); }
@Test /** Tests the present value. */ public void presentValue() { CurrencyAmount pv = METHOD.presentValue(ZERO_COUPON_1, MARKET); double df = MARKET .getCurve(ZERO_COUPON_1.getCurrency()) .getDiscountFactor(ZERO_COUPON_1.getPaymentTime()); double indexMonth0 = MARKET.getCurve(PRICE_INDEX_EUR).getPriceIndex(ZERO_COUPON_1.getReferenceEndTime()[0]); double indexMonth1 = MARKET.getCurve(PRICE_INDEX_EUR).getPriceIndex(ZERO_COUPON_1.getReferenceEndTime()[1]); double finalIndex = ZERO_COUPON_1_DEFINITION.getWeight() * indexMonth0 + (1 - ZERO_COUPON_1_DEFINITION.getWeight()) * indexMonth1; double pvExpected = (finalIndex / INDEX_MAY_2008_INT - 1) * df * NOTIONAL; assertEquals("Zero-coupon inflation: Present value", pvExpected, pv.getAmount(), 1.0E-2); }
@Test /** Compare approximate formula with numerical integration. */ public void comparison() { double bp1 = 10000; CurrencyAmount pvPayerLongExplicit = METHOD_HW_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_HW); CurrencyAmount pvPayerLongIntegration = METHOD_HW_INTEGRATION.presentValue(SWAPTION_PAYER_LONG, BUNDLE_HW); assertEquals( "Swaption cash - Hull-White - present value - explicit/numerical integration", pvPayerLongExplicit.getAmount() / NOTIONAL * bp1, pvPayerLongIntegration.getAmount() / NOTIONAL * bp1, 3.0E-1); CurrencyAmount pvPayerShortExplicit = METHOD_HW_APPROXIMATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_HW); CurrencyAmount pvPayerShortIntegration = METHOD_HW_INTEGRATION.presentValue(SWAPTION_PAYER_SHORT, BUNDLE_HW); assertEquals( "Swaption cash - Hull-White - present value - explicit/numerical integration", pvPayerShortExplicit.getAmount() / NOTIONAL * bp1, pvPayerShortIntegration.getAmount() / NOTIONAL * bp1, 3.0E-1); CurrencyAmount pvReceiverLongExplicit = METHOD_HW_APPROXIMATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_HW); CurrencyAmount pvReceiverLongIntegration = METHOD_HW_INTEGRATION.presentValue(SWAPTION_RECEIVER_LONG, BUNDLE_HW); assertEquals( "Swaption cash - Hull-White - present value - explicit/numerical integration", pvReceiverLongExplicit.getAmount() / NOTIONAL * bp1, pvReceiverLongIntegration.getAmount() / NOTIONAL * bp1, 5.0E-1); CurrencyAmount pvReceiverShortExplicit = METHOD_HW_APPROXIMATION.presentValue(SWAPTION_RECEIVER_SHORT, BUNDLE_HW); CurrencyAmount pvReceiverShortIntegration = METHOD_HW_INTEGRATION.presentValue(SWAPTION_RECEIVER_SHORT, BUNDLE_HW); assertEquals( "Swaption cash - Hull-White - present value - explicit/numerical integration", pvReceiverShortExplicit.getAmount() / NOTIONAL * bp1, pvReceiverShortIntegration.getAmount() / NOTIONAL * bp1, 5.0E-1); }
@Override protected Set<ComputedValue> getResult( final InstrumentDerivative fxDigital, final ForexOptionDataBundle<?> data, final ComputationTarget target, final Set<ValueRequirement> desiredValues, final FunctionInputs inputs, final ValueSpecification spec, final FunctionExecutionContext executionContext) { final String spreadName = Iterables.getOnlyElement(desiredValues) .getConstraint(CalculationPropertyNamesAndValues.PROPERTY_CALL_SPREAD_VALUE); final double spread = Double.parseDouble(spreadName); final PresentValueBlackVolatilitySensitivityCallSpreadBlackForexCalculator calculator = new PresentValueBlackVolatilitySensitivityCallSpreadBlackForexCalculator(spread); final PresentValueForexBlackVolatilitySensitivity result = fxDigital.accept(calculator, data); final CurrencyAmount vegaValue = result.toSingleValue(); return Collections.singleton(new ComputedValue(spec, vegaValue.getAmount())); }
@Test /** Tests the present value for curves with seasonal adjustment. */ public void presentValueSeasonality() { MarketBundle marketSeason = MarketDataSets.createMarket2(PRICING_DATE); int tenorYear = 5; double notional = 100000000; ZonedDateTime settleDate = ScheduleCalculator.getAdjustedDate(PRICING_DATE, USDLIBOR3M.getSpotLag(), CALENDAR_USD); ZonedDateTime paymentDate = ScheduleCalculator.getAdjustedDate( settleDate, Period.ofYears(tenorYear), BUSINESS_DAY, CALENDAR_USD, USDLIBOR3M.isEndOfMonth()); double weightSettle = 1.0 - (settleDate.getDayOfMonth() - 1.0) / settleDate.getMonthOfYear().getLastDayOfMonth(settleDate.isLeapYear()); double indexStart = weightSettle * 225.964 + (1 - weightSettle) * 225.722; CouponInflationZeroCouponInterpolationDefinition zeroCouponUsdDefinition = CouponInflationZeroCouponInterpolationDefinition.from( settleDate, paymentDate, notional, PRICE_INDEX_US, indexStart, MONTH_LAG, false); CouponInflationZeroCouponInterpolation zeroCouponUsd = zeroCouponUsdDefinition.toDerivative(PRICING_DATE, "not used"); CurrencyAmount pvInflation = METHOD.presentValue(zeroCouponUsd, marketSeason); double df = MARKET .getCurve(zeroCouponUsd.getCurrency()) .getDiscountFactor(zeroCouponUsd.getPaymentTime()); double indexMonth0 = marketSeason.getCurve(PRICE_INDEX_US).getPriceIndex(zeroCouponUsd.getReferenceEndTime()[0]); double indexMonth1 = marketSeason.getCurve(PRICE_INDEX_US).getPriceIndex(zeroCouponUsd.getReferenceEndTime()[1]); double finalIndex = zeroCouponUsdDefinition.getWeight() * indexMonth0 + (1 - zeroCouponUsdDefinition.getWeight()) * indexMonth1; double pvExpected = (finalIndex / indexStart - 1) * df * notional; assertEquals( "PV in market with seasonal adjustment", pvExpected, pvInflation.getAmount(), 1E-2); }
@Test(enabled = false) /** * Test the present value vs a external system. "enabled = false" for the standard testing: the * external system is using a TimeCalculator with ACT/365. */ public void presentValueExternal() { G2ppPiecewiseConstantParameters parametersCst = G2ppTestsDataSet.createG2ppCstParameters(); final YieldAndDiscountCurve curve5 = new YieldCurve(ConstantDoublesCurve.from(0.05)); final YieldCurveBundle curves = new YieldCurveBundle(); curves.setCurve(FUNDING_CURVE_NAME, curve5); curves.setCurve(FORWARD_CURVE_NAME, curve5); G2ppPiecewiseConstantDataBundle bundleCst = new G2ppPiecewiseConstantDataBundle(parametersCst, curves); CurrencyAmount pv = METHOD_G2PP_APPROXIMATION.presentValue(SWAPTION_PAYER_LONG, bundleCst); double pvExternal = 6885626.28245924; // ! TimeCalculator with ACT/365 assertEquals( "Swaption physical - G2++ - present value - external system", pvExternal, pv.getAmount(), 1E-2); }
@Test /** * Test the present value SABR parameters sensitivity against a finite difference computation; * strike above the cut-off strike. */ public void testPresentValueSABRSensitivityAboveCutOff() { final YieldCurveBundle curves = TestsDataSetsSABR.createCurves1(); final SABRInterestRateParameters sabrParameter = TestsDataSetsSABR.createSABR1(); final SABRInterestRateDataBundle sabrBundle = new SABRInterestRateDataBundle(sabrParameter, curves); final CurrencyAmount pv = METHOD.presentValue(CAP_HIGH_LONG, sabrBundle); final PresentValueSABRSensitivityDataBundle pvsCapLong = METHOD.presentValueSABRSensitivity(CAP_HIGH_LONG, sabrBundle); PresentValueSABRSensitivityDataBundle pvsCapShort = METHOD.presentValueSABRSensitivity(CAP_HIGH_SHORT, sabrBundle); // Long/short parity pvsCapShort = pvsCapShort.multiplyBy(-1.0); assertEquals(pvsCapShort.getAlpha(), pvsCapLong.getAlpha()); // SABR sensitivity vs finite difference final double shift = 0.0001; final double shiftAlpha = 0.00001; final DoublesPair expectedExpiryTenor = new DoublesPair( CAP_HIGH_LONG.getFixingTime(), CAP_HIGH_LONG.getFixingPeriodEndTime() - CAP_HIGH_LONG.getFixingPeriodStartTime()); // Alpha sensitivity vs finite difference computation final SABRInterestRateParameters sabrParameterAlphaBumped = TestsDataSetsSABR.createSABR1AlphaBumped(shiftAlpha); final SABRInterestRateDataBundle sabrBundleAlphaBumped = new SABRInterestRateDataBundle(sabrParameterAlphaBumped, curves); final CurrencyAmount pvLongPayerAlphaBumped = METHOD.presentValue(CAP_HIGH_LONG, sabrBundleAlphaBumped); final double expectedAlphaSensi = (pvLongPayerAlphaBumped.getAmount() - pv.getAmount()) / shiftAlpha; assertEquals("Number of alpha sensitivity", pvsCapLong.getAlpha().getMap().keySet().size(), 1); assertEquals( "Alpha sensitivity expiry/tenor", pvsCapLong.getAlpha().getMap().keySet().contains(expectedExpiryTenor), true); assertEquals( "Alpha sensitivity value", expectedAlphaSensi, pvsCapLong.getAlpha().getMap().get(expectedExpiryTenor), 1.0E-0); // Rho sensitivity vs finite difference computation final SABRInterestRateParameters sabrParameterRhoBumped = TestsDataSetsSABR.createSABR1RhoBumped(); final SABRInterestRateDataBundle sabrBundleRhoBumped = new SABRInterestRateDataBundle(sabrParameterRhoBumped, curves); final CurrencyAmount pvLongPayerRhoBumped = METHOD.presentValue(CAP_HIGH_LONG, sabrBundleRhoBumped); final double expectedRhoSensi = (pvLongPayerRhoBumped.getAmount() - pv.getAmount()) / shift; assertEquals("Number of rho sensitivity", pvsCapLong.getRho().getMap().keySet().size(), 1); assertEquals( "Rho sensitivity expiry/tenor", pvsCapLong.getRho().getMap().keySet().contains(expectedExpiryTenor), true); assertEquals( "Rho sensitivity value", pvsCapLong.getRho().getMap().get(expectedExpiryTenor), expectedRhoSensi, 1.0E-1); // Alpha sensitivity vs finite difference computation final SABRInterestRateParameters sabrParameterNuBumped = TestsDataSetsSABR.createSABR1NuBumped(); final SABRInterestRateDataBundle sabrBundleNuBumped = new SABRInterestRateDataBundle(sabrParameterNuBumped, curves); final CurrencyAmount pvLongPayerNuBumped = METHOD.presentValue(CAP_HIGH_LONG, sabrBundleNuBumped); final double expectedNuSensi = (pvLongPayerNuBumped.getAmount() - pv.getAmount()) / shift; assertEquals("Number of nu sensitivity", pvsCapLong.getNu().getMap().keySet().size(), 1); assertEquals( "Nu sensitivity expiry/tenor", pvsCapLong.getNu().getMap().keySet().contains(expectedExpiryTenor), true); assertEquals( "Nu sensitivity value", pvsCapLong.getNu().getMap().get(expectedExpiryTenor), expectedNuSensi, 2.0E-1); }