/** * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.pricer.fxopt; import static org.testng.AssertJUnit.assertEquals; import org.testng.annotations.Test; import com.opengamma.strata.basics.value.ValueDerivatives; import com.opengamma.strata.collect.array.DoubleArray; import com.opengamma.strata.pricer.impl.option.BlackFormulaRepository; /** * Test {@link SmileDeltaParameters}. */ @Test public class SmileDeltaParametersTest { private static final double TIME_TO_EXPIRY = 2.0; private static final double FORWARD = 1.40; private static final double ATM = 0.185; private static final DoubleArray DELTA = DoubleArray.of(0.10, 0.25); private static final DoubleArray RISK_REVERSAL = DoubleArray.of(-0.0130, -0.0050); private static final DoubleArray STRANGLE = DoubleArray.of(0.0300, 0.0100); private static final SmileDeltaParameters SMILE = SmileDeltaParameters.of( TIME_TO_EXPIRY, ATM, DELTA, RISK_REVERSAL, STRANGLE); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDelta() { SmileDeltaParameters.of(TIME_TO_EXPIRY, ATM, null, RISK_REVERSAL, STRANGLE); } @Test(expectedExceptions = IllegalArgumentException.class) public void testRRLength() { SmileDeltaParameters.of(TIME_TO_EXPIRY, ATM, DELTA, DoubleArray.filled(3), STRANGLE); } @Test(expectedExceptions = IllegalArgumentException.class) public void testStrangleLength() { SmileDeltaParameters.of(TIME_TO_EXPIRY, ATM, DELTA, RISK_REVERSAL, DoubleArray.filled(3)); } /** * Tests the constructor directly from volatilities (not RR and S). */ public void constructorVolatility() { DoubleArray volatility = SMILE.getVolatility(); SmileDeltaParameters smileFromVolatility = SmileDeltaParameters.of(TIME_TO_EXPIRY, DELTA, volatility); assertEquals("Smile by delta: constructor", SMILE, smileFromVolatility); } /** * Tests the getters. */ public void getter() { assertEquals("Smile by delta: time to expiry", TIME_TO_EXPIRY, SMILE.getExpiry()); assertEquals("Smile by delta: delta", DELTA, SMILE.getDelta()); SmileDeltaParameters smile2 = SmileDeltaParameters.of(TIME_TO_EXPIRY, DELTA, SMILE.getVolatility()); assertEquals("Smile by delta: volatility", SMILE.getVolatility(), smile2.getVolatility()); } /** * Tests the volatility computations. */ public void volatility() { DoubleArray volatility = SMILE.getVolatility(); int nbDelta = DELTA.size(); assertEquals("Volatility: ATM", ATM, volatility.get(nbDelta)); for (int loopdelta = 0; loopdelta < nbDelta; loopdelta++) { assertEquals( "Volatility: Risk Reversal " + loopdelta, RISK_REVERSAL.get(loopdelta), volatility.get(2 * nbDelta - loopdelta) - volatility.get(loopdelta), 1e-8); assertEquals( "Volatility: Strangle " + loopdelta, STRANGLE.get(loopdelta), (volatility.get(2 * nbDelta - loopdelta) + volatility.get(loopdelta)) / 2 - volatility.get(nbDelta), 1e-8); } } /** * Tests the strikes computations. */ public void strike() { double[] strike = SMILE.strike(FORWARD).toArrayUnsafe(); DoubleArray volatility = SMILE.getVolatility(); int nbDelta = DELTA.size(); for (int loopdelta = 0; loopdelta < nbDelta; loopdelta++) { ValueDerivatives dPut = BlackFormulaRepository.priceAdjoint( FORWARD, strike[loopdelta], TIME_TO_EXPIRY, volatility.get(loopdelta), false); assertEquals("Strike: Put " + loopdelta, dPut.getDerivative(0), -DELTA.get(loopdelta), 1e-8); ValueDerivatives dCall = BlackFormulaRepository.priceAdjoint( FORWARD, strike[2 * nbDelta - loopdelta], TIME_TO_EXPIRY, volatility.get(2 * nbDelta - loopdelta), true); assertEquals("Strike: Call " + loopdelta, dCall.getDerivative(0), DELTA.get(loopdelta), 1e-8); } ValueDerivatives dPut = BlackFormulaRepository.priceAdjoint( FORWARD, strike[nbDelta], TIME_TO_EXPIRY, volatility.get(nbDelta), false); ValueDerivatives dCall = BlackFormulaRepository.priceAdjoint( FORWARD, strike[nbDelta], TIME_TO_EXPIRY, volatility.get(nbDelta), true); assertEquals("Strike: ATM", dCall.getDerivative(0) + dPut.getDerivative(0), 0.0, 1e-8); } }