/** Test. */ @Test(groups = TestGroup.UNIT) public class ForwardStartOptionModelTest { private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1); private static final double R = 0.08; private static final YieldCurve CURVE = YieldCurve.from(ConstantDoublesCurve.from(R)); private static final VolatilitySurface SURFACE = new VolatilitySurface(ConstantDoublesSurface.from(0.3)); private static final double B = 0.04; private static final double SPOT = 60; private static final double PERCENT = 0.1; private static final ZonedDateTime START = DateUtils.getDateOffsetWithYearFraction(DATE, 0.25); private static final ZonedDateTime EXPIRY = DateUtils.getDateOffsetWithYearFraction(DATE, 1); private static final StandardOptionDataBundle DATA = new StandardOptionDataBundle(CURVE, B, SURFACE, SPOT, DATE); private static final ForwardStartOptionDefinition FORWARD = new ForwardStartOptionDefinition( new Expiry(EXPIRY), true, new Expiry(START), PERCENT, Moneyness.OTM); private static final ForwardStartOptionDefinition NOW = new ForwardStartOptionDefinition( new Expiry(EXPIRY), true, new Expiry(DATE), PERCENT, Moneyness.OTM); private static final ForwardStartOptionDefinition END = new ForwardStartOptionDefinition( new Expiry(EXPIRY), true, new Expiry(EXPIRY), PERCENT, Moneyness.OTM); private static final EuropeanVanillaOptionDefinition VANILLA = new EuropeanVanillaOptionDefinition(SPOT * (1 + PERCENT), new Expiry(EXPIRY), true); private static final AnalyticOptionModel<ForwardStartOptionDefinition, StandardOptionDataBundle> MODEL = new ForwardStartOptionModel(); private static final AnalyticOptionModel<OptionDefinition, StandardOptionDataBundle> BSM = new BlackScholesMertonModel(); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDefinition() { MODEL.getPricingFunction(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { MODEL.getPricingFunction(FORWARD).evaluate((StandardOptionDataBundle) null); } @Test public void test() { assertEquals(MODEL.getPricingFunction(END).evaluate(DATA), 0, 0); assertEquals( MODEL .getPricingFunction(FORWARD) .evaluate( DATA.withVolatilitySurface( new VolatilitySurface(ConstantDoublesSurface.from(1e-9)))), 0, 0); assertEquals( MODEL.getPricingFunction(NOW).evaluate(DATA), BSM.getPricingFunction(VANILLA).evaluate(DATA), 1e-4); assertEquals(MODEL.getPricingFunction(FORWARD).evaluate(DATA), 4.4064, 1e-4); } }
public class ProductOptionModelTest { private static final double S1 = 100; private static final double S2 = 105; private static final YieldAndDiscountCurve R = new YieldCurve(ConstantDoublesCurve.from(0.07)); private static final double B1 = 0.02; private static final double B2 = 0.05; private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1); private static final ProductOptionModel MODEL = new ProductOptionModel(); private static final Expiry EXPIRY1 = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.1)); private static final Expiry EXPIRY2 = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.5)); private static final double EPS = 1e-4; @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDefinition() { MODEL.getPricingFunction(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { MODEL .getPricingFunction(new ProductOptionDefinition(0.1, EXPIRY1, true)) .evaluate((StandardTwoAssetOptionDataBundle) null); } @Test public void test() { ProductOptionDefinition option = new ProductOptionDefinition(15000, EXPIRY1, true); StandardTwoAssetOptionDataBundle data = new StandardTwoAssetOptionDataBundle( R, B1, B2, new VolatilitySurface(ConstantDoublesSurface.from(0.2)), new VolatilitySurface(ConstantDoublesSurface.from(0.3)), S1, S2, -0.5, DATE); assertEquals(MODEL.getPricingFunction(option).evaluate(data), 0.0028, EPS); data = data.withFirstVolatilitySurface(new VolatilitySurface(ConstantDoublesSurface.from(0.3))) .withCorrelation(0); assertEquals(MODEL.getPricingFunction(option).evaluate(data), 2.4026, EPS); option = new ProductOptionDefinition(15000, EXPIRY2, true); assertEquals(MODEL.getPricingFunction(option).evaluate(data), 266.1594, EPS); } }
@Test public void test() { boolean isCall; double spot, strike, b, price; Expiry expiry; YieldAndDiscountCurve curve; EuropeanVanillaOptionDefinition definition; StandardOptionDataBundle initialData, data; double sigma = 0.01; for (int i = 0; i < 100; i++) { expiry = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, RANDOM.nextDouble() * 2)); sigma += 0.03; spot = 2 * RANDOM.nextDouble() + 10; strike = 2 * RANDOM.nextDouble() + 10; curve = YieldCurve.from(ConstantDoublesCurve.from(RANDOM.nextDouble() / 10)); b = 0; // RANDOM.nextDouble() / 20; isCall = RANDOM.nextDouble() < 0.5 ? true : false; definition = new EuropeanVanillaOptionDefinition(strike, expiry, isCall); initialData = new StandardOptionDataBundle(curve, b, null, spot, DATE); data = new StandardOptionDataBundle( curve, b, new VolatilitySurface(ConstantDoublesSurface.from(sigma)), spot, DATE); price = BSM.getPricingFunction(definition).evaluate(data); assertEquals( sigma, MODEL .getSurface( Collections.<OptionDefinition, Double>singletonMap(definition, price), initialData) .getVolatility(DoublesPair.of(0., 0.)), EPS); } }
@Test public void testEqualsAndHashCode() { final OptionDefinition call1 = new FloatingStrikeLookbackOptionDefinition(EXPIRY, true); final OptionDefinition put1 = new FloatingStrikeLookbackOptionDefinition(EXPIRY, false); final OptionDefinition call2 = new FloatingStrikeLookbackOptionDefinition( new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 3)), true); final OptionDefinition put2 = new FloatingStrikeLookbackOptionDefinition( new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 3)), false); assertFalse(CALL.equals(PUT)); assertEquals(call1, CALL); assertEquals(put1, PUT); assertEquals(call1.hashCode(), CALL.hashCode()); assertEquals(put1.hashCode(), PUT.hashCode()); assertFalse(call2.equals(CALL)); assertFalse(put2.equals(PUT)); }
@Test public void test() { assertEquals(PUT.getPeriodEnd(), PERIOD_END); assertFalse(PUT.isReverse()); ExtremeSpreadOptionDefinition other = new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, false); assertEquals(other, PUT); assertEquals(other.hashCode(), PUT.hashCode()); other = new ExtremeSpreadOptionDefinition( EXPIRY, false, new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.15)), false); assertFalse(other.equals(PUT)); other = new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, true); assertFalse(other.equals(PUT)); assertEquals(PUT.getTimeFromPeriodEnd(EXPIRY.getExpiry()), 0.725, 0); assertEquals(PUT.getTimeFromPeriodEnd(DATE), -0.275, 0); }
/** Test. */ @Test(groups = TestGroup.UNIT) public class LogOptionModelTest { private static final AnalyticOptionModel<LogOptionDefinition, StandardOptionDataBundle> MODEL = new LogOptionModel(); private static final Set<Greek> REQUIRED_GREEKS = Collections.singleton(Greek.FAIR_PRICE); private static final ZonedDateTime DATE = DateUtils.getUTCDate(2009, 1, 1); private static final Expiry EXPIRY = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.75)); private static final YieldAndDiscountCurve CURVE = YieldCurve.from(ConstantDoublesCurve.from(0.08)); private static final double B = 0.04; private static final double SPOT = 100; private static final double EPS = 1e-4; @Test public void test() { LogOptionDefinition definition = getDefinition(70); assertPriceEquals(definition, 0.2, 0.3510); assertPriceEquals(definition, 0.3, 0.3422); assertPriceEquals(definition, 0.4, 0.3379); assertPriceEquals(definition, 0.5, 0.3365); assertPriceEquals(definition, 0.6, 0.3362); definition = getDefinition(130); assertPriceEquals(definition, 0.2, 0.0056); assertPriceEquals(definition, 0.3, 0.0195); assertPriceEquals(definition, 0.4, 0.0363); assertPriceEquals(definition, 0.5, 0.0532); assertPriceEquals(definition, 0.6, 0.0691); } private void assertPriceEquals( final LogOptionDefinition definition, final double sigma, final double price) { final StandardOptionDataBundle bundle = getBundle(sigma); final GreekResultCollection actual = MODEL.getGreeks(definition, bundle, REQUIRED_GREEKS); assertEquals(actual.get(Greek.FAIR_PRICE), price, EPS); } private StandardOptionDataBundle getBundle(final double sigma) { return new StandardOptionDataBundle( CURVE, B, new VolatilitySurface(ConstantDoublesSurface.from(sigma)), SPOT, DATE); } private LogOptionDefinition getDefinition(final double strike) { return new LogOptionDefinition(strike, EXPIRY); } }
public class RelativeOutperformanceOptionModelTest { private static final double S1 = 130; private static final double S2 = 100; private static final YieldAndDiscountCurve R = YieldCurve.from(ConstantDoublesCurve.from(0.07)); private static final double B1 = 0.05; private static final double B2 = 0.03; private static final VolatilitySurface SIGMA1 = new VolatilitySurface(ConstantDoublesSurface.from(0.3)); private static final VolatilitySurface SIGMA2 = new VolatilitySurface(ConstantDoublesSurface.from(0.4)); private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1); private static final RelativeOutperformanceOptionModel MODEL = new RelativeOutperformanceOptionModel(); private static final Expiry EXPIRY = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.25)); private static final double EPS = 1e-4; @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDefinition() { MODEL.getPricingFunction(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { MODEL .getPricingFunction(new RelativeOutperformanceOptionDefinition(0.1, EXPIRY, true)) .evaluate((StandardTwoAssetOptionDataBundle) null); } @Test public void test() { RelativeOutperformanceOptionDefinition option = new RelativeOutperformanceOptionDefinition(0.1, EXPIRY, true); StandardTwoAssetOptionDataBundle data = new StandardTwoAssetOptionDataBundle(R, B1, B2, SIGMA1, SIGMA2, S1, S2, -0.5, DATE); assertEquals(MODEL.getPricingFunction(option).evaluate(data), 1.2582, EPS); option = new RelativeOutperformanceOptionDefinition(0.5, EXPIRY, true); data = data.withCorrelation(0); assertEquals(MODEL.getPricingFunction(option).evaluate(data), 0.8449, EPS); option = new RelativeOutperformanceOptionDefinition(1, EXPIRY, true); data = data.withCorrelation(0.5); assertEquals(MODEL.getPricingFunction(option).evaluate(data), 0.3382, EPS); } }
@Test public void testEqualsAndHashCode() { FXVannaVolgaVolatilityCurveDataBundle other = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, VWB, DATE); assertEquals(DATA, other); assertEquals(DATA.hashCode(), other.hashCode()); other = new FXVannaVolgaVolatilityCurveDataBundle(-DELTA, RR, ATM, VWB, DATE); assertFalse(other.equals(DATA)); other = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, -RR, ATM, VWB, DATE); assertFalse(other.equals(DATA)); other = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM + 1, VWB, DATE); assertFalse(other.equals(DATA)); other = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, -VWB, DATE); assertFalse(other.equals(DATA)); other = new FXVannaVolgaVolatilityCurveDataBundle( DELTA, RR, ATM, VWB, DateUtils.getDateOffsetWithYearFraction(DATE, 1)); assertFalse(other.equals(DATA)); }
public class AsymmetricPowerOptionModelTest { private static final double B = 0.02; private static final double SPOT = 10; private static final double STRIKE = 100; private static final ZonedDateTime DATE = DateUtils.getUTCDate(2009, 1, 1); private static final Expiry EXPIRY = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.5)); private static final YieldAndDiscountCurve CURVE = new YieldCurve(ConstantDoublesCurve.from(0.08)); private static final VolatilitySurface SURFACE = new VolatilitySurface(ConstantDoublesSurface.from(0.1)); private static final StandardOptionDataBundle BUNDLE = new StandardOptionDataBundle(CURVE, B, SURFACE, SPOT, DATE); private static final AnalyticOptionModel< AsymmetricPowerOptionDefinition, StandardOptionDataBundle> MODEL = new AsymmetricPowerOptionModel(); private static final AnalyticOptionModel<OptionDefinition, StandardOptionDataBundle> BS_MODEL = new BlackScholesMertonModel(); private static final Set<Greek> REQUIRED_GREEKS = Collections.singleton(Greek.FAIR_PRICE); private static final double EPS = 1e-4; @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDefinition() { MODEL.getPricingFunction(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { MODEL .getPricingFunction(new AsymmetricPowerOptionDefinition(STRIKE, EXPIRY, 1, true)) .evaluate((StandardOptionDataBundle) null); } @Test public void test() { assertEquals(getPrice(1.9, true), 0.3102, EPS); assertEquals(getPrice(1.95, true), 1.9320, EPS); assertEquals(getPrice(2., true), 6.7862, EPS); assertEquals(getPrice(2.05, true), 15.8587, EPS); assertEquals(getPrice(2.1, true), 28.4341, EPS); assertEquals(getPrice(1.9, false), 18.2738, EPS); assertEquals(getPrice(1.95, false), 10.2890, EPS); assertEquals(getPrice(2., false), 4.3539, EPS); assertEquals(getPrice(2.05, false), 1.3089, EPS); assertEquals(getPrice(2.1, false), 0.2745, EPS); for (int i = 0; i < 5; i++) { final double power = 1.9 + 0.05 * i; assertEquals(getPrice(power, true), getBSPrice(power, true), EPS); assertEquals(getPrice(power, false), getBSPrice(power, false), EPS); } } private double getPrice(final double power, final boolean isCall) { return MODEL .getGreeks(getDefinition(power, isCall), BUNDLE, REQUIRED_GREEKS) .get(Greek.FAIR_PRICE); } private double getBSPrice(final double power, final boolean isCall) { final StandardOptionDataBundle bsBundle = getModifiedDataBundle(BUNDLE, power); return BS_MODEL .getGreeks(getDefinition(power, isCall), bsBundle, REQUIRED_GREEKS) .get(Greek.FAIR_PRICE); } private AsymmetricPowerOptionDefinition getDefinition(final double power, final boolean isCall) { return new AsymmetricPowerOptionDefinition(STRIKE, EXPIRY, power, isCall); } private StandardOptionDataBundle getModifiedDataBundle( final StandardOptionDataBundle data, final double p) { final double t = DateUtils.getDifferenceInYears(DATE, EXPIRY); final double spot = Math.pow(data.getSpot(), p); double sigma = data.getVolatility(t, STRIKE); final double b = p * (data.getCostOfCarry() + (p - 1) * sigma * sigma * 0.5); sigma *= p; return new StandardOptionDataBundle( CURVE, b, new VolatilitySurface(ConstantDoublesSurface.from(sigma)), spot, DATE); } }
public class PoweredOptionModelTest { private static final AnalyticOptionModel<PoweredOptionDefinition, StandardOptionDataBundle> POWERED_MODEL = new PoweredOptionModel(); private static final AnalyticOptionModel<OptionDefinition, StandardOptionDataBundle> BSM = new BlackScholesMertonModel(); private static final Set<Greek> REQUIRED_GREEKS = Collections.singleton(Greek.FAIR_PRICE); private static final ZonedDateTime DATE = DateUtils.getUTCDate(2009, 1, 1); private static final Expiry EXPIRY = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.5)); private static final YieldAndDiscountCurve CURVE = new YieldCurve(ConstantDoublesCurve.from(0.1)); private static final double B = 0.07; private static final double SPOT = 100; private static final double STRIKE = 100; private static final double SMALL_EPS = 1e-9; private static final double BIG_EPS = 1e-4; @Test public void testNonIntegerPower() { try { POWERED_MODEL.getGreeks( new PoweredOptionDefinition(100, EXPIRY, 1.3, true), getBundle(0.), REQUIRED_GREEKS); Assert.fail(); } catch (final OptionPricingException e) { // Expected } } @Test public void testPowerOfOne() { PoweredOptionDefinition poweredDefinition = getPoweredDefinition(1, true); EuropeanVanillaOptionDefinition vanillaDefinition = getVanillaOption(true); assertPriceEquals(poweredDefinition, vanillaDefinition, 0.1); assertPriceEquals(poweredDefinition, vanillaDefinition, 0.2); assertPriceEquals(poweredDefinition, vanillaDefinition, 0.3); poweredDefinition = getPoweredDefinition(1, false); vanillaDefinition = getVanillaOption(false); assertPriceEquals(poweredDefinition, vanillaDefinition, 0.1); assertPriceEquals(poweredDefinition, vanillaDefinition, 0.2); assertPriceEquals(poweredDefinition, vanillaDefinition, 0.3); } @Test public void test() { PoweredOptionDefinition definition = getPoweredDefinition(2, true); assertPriceEquals(definition, 0.1, 53.4487); assertPriceEquals(definition, 0.2, 160.2944); assertPriceEquals(definition, 0.3, 339.3713); definition = getPoweredDefinition(3, true); assertPriceEquals(definition, 0.1, 758.8427); assertPriceEquals(definition, 0.2, 4608.7213); assertPriceEquals(definition, 0.3, 15624.1041); definition = getPoweredDefinition(2, false); assertPriceEquals(definition, 0.1, 9.7580); assertPriceEquals(definition, 0.2, 57.8677); assertPriceEquals(definition, 0.3, 142.2726); definition = getPoweredDefinition(3, false); assertPriceEquals(definition, 0.1, 89.6287); assertPriceEquals(definition, 0.2, 1061.2120); assertPriceEquals(definition, 0.3, 3745.1853); } private void assertPriceEquals( final PoweredOptionDefinition poweredDefinition, final EuropeanVanillaOptionDefinition vanillaDefinition, final double sigma) { final StandardOptionDataBundle bundle = getBundle(sigma); final GreekResultCollection actual = POWERED_MODEL.getGreeks(poweredDefinition, bundle, REQUIRED_GREEKS); final GreekResultCollection expected = BSM.getGreeks(vanillaDefinition, bundle, REQUIRED_GREEKS); assertEquals(expected.get(Greek.FAIR_PRICE), actual.get(Greek.FAIR_PRICE), SMALL_EPS); } private void assertPriceEquals( final PoweredOptionDefinition poweredDefinition, final double sigma, final double price) { final StandardOptionDataBundle bundle = getBundle(sigma); final GreekResultCollection actual = POWERED_MODEL.getGreeks(poweredDefinition, bundle, REQUIRED_GREEKS); assertEquals(price, actual.get(Greek.FAIR_PRICE), BIG_EPS * price); } private StandardOptionDataBundle getBundle(final double sigma) { return new StandardOptionDataBundle( CURVE, B, new VolatilitySurface(ConstantDoublesSurface.from(sigma)), SPOT, DATE); } private PoweredOptionDefinition getPoweredDefinition(final double power, final boolean isCall) { return new PoweredOptionDefinition(STRIKE, EXPIRY, power, isCall); } private EuropeanVanillaOptionDefinition getVanillaOption(final boolean isCall) { return new EuropeanVanillaOptionDefinition(STRIKE, EXPIRY, isCall); } }
@Test(expectedExceptions = IllegalArgumentException.class) public void testPeriodEndAfterExpiry() { new ExtremeSpreadOptionDefinition( EXPIRY, false, new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 2)), false); }
/** Test. */ @Test(groups = TestGroup.UNIT) public class ExtremeSpreadOptionDefinitionTest { private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1); private static final Expiry EXPIRY = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 1)); private static final Expiry PERIOD_END = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.275)); private static final ExtremeSpreadOptionDefinition PUT = new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, false); private static final ExtremeSpreadOptionDefinition PUT_REVERSE = new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, true); private static final ExtremeSpreadOptionDefinition CALL = new ExtremeSpreadOptionDefinition(EXPIRY, true, PERIOD_END, false); private static final ExtremeSpreadOptionDefinition CALL_REVERSE = new ExtremeSpreadOptionDefinition(EXPIRY, true, PERIOD_END, true); private static final DoubleTimeSeries<?> SPOT_SERIES = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] { DateUtils.getUTCDate(2010, 7, 1), DateUtils.getUTCDate(2010, 8, 1), DateUtils.getUTCDate(2010, 9, 1), DateUtils.getUTCDate(2010, 10, 1), DateUtils.getUTCDate(2010, 11, 1), DateUtils.getUTCDate(2010, 12, 1), DateUtils.getUTCDate(2011, 1, 1), DateUtils.getUTCDate(2011, 2, 1), DateUtils.getUTCDate(2011, 3, 1), DateUtils.getUTCDate(2011, 4, 1), DateUtils.getUTCDate(2011, 5, 1), DateUtils.getUTCDate(2011, 6, 1) }, new double[] {1, 2, 0, 1, 4, 15, 4, 4, 0, 4, 4, 4}); private static final StandardOptionWithSpotTimeSeriesDataBundle DATA = new StandardOptionWithSpotTimeSeriesDataBundle( YieldCurve.from(ConstantDoublesCurve.from(0.)), 0, new VolatilitySurface(ConstantDoublesSurface.from(0)), 2, DATE, SPOT_SERIES); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullPeriodEnd() { new ExtremeSpreadOptionDefinition(EXPIRY, true, null, true); } @Test(expectedExceptions = IllegalArgumentException.class) public void testPeriodEndAfterExpiry() { new ExtremeSpreadOptionDefinition( EXPIRY, false, new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 2)), false); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDate() { PUT.getTimeFromPeriodEnd(null); } @Test public void test() { assertEquals(PUT.getPeriodEnd(), PERIOD_END); assertFalse(PUT.isReverse()); ExtremeSpreadOptionDefinition other = new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, false); assertEquals(other, PUT); assertEquals(other.hashCode(), PUT.hashCode()); other = new ExtremeSpreadOptionDefinition( EXPIRY, false, new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, 0.15)), false); assertFalse(other.equals(PUT)); other = new ExtremeSpreadOptionDefinition(EXPIRY, false, PERIOD_END, true); assertFalse(other.equals(PUT)); assertEquals(PUT.getTimeFromPeriodEnd(EXPIRY.getExpiry()), 0.725, 0); assertEquals(PUT.getTimeFromPeriodEnd(DATE), -0.275, 0); } @Test public void testExercise() { assertFalse(PUT.getExerciseFunction().shouldExercise(DATA, null)); assertFalse(PUT_REVERSE.getExerciseFunction().shouldExercise(DATA, null)); } @Test public void testPayoff() { assertEquals(CALL.getPayoffFunction().getPayoff(DATA, null), 13, 0); assertEquals(CALL_REVERSE.getPayoffFunction().getPayoff(DATA, null), 0, 0); assertEquals(PUT.getPayoffFunction().getPayoff(DATA, null), 0, 0); assertEquals(PUT_REVERSE.getPayoffFunction().getPayoff(DATA, null), 13, 0); } }
public class ComplexChooserOptionModelTest { private static final YieldAndDiscountCurve CURVE = YieldCurve.from(ConstantDoublesCurve.from(0.1)); private static final double B = 0.05; private static final VolatilitySurface SURFACE = new VolatilitySurface(ConstantDoublesSurface.from(0.35)); private static final double SPOT = 50; private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1); private static final double CHOOSE_TIME = 0.25; private static final double CALL_LIFE = 0.5; private static final double PUT_LIFE = 7. / 12; private static final Expiry CHOOSE_DATE = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, CHOOSE_TIME)); private static final Expiry CALL_EXPIRY = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, CALL_LIFE)); private static final Expiry PUT_EXPIRY = new Expiry(DateUtils.getDateOffsetWithYearFraction(DATE, PUT_LIFE)); private static final double CALL_STRIKE = 55; private static final double PUT_STRIKE = 48; @SuppressWarnings("unused") private static final OptionDefinition CALL = new EuropeanVanillaOptionDefinition(CALL_STRIKE, CALL_EXPIRY, true); @SuppressWarnings("unused") private static final OptionDefinition PUT = new EuropeanVanillaOptionDefinition(PUT_STRIKE, PUT_EXPIRY, false); private static final ComplexChooserOptionDefinition CHOOSER = new ComplexChooserOptionDefinition( CHOOSE_DATE, CALL_STRIKE, CALL_EXPIRY, PUT_STRIKE, PUT_EXPIRY); private static final StandardOptionDataBundle DATA = new StandardOptionDataBundle(CURVE, B, SURFACE, SPOT, DATE); private static final AnalyticOptionModel<ComplexChooserOptionDefinition, StandardOptionDataBundle> MODEL = new ComplexChooserOptionModel(); @SuppressWarnings("unused") private static final AnalyticOptionModel<OptionDefinition, StandardOptionDataBundle> BSM = new BlackScholesMertonModel(); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDefinition() { MODEL.getPricingFunction(null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullData() { MODEL.getPricingFunction(CHOOSER).evaluate((StandardOptionDataBundle) null); } @Test public void test() { // TODO test wrt BSM // final double spot = 2; // final StandardOptionDataBundle data = DATA.withSpot(spot); // final ComplexChooserOptionDefinition chooser = new ComplexChooserOptionDefinition(new // Expiry(DATE), CALL_STRIKE, CALL_EXPIRY, PUT_STRIKE, PUT_EXPIRY); // assertEquals(MODEL.getPricingFunction(chooser).evaluate(data), BSM.getPricingFunction( // new EuropeanVanillaOptionDefinition(CALL_STRIKE, new // Expiry(DateUtil.getDateOffsetWithYearFraction(DATE, CALL_LIFE)), true)).evaluate(data), 0); assertEquals(MODEL.getPricingFunction(CHOOSER).evaluate(DATA), 6.0508, 1e-4); } }