ValueDerivatives computed = PRICER.priceAdjoint( SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier); double spotUp = PRICER.price( SPOT + EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier); double spotDw = PRICER.price( SPOT - EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier); double rateUp = PRICER.price( SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM + EPS_FD, VOLATILITY, barrier); double rateDw = PRICER.price( SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM - EPS_FD, VOLATILITY, barrier); double costUp = PRICER.price( SPOT, EXPIRY_TIME, COST_OF_CARRY + EPS_FD, RATE_DOM, VOLATILITY, barrier); double costDw = PRICER.price( SPOT, EXPIRY_TIME, COST_OF_CARRY - EPS_FD, RATE_DOM, VOLATILITY, barrier); double volUp = PRICER.price( SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY + EPS_FD, barrier); double volDw = PRICER.price( SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY - EPS_FD, barrier); double timeUp = PRICER.price( SPOT, EXPIRY_TIME + EPS_FD, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier); double timeDw = PRICER.price( SPOT, EXPIRY_TIME - EPS_FD, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier); ValueDerivatives spotUp1 = PRICER.priceAdjoint( SPOT + EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier); ValueDerivatives spotDw1 = PRICER.priceAdjoint( SPOT - EPS_FD, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, barrier); assertEquals(computed.getDerivative(0), 0.5 * (spotUp - spotDw) / EPS_FD, EPS_FD);
double[] fDerivSecond = new double[5]; double price = isKnockIn ? getFAdjoint(spot, z, lognormalVolT, h, mu, lambda, eta, h, fDerivFirst, fDerivSecond) : getEAdjoint(spot, df1, x2, y2, h, mu, eta, eDerivFirst, eDerivSecond); double zBar = 0.0; double y2Bar = 0.0;
/** * standard in-out parity holds if r=0. */ public void inOutParity() { double upIn = PRICER.price(SPOT, EXPIRY_TIME, RATE_DOM, RATE_DOM, VOLATILITY, BARRIER_UP_IN); double upOut = PRICER.price(SPOT, EXPIRY_TIME, RATE_DOM, RATE_DOM, VOLATILITY, BARRIER_UP_OUT); double downIn = PRICER.price(SPOT, EXPIRY_TIME, RATE_DOM, RATE_DOM, VOLATILITY, BARRIER_DOWN_IN); double downOut = PRICER.price(SPOT, EXPIRY_TIME, RATE_DOM, RATE_DOM, VOLATILITY, BARRIER_DOWN_OUT); assertRelative(upIn + upOut, SPOT, TOL); assertRelative(downIn + downOut, SPOT, TOL); }
.priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKO).getDerivative(3); double expectedAsset = ASSET_REBATE_PRICER .priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKI).getDerivative(3); double expectedCall = BARRIER_PRICER.priceAdjoint(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, true, BARRIER_UKI).getDerivative(4) + rebateRate * expectedCash;
/** * Upper barrier level is very high. */ public void largeBarrierTest() { SimpleConstantContinuousBarrier in = SimpleConstantContinuousBarrier.of(BarrierType.UP, KnockType.KNOCK_IN, 1.0e4); SimpleConstantContinuousBarrier out = SimpleConstantContinuousBarrier .of(BarrierType.UP, KnockType.KNOCK_OUT, 1.0e4); double upIn = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, in); double upOut = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, out); assertRelative(upIn, 0d, TOL); assertRelative(upOut, FWD_FX * DF_DOM, TOL); }
public void test_delta_presentValueDelta() { double computedDeltaCall = PRICER.delta(CALL_UKI, RATE_PROVIDER, VOLS); double computedDeltaPut = PRICER.delta(PUT_UKO_BASE, RATE_PROVIDER, VOLS); CurrencyAmount computedPvDeltaCall = PRICER.presentValueDelta(CALL_UKI, RATE_PROVIDER, VOLS); CurrencyAmount computedPvDeltaPut = PRICER.presentValueDelta(PUT_UKO_BASE, RATE_PROVIDER, VOLS); double rateBase = RATE_PROVIDER.discountFactors(EUR).zeroRate(PAY_DATE); double rateCounter = RATE_PROVIDER.discountFactors(USD).zeroRate(PAY_DATE); double costOfCarry = rateCounter - rateBase; double forward = RATE_PROVIDER.fxForwardRates(CURRENCY_PAIR).rate(EUR, PAY_DATE); double volatility = VOLS.volatility(CURRENCY_PAIR, EXPIRY_DATETIME, STRIKE_RATE, forward); double timeToExpiry = VOLS.relativeTime(EXPIRY_DATETIME); double rebateRate = REBATE_AMOUNT / NOTIONAL; double expectedCash = CASH_REBATE_PRICER .priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKO).getDerivative(0); double expectedAsset = ASSET_REBATE_PRICER .priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKI).getDerivative(0); double expectedDeltaCall = BARRIER_PRICER.priceAdjoint(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, true, BARRIER_UKI).getDerivative(0) + rebateRate * expectedCash; double expectedDeltaPut = BARRIER_PRICER.priceAdjoint(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, false, BARRIER_UKO).getDerivative(0) + rebateRate * expectedAsset; assertEquals(computedDeltaCall, expectedDeltaCall, TOL); assertEquals(computedDeltaPut, expectedDeltaPut, TOL); assertEquals(computedPvDeltaCall.getCurrency(), USD); assertEquals(computedPvDeltaPut.getCurrency(), USD); assertEquals(computedPvDeltaCall.getAmount(), expectedDeltaCall * NOTIONAL, TOL); assertEquals(computedPvDeltaPut.getAmount(), -expectedDeltaPut * NOTIONAL, TOL); }
/** * Barrier event has occured already. */ public void illegalBarrierLevelTest() { assertThrowsIllegalArg(() -> PRICER.price(BARRIER_UP_IN.getBarrierLevel() + 0.1, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_UP_IN)); assertThrowsIllegalArg(() -> PRICER.price(BARRIER_DOWN_OUT.getBarrierLevel() - 0.1, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_DOWN_OUT)); assertThrowsIllegalArg(() -> PRICER.priceAdjoint(BARRIER_UP_IN.getBarrierLevel() + 0.1, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_UP_IN)); assertThrowsIllegalArg(() -> PRICER.priceAdjoint(BARRIER_DOWN_OUT.getBarrierLevel() - 0.1, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, BARRIER_DOWN_OUT)); }
/** * Lower barrier level is very small. */ public void smallBarrierTest() { SimpleConstantContinuousBarrier in = SimpleConstantContinuousBarrier.of(BarrierType.DOWN, KnockType.KNOCK_IN, 0.1d); SimpleConstantContinuousBarrier out = SimpleConstantContinuousBarrier.of(BarrierType.DOWN, KnockType.KNOCK_OUT, 0.1d); double dwIn = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, in); double dwOut = PRICER.price(SPOT, EXPIRY_TIME, COST_OF_CARRY, RATE_DOM, VOLATILITY, out); assertRelative(dwIn, 0d, TOL); assertRelative(dwOut, FWD_FX * DF_DOM, TOL); }
public void test_gamma_presentValueGamma() { double computedGammaCall = PRICER.gamma(CALL_UKI, RATE_PROVIDER, VOLS); double computedGammaPut = PRICER.gamma(PUT_UKO_BASE, RATE_PROVIDER, VOLS); CurrencyAmount computedPvGammaCall = PRICER.presentValueGamma(CALL_UKI, RATE_PROVIDER, VOLS); CurrencyAmount computedPvGammaPut = PRICER.presentValueGamma(PUT_UKO_BASE, RATE_PROVIDER, VOLS); double rateBase = RATE_PROVIDER.discountFactors(EUR).zeroRate(PAY_DATE); double rateCounter = RATE_PROVIDER.discountFactors(USD).zeroRate(PAY_DATE); double costOfCarry = rateCounter - rateBase; double forward = RATE_PROVIDER.fxForwardRates(CURRENCY_PAIR).rate(EUR, PAY_DATE); double volatility = VOLS.volatility(CURRENCY_PAIR, EXPIRY_DATETIME, STRIKE_RATE, forward); double timeToExpiry = VOLS.relativeTime(EXPIRY_DATETIME); double rebateRate = REBATE_AMOUNT / NOTIONAL; double expectedCash = CASH_REBATE_PRICER .priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKO).getDerivative(5); double expectedAsset = ASSET_REBATE_PRICER .priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKI).getDerivative(5); double expectedGammaCall = BARRIER_PRICER.priceAdjoint(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, true, BARRIER_UKI).getDerivative(6) + rebateRate * expectedCash; double expectedGammaPut = BARRIER_PRICER.priceAdjoint(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, false, BARRIER_UKO).getDerivative(6) + rebateRate * expectedAsset; assertEquals(computedGammaCall, expectedGammaCall, TOL); assertEquals(computedGammaPut, expectedGammaPut, TOL); assertEquals(computedPvGammaCall.getCurrency(), USD); assertEquals(computedPvGammaPut.getCurrency(), USD); assertEquals(computedPvGammaCall.getAmount(), expectedGammaCall * NOTIONAL, TOL); assertEquals(computedPvGammaPut.getAmount(), -expectedGammaPut * NOTIONAL, TOL); }
/** * smoothly connected to limiting cases. */ public void smallsigmaTTest() { for (SimpleConstantContinuousBarrier barrier : BARRIERS) { double volUp = 2.0e-3; double volDw = 1.0e-3; double time = 1.0e-2; double optUp = PRICER.price(SPOT, time, COST_OF_CARRY, RATE_DOM, volUp, barrier); double optDw = PRICER.price(SPOT, time, COST_OF_CARRY, RATE_DOM, volDw, barrier); assertRelative(optUp, optDw, 1.0e-3); ValueDerivatives optUpAdj = PRICER.priceAdjoint(SPOT, time, COST_OF_CARRY, RATE_DOM, volUp, barrier); ValueDerivatives optDwAdj = PRICER.priceAdjoint(SPOT, time, COST_OF_CARRY, RATE_DOM, volDw, barrier); assertRelative(optUpAdj.getValue(), optDwAdj.getValue(), 1.0e-3); for (int i = 0; i < 6; ++i) { assertRelative(optUpAdj.getDerivative(i), optDwAdj.getDerivative(i), TOL); } } }
public void test_price_presentValue() { double computedPriceCall = PRICER.price(CALL_UKI, RATE_PROVIDER, VOLS); double computedPricePut = PRICER.price(PUT_UKO_BASE, RATE_PROVIDER, VOLS); CurrencyAmount computedPvCall = PRICER.presentValue(CALL_UKI, RATE_PROVIDER, VOLS); CurrencyAmount computedPvPut = PRICER.presentValue(PUT_UKO_BASE, RATE_PROVIDER, VOLS); double rateBase = RATE_PROVIDER.discountFactors(EUR).zeroRate(PAY_DATE); double rateCounter = RATE_PROVIDER.discountFactors(USD).zeroRate(PAY_DATE); double costOfCarry = rateCounter - rateBase; double forward = RATE_PROVIDER.fxForwardRates(CURRENCY_PAIR).rate(EUR, PAY_DATE); double volatility = VOLS.volatility(CURRENCY_PAIR, EXPIRY_DATETIME, STRIKE_RATE, forward); double timeToExpiry = VOLS.relativeTime(EXPIRY_DATETIME); double rebateRate = REBATE_AMOUNT / NOTIONAL; double expectedCash = CASH_REBATE_PRICER.price(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKO); double expectedAsset = ASSET_REBATE_PRICER.price(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKI); double expectedPriceCall = BARRIER_PRICER.price(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, true, BARRIER_UKI) + rebateRate * expectedCash; double expectedPricePut = BARRIER_PRICER.price(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, false, BARRIER_UKO) + rebateRate * expectedAsset; assertEquals(computedPriceCall, expectedPriceCall, TOL); assertEquals(computedPricePut, expectedPricePut, TOL); assertEquals(computedPvCall.getCurrency(), USD); assertEquals(computedPvPut.getCurrency(), USD); assertEquals(computedPvCall.getAmount(), expectedPriceCall * NOTIONAL, TOL); assertEquals(computedPvPut.getAmount(), -expectedPricePut * NOTIONAL, TOL); }
public void test_theta_presentValueTheta() { double computedThetaCall = PRICER.theta(CALL_UKI, RATE_PROVIDER, VOLS); double computedThetaPut = PRICER.theta(PUT_UKO_BASE, RATE_PROVIDER, VOLS); CurrencyAmount computedPvThetaCall = PRICER.presentValueTheta(CALL_UKI, RATE_PROVIDER, VOLS); CurrencyAmount computedPvThetaPut = PRICER.presentValueTheta(PUT_UKO_BASE, RATE_PROVIDER, VOLS); double rateBase = RATE_PROVIDER.discountFactors(EUR).zeroRate(PAY_DATE); double rateCounter = RATE_PROVIDER.discountFactors(USD).zeroRate(PAY_DATE); double costOfCarry = rateCounter - rateBase; double forward = RATE_PROVIDER.fxForwardRates(CURRENCY_PAIR).rate(EUR, PAY_DATE); double volatility = VOLS.volatility(CURRENCY_PAIR, EXPIRY_DATETIME, STRIKE_RATE, forward); double timeToExpiry = VOLS.relativeTime(EXPIRY_DATETIME); double rebateRate = REBATE_AMOUNT / NOTIONAL; double expectedCash = CASH_REBATE_PRICER .priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKO).getDerivative(4); double expectedAsset = ASSET_REBATE_PRICER .priceAdjoint(SPOT, timeToExpiry, costOfCarry, rateCounter, volatility, BARRIER_UKI).getDerivative(4); double expectedThetaCall = BARRIER_PRICER.priceAdjoint(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, true, BARRIER_UKI).getDerivative(5) + rebateRate * expectedCash; double expectedThetaPut = BARRIER_PRICER.priceAdjoint(SPOT, STRIKE_RATE, timeToExpiry, costOfCarry, rateCounter, volatility, false, BARRIER_UKO).getDerivative(5) + rebateRate * expectedAsset; expectedThetaCall *= -1d; expectedThetaPut *= -1d; assertEquals(computedThetaCall, expectedThetaCall, TOL); assertEquals(computedThetaPut, expectedThetaPut, TOL); assertEquals(computedPvThetaCall.getCurrency(), USD); assertEquals(computedPvThetaPut.getCurrency(), USD); assertEquals(computedPvThetaCall.getAmount(), expectedThetaCall * NOTIONAL, TOL); assertEquals(computedPvThetaPut.getAmount(), -expectedThetaPut * NOTIONAL, TOL); }
double priceRebate = rebate.getCurrency().equals(ccyCounter) ? CASH_REBATE_PRICER.price(todayFx, timeToExpiry, costOfCarry, rateCounter, volatility, barrier.inverseKnockType()) : ASSET_REBATE_PRICER.price(todayFx, timeToExpiry, costOfCarry, rateCounter, volatility, barrier.inverseKnockType()); price += priceRebate * rebate.getAmount() / Math.abs(underlyingFx.getBaseCurrencyPayment().getAmount());
ValueDerivatives valueDerivativesRebate = rebate.getCurrency().equals(ccyCounter) ? CASH_REBATE_PRICER.priceAdjoint(todayFx, timeToExpiry, costOfCarry, rateCounter, volatility, barrier.inverseKnockType()) : ASSET_REBATE_PRICER.priceAdjoint(todayFx, timeToExpiry, costOfCarry, rateCounter, volatility, barrier.inverseKnockType()); double rebateRate = rebate.getAmount() / Math.abs(underlyingFx.getBaseCurrencyPayment().getAmount()); double price = valueDerivatives.getValue() + rebateRate * valueDerivativesRebate.getValue();