@Test public void toDerivativesStartMonthKnown() { final ZonedDateTime pricingDate = DateUtils.getUTCDate(2018, 6, 25); final DoubleTimeSeries<ZonedDateTime> priceIndexTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] { DateUtils.getUTCDate(2017, 5, 1), DateUtils.getUTCDate(2017, 6, 1), DateUtils.getUTCDate(2018, 5, 1), DateUtils.getUTCDate(2018, 6, 1) }, new double[] {127.23, 127.43, 128.23, 128.43}); Coupon zeroCouponConverted = YoY_COUPON_DEFINITION.toDerivative(pricingDate, priceIndexTS, CURVE_NAMES); double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE); CouponFixed zeroCoupon = new CouponFixed( CUR, paymentTime, DISCOUNTING_CURVE_NAME, 1.0, NOTIONAL, (WEIGHT_END * 128.23 + (1 - WEIGHT_END) * 128.43) / (WEIGHT_START * 127.23 + (1 - WEIGHT_START) * 127.43) - 1.0); assertEquals("Inflation zero-coupon: toDerivative", zeroCoupon, zeroCouponConverted); }
public class BondIborTransactionDefinitionTest { // Quarterly Libor6m 2Y private static final Currency CUR = Currency.USD; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final DayCount DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA"); private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Following"); private static final boolean IS_EOM = false; private static final Period IBOR_TENOR = Period.ofMonths(3); private static final DayCount IBOR_DAY_COUNT = DayCountFactory.INSTANCE.getDayCount("30/360"); private static final int IBOR_SPOT_LAG = 2; private static final BusinessDayConvention IBOR_BUSINESS_DAY = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following"); private static final boolean IBOR_IS_EOM = false; private static final IborIndex IBOR_INDEX = new IborIndex( CUR, IBOR_TENOR, IBOR_SPOT_LAG, CALENDAR, IBOR_DAY_COUNT, IBOR_BUSINESS_DAY, IBOR_IS_EOM); private static final Period BOND_TENOR = Period.ofYears(2); private static final int SETTLEMENT_DAYS = 3; // Standard for euro-bonds. private static final ZonedDateTime START_ACCRUAL_DATE = DateUtils.getUTCDate(2011, 7, 13); private static final ZonedDateTime MATURITY_DATE = START_ACCRUAL_DATE.plus(BOND_TENOR); private static final BondIborSecurityDefinition BOND_DESCRIPTION = BondIborSecurityDefinition.from( MATURITY_DATE, START_ACCRUAL_DATE, IBOR_INDEX, SETTLEMENT_DAYS, DAY_COUNT, BUSINESS_DAY, IS_EOM); // Transaction private static final double PRICE = 0.90; private static final ZonedDateTime SETTLEMENT_DATE = DateUtils.getUTCDate(2011, 8, 18); private static final double QUANTITY = 100000000; // 100m private static final BondIborTransactionDefinition BOND_TRANSACTION = new BondIborTransactionDefinition(BOND_DESCRIPTION, QUANTITY, SETTLEMENT_DATE, PRICE); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullUnderlying() { new BondIborTransactionDefinition(null, QUANTITY, SETTLEMENT_DATE, PRICE); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullSettle() { new BondIborTransactionDefinition(BOND_DESCRIPTION, QUANTITY, null, PRICE); } @Test public void testGetters() { assertEquals(PRICE, BOND_TRANSACTION.getPrice()); assertEquals(QUANTITY, BOND_TRANSACTION.getQuantity()); assertEquals(SETTLEMENT_DATE, BOND_TRANSACTION.getSettlementDate()); assertEquals(BOND_DESCRIPTION, BOND_TRANSACTION.getUnderlyingBond()); assertEquals(DateUtils.getUTCDate(2011, 7, 13), BOND_TRANSACTION.getPreviousAccrualDate()); assertEquals(DateUtils.getUTCDate(2011, 10, 13), BOND_TRANSACTION.getNextAccrualDate()); } }
@Test public void testGetters() { assertEquals(PRICE, BOND_TRANSACTION.getPrice()); assertEquals(QUANTITY, BOND_TRANSACTION.getQuantity()); assertEquals(SETTLEMENT_DATE, BOND_TRANSACTION.getSettlementDate()); assertEquals(BOND_DESCRIPTION, BOND_TRANSACTION.getUnderlyingBond()); assertEquals(DateUtils.getUTCDate(2011, 7, 13), BOND_TRANSACTION.getPreviousAccrualDate()); assertEquals(DateUtils.getUTCDate(2011, 10, 13), BOND_TRANSACTION.getNextAccrualDate()); }
/** Tests related to the discounting method for bond security. */ public class BondSecurityFRDiscountingMethodTest { // Calculators private static final PresentValueCalculator PVC = PresentValueCalculator.getInstance(); private static final BondSecurityDiscountingMethod METHOD = BondSecurityDiscountingMethod.getInstance(); private static final double TOLERANCE_PRICE = 1.0E-8; private static final String REPO_TYPE = "General collateral"; private static final Currency EUR = Currency.EUR; private static final Calendar TARGET = new MondayToFridayCalendar("TARGET"); private static final DayCount DAY_COUNT_ACTACTICMA = DayCountFactory.INSTANCE.getDayCount("Actual/Actual ICMA"); private static final BusinessDayConvention BUSINESS_DAY_FOL = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Following"); private static final boolean IS_EOM_FIXED = false; // To derivatives private static final DayCount ACT_ACT = DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA"); private static final String CREDIT_CURVE_NAME = "Credit"; private static final String REPO_CURVE_NAME = "Repo"; private static final String FORWARD_CURVE_NAME = "Forward"; private static final String[] CURVES_NAME = { CREDIT_CURVE_NAME, REPO_CURVE_NAME, FORWARD_CURVE_NAME }; private static final YieldCurveBundle CURVES = TestsDataSetsSABR.createCurvesBond1(); // FRTR 4 1/2 04/25/41 - ISIN: FR0010773192 private static final String ISSUER_FR = "FRANCE (GOVT OF)"; private static final YieldConvention YIELD_CONVENTION_FRANCE = SimpleYieldConvention.FRANCE_COMPOUND_METHOD; private static final int SETTLEMENT_DAYS_FR = 3; private static final Period PAYMENT_TENOR_FR = Period.ofMonths(12); // private static final int COUPON_PER_YEAR_FR = 1; private static final ZonedDateTime BOND_START_FR = DateUtils.getUTCDate(2009, 4, 25); private static final ZonedDateTime BOND_MATURITY_FR = DateUtils.getUTCDate(2041, 4, 25); private static final ZonedDateTime BOND_FIRSTCPN_FR = DateUtils.getUTCDate(2010, 4, 25); private static final double RATE_FR = 0.0450; private static final BondFixedSecurityDefinition BOND_FR_SECURITY_DEFINITION = BondFixedSecurityDefinition.from( EUR, BOND_START_FR, BOND_FIRSTCPN_FR, BOND_MATURITY_FR, PAYMENT_TENOR_FR, RATE_FR, SETTLEMENT_DAYS_FR, TARGET, DAY_COUNT_ACTACTICMA, BUSINESS_DAY_FOL, YIELD_CONVENTION_FRANCE, IS_EOM_FIXED, ISSUER_FR); }
@Test /** Tests the toDerivative method. */ public void toDerivativeFixingOnStartNotYetFixed() { final ZonedDateTime referenceDate = SPOT_DATE; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] { DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8) }, new double[] {0.01, 0.01}); final Payment cpnConverted = ON_COMPOUNDED_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final double paymentTime = EUR_DAY_COUNT.getDayCountFraction(referenceDate, EUR_PAYMENT_DATE, EUR_CALENDAR); final double[] FIXING_PERIOD_START_TIMES = new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1]; final double[] FIXING_PERIOD_END_TIMES = new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1]; final double[] FIXING_PERIOD_ACCRUAL_FACTOR = new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1]; final double[] FIXING_PERIOD_ACCRUAL_FACTOR_ACT_ACT = new double[ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1]; for (int i = 0; i < ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates().length - 1; i++) { FIXING_PERIOD_START_TIMES[i] = EUR_DAY_COUNT.getDayCountFraction( referenceDate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i], EUR_CALENDAR); FIXING_PERIOD_END_TIMES[i] = EUR_DAY_COUNT.getDayCountFraction( referenceDate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i + 1], EUR_CALENDAR); FIXING_PERIOD_ACCRUAL_FACTOR[i] = EUR_DAY_COUNT.getDayCountFraction( ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i], ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i + 1], EUR_CALENDAR); FIXING_PERIOD_ACCRUAL_FACTOR_ACT_ACT[i] = TimeCalculator.getTimeBetween( ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i], ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodDates()[i + 1]); } final CouponONCompounded cpnExpected = new CouponONCompounded( EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, EUR_OIS, FIXING_PERIOD_START_TIMES, FIXING_PERIOD_END_TIMES, FIXING_PERIOD_ACCRUAL_FACTOR, NOTIONAL); assertEquals("CouponONCompounded definition: toDerivative", cpnExpected, cpnConverted); }
@Test public void toDerivativesStartMonthNotknown() { final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29); final DoubleTimeSeries<ZonedDateTime> priceIndexTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] { DateUtils.getUTCDate(2017, 5, 1), DateUtils.getUTCDate(2017, 6, 1), DateUtils.getUTCDate(2018, 5, 1), DateUtils.getUTCDate(2018, 6, 1) }, new double[] {127.23, 127.43, 128.23, 128.43}); Coupon yearOnYearCouponConverted = YoY_COUPON_DEFINITION.toDerivative(pricingDate, priceIndexTS, CURVE_NAMES); double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE); final double referenceStartTime0 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[0]); final double referenceEndTime0 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[0]); final double referenceStartTime1 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[1]); final double referenceEndTime1 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[1]); final double naturalPaymentStartPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE); final double naturalPaymentEndPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE); final double[] referenceStartTime = new double[2]; final double[] referenceEndTime = new double[2]; referenceStartTime[0] = referenceStartTime0; referenceStartTime[1] = referenceStartTime1; referenceEndTime[0] = referenceEndTime0; referenceEndTime[1] = referenceEndTime1; CouponInflationYearOnYearInterpolation yearOnYearCoupon = new CouponInflationYearOnYearInterpolation( CUR, paymentTime, 1.0, NOTIONAL, PRICE_INDEX, referenceStartTime, naturalPaymentStartPaymentTime, referenceEndTime, naturalPaymentEndPaymentTime, false, WEIGHT_START, WEIGHT_END); assertEquals( "Inflation zero-coupon: toDerivative", yearOnYearCoupon, yearOnYearCouponConverted); }
@Test public void toDerivativesNoData() { final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29); final Coupon zeroCouponConverted = YoY_CAP_DEFINITION.toDerivative(pricingDate); // lastKnownFixingTime could be negatif so we don't use the dayfraction final double lastKnownFixingTime = TimeCalculator.getTimeBetween(pricingDate, LAST_KNOWN_FIXING_DATE); final double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE); final double referenceStartTime = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE); final double referenceEndTime = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE); final double naturalPaymentStartPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE); final double naturalPaymentEndPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE); final CapFloorInflationYearOnYearMonthly zeroCoupon = new CapFloorInflationYearOnYearMonthly( CUR, paymentTime, 1.0, NOTIONAL, PRICE_INDEX, lastKnownFixingTime, referenceStartTime, naturalPaymentStartPaymentTime, referenceEndTime, naturalPaymentEndPaymentTime, STRIKE, IS_CAP); assertEquals("Inflation zero-coupon: toDerivative", zeroCouponConverted, zeroCoupon); }
@Test public void testStartAndEndSame2() { final ZonedDateTime date = DateUtils.getUTCDate(2000, 1, 1); final ZonedDateTime[] dates = CALCULATOR.getSchedule(date, date); assertEquals(dates.length, 1); assertEquals(dates[0], date); }
@Test public void test2() { ZonedDateTime startDate = DateUtils.getUTCDate(2000, 1, 1); ZonedDateTime endDate = DateUtils.getUTCDate(2000, 12, 30); ZonedDateTime[] forward = CALCULATOR.getSchedule(startDate, endDate, false, true); assertEquals(forward.length, 1); assertEquals(forward[0], startDate); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false)); startDate = DateUtils.getUTCDate(2000, 1, 2); endDate = DateUtils.getUTCDate(2000, 12, 30); forward = CALCULATOR.getSchedule(startDate, endDate, false, true); assertEquals(forward.length, 0); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false)); startDate = DateUtils.getUTCDate(2002, 2, 2); endDate = DateUtils.getUTCDate(2003, 2, 9); forward = CALCULATOR.getSchedule(startDate, endDate, false, true); assertEquals(forward.length, 1); assertEquals(forward[0], DateUtils.getUTCDate(2003, 1, 1)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false)); startDate = DateUtils.getUTCDate(2000, 1, 1); endDate = DateUtils.getUTCDate(2010, 2, 9); final int months = 11; forward = CALCULATOR.getSchedule(startDate, endDate, false, true); assertEquals(forward.length, months); assertEquals(forward[0], startDate); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false)); final ZonedDateTime lastDate = DateUtils.getUTCDate(2010, 1, 1); assertEquals(forward[months - 1], lastDate); for (int i = 1; i < months; i++) { if (forward[i].getYear() == forward[i - 1].getYear()) { assertEquals(forward[i].getYear() - forward[i - 1].getYear(), 1); assertEquals(forward[i].getMonthOfYear().getValue(), 1); assertEquals(forward[i].getDayOfMonth(), 1); } } assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, true)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, false, false)); assertArrayEquals(forward, CALCULATOR.getSchedule(startDate, endDate, true, false)); }
/** 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); } }
/** Test. */ @Test(groups = TestGroup.UNIT) public class BlackOptionDataBundleTest { private static final double R = 0.05; private static final YieldAndDiscountCurve CURVE = YieldCurve.from(ConstantDoublesCurve.from(R)); private static final VolatilitySurface SURFACE = new VolatilitySurface(ConstantDoublesSurface.from(0.35)); private static final double F = 100; private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 5, 1); private static final BlackOptionDataBundle DATA = new BlackOptionDataBundle(F, CURVE, SURFACE, DATE); @Test public void test() { assertEquals(DATA.getDate(), DATE); assertEquals(DATA.getForward(), F, 0); assertEquals(DATA.getVolatilitySurface(), SURFACE); assertEquals(DATA.getInterestRateCurve(), CURVE); final double t = Math.random(); assertEquals(DATA.getDiscountFactor(t), Math.exp(-R * t), 0); BlackOptionDataBundle other = new BlackOptionDataBundle(F, CURVE, SURFACE, DATE); assertEquals(other, DATA); assertEquals(other.hashCode(), DATA.hashCode()); other = new BlackOptionDataBundle(DATA); assertEquals(other, DATA); assertEquals(other.hashCode(), DATA.hashCode()); other = new BlackOptionDataBundle(F + 1, CURVE, SURFACE, DATE); assertFalse(other.equals(DATA)); other = new BlackOptionDataBundle( F, YieldCurve.from(ConstantDoublesCurve.from(0.06)), SURFACE, DATE); assertFalse(other.equals(DATA)); other = new BlackOptionDataBundle( F, CURVE, new VolatilitySurface(ConstantDoublesSurface.from(0.6)), DATE); assertFalse(other.equals(DATA)); other = new BlackOptionDataBundle(F, CURVE, SURFACE, DATE.plusDays(1)); assertFalse(other.equals(DATA)); } @Test public void testBuilders() { final ZonedDateTime newDate = DATE.plusDays(1); assertEquals(DATA.withDate(newDate), new BlackOptionDataBundle(F, CURVE, SURFACE, newDate)); final double newForward = F + 1; assertEquals( DATA.withForward(newForward), new BlackOptionDataBundle(newForward, CURVE, SURFACE, DATE)); final YieldCurve newCurve = YieldCurve.from(ConstantDoublesCurve.from(0.05)); assertEquals( DATA.withInterestRateCurve(newCurve), new BlackOptionDataBundle(F, newCurve, SURFACE, DATE)); final VolatilitySurface newSurface = new VolatilitySurface(ConstantDoublesSurface.from(0.9)); assertEquals( DATA.withVolatilitySurface(newSurface), new BlackOptionDataBundle(F, CURVE, newSurface, DATE)); } }
@Override public BondIborSecurity toDerivative(final ZonedDateTime date) { ArgumentChecker.notNull(date, "date"); final ZonedDateTime spot = ScheduleCalculator.getAdjustedDate(date, getSettlementDays(), getCalendar()); return toDerivative( date, ImmutableZonedDateTimeDoubleTimeSeries.of(DateUtils.getUTCDate(1800, 1, 1), 0.0), spot); }
@Test public void toDerivativesStartMonthNotknown() { final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29); final DoubleTimeSeries<ZonedDateTime> priceIndexTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] { DateUtils.getUTCDate(2017, 5, 1), DateUtils.getUTCDate(2017, 6, 1), DateUtils.getUTCDate(2018, 5, 1), DateUtils.getUTCDate(2018, 6, 1) }, new double[] {127.23, 127.43, 128.23, 128.43}); final Coupon zeroCouponConverted = YoY_CAP_DEFINITION.toDerivative(pricingDate, priceIndexTS); // lastKnownFixingTime could be negatif so we don't use the dayfraction final double lastKnownFixingTime = TimeCalculator.getTimeBetween(pricingDate, LAST_KNOWN_FIXING_DATE); final double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE); final double referenceStartTime = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE); final double referenceEndTime = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE); final double naturalPaymentStartPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE); final double naturalPaymentEndPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE); final CapFloorInflationYearOnYearMonthly zeroCoupon = new CapFloorInflationYearOnYearMonthly( CUR, paymentTime, 1.0, NOTIONAL, PRICE_INDEX, lastKnownFixingTime, referenceStartTime, naturalPaymentStartPaymentTime, referenceEndTime, naturalPaymentEndPaymentTime, STRIKE, IS_CAP); assertEquals("Inflation zero-coupon: toDerivative", zeroCoupon, zeroCouponConverted); }
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); } }
public class FXVannaVolgaVolatilityCurveDataBundleTest { private static final double DELTA = 0.1; private static final double RR = 0.01; private static final double ATM = 0.2; private static final double VWB = 0.05; private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 7, 1); private static final FXVannaVolgaVolatilityCurveDataBundle DATA = new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, VWB, DATE); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullMaturity() { new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, ATM, VWB, null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNegativeATMVol() { new FXVannaVolgaVolatilityCurveDataBundle(DELTA, RR, -ATM, VWB, DATE); } @Test public void testGetters() { assertEquals(ATM, DATA.getAtTheMoney(), 0); assertEquals(DELTA, DATA.getDelta(), 0); assertEquals(DATE, DATA.getMaturity()); assertEquals(RR, DATA.getRiskReversal(), 0); assertEquals(VWB, DATA.getVegaWeightedButterfly(), 0); } @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)); } }
@Test public void test() { GapOptionDefinition other = new GapOptionDefinition(STRIKE, EXPIRY, true, PAYOFF_STRIKE); assertEquals(other, CALL); assertEquals(other.hashCode(), CALL.hashCode()); other = new GapOptionDefinition(STRIKE + 1, EXPIRY, true, PAYOFF_STRIKE); assertFalse(other.equals(CALL)); other = new GapOptionDefinition( STRIKE, new Expiry(DateUtils.getUTCDate(2010, 3, 1)), true, PAYOFF_STRIKE); assertFalse(other.equals(CALL)); other = new GapOptionDefinition(STRIKE, EXPIRY, false, PAYOFF_STRIKE); assertFalse(other.equals(CALL)); other = new GapOptionDefinition(STRIKE, EXPIRY, true, PAYOFF_STRIKE + 1); assertFalse(other.equals(CALL)); }
@Test /** Tests the toDerivative method. */ public void toDerivativeFixingLast() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 16); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] { DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13), DateUtils.getUTCDate(2011, 9, 14), DateUtils.getUTCDate(2011, 9, 15) }, new double[] { fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); final Payment cpnConverted = ON_COMPOUNDED_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); final double paymentTime = EUR_DAY_COUNT.getDayCountFraction(referenceDate, EUR_PAYMENT_DATE, EUR_CALENDAR); final double notionalAccrued = NOTIONAL * Math.pow( 1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[0]) * Math.pow( 1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[1]) * Math.pow( 1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[2]) * Math.pow( 1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[3]) * Math.pow( 1 + fixingRate, ON_COMPOUNDED_COUPON_DEFINITION.getFixingPeriodAccrualFactors()[4]); final CouponFixed cpnExpected = new CouponFixed( EUR_CUR, paymentTime, EUR_PAYMENT_YEAR_FRACTION, NOTIONAL, (notionalAccrued / NOTIONAL - 1.0) / EUR_PAYMENT_YEAR_FRACTION); assertEquals("CouponONCompounded definition: toDerivative", cpnExpected, cpnConverted); }
/** 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); } }
static { final int n = NO_STUB1.length; SHORT_START_STUB1 = Arrays.copyOf(NO_STUB1, n); LONG_START_STUB1 = Arrays.copyOf(NO_STUB1, n); SHORT_END_STUB1 = Arrays.copyOf(NO_STUB1, n); LONG_END_STUB1 = Arrays.copyOf(NO_STUB1, n); SHORT_START_STUB3 = Arrays.copyOf(NO_STUB3, n); LONG_START_STUB3 = Arrays.copyOf(NO_STUB3, n); SHORT_END_STUB3 = Arrays.copyOf(NO_STUB3, n); LONG_END_STUB3 = Arrays.copyOf(NO_STUB3, n); SHORT_START_STUB1[0] = DateUtils.getUTCDate(2008, 1, 30); LONG_START_STUB1[0] = DateUtils.getUTCDate(2007, 12, 1); SHORT_END_STUB1[n - 1] = DateUtils.getUTCDate(2011, 9, 4); LONG_END_STUB1[n - 1] = DateUtils.getUTCDate(2011, 11, 3); SHORT_START_STUB3[0] = DateUtils.getUTCDate(2008, 2, 27); LONG_START_STUB3[0] = DateUtils.getUTCDate(2008, 1, 27); SHORT_END_STUB3[n - 1] = DateUtils.getUTCDate(2011, 9, 4); LONG_END_STUB3[n - 1] = DateUtils.getUTCDate(2011, 11, 4); NO_STUB2 = new LocalDate[n]; SHORT_START_STUB2 = new LocalDate[n]; LONG_START_STUB2 = new LocalDate[n]; SHORT_END_STUB2 = new LocalDate[n]; LONG_END_STUB2 = new LocalDate[n]; NO_STUB4 = new LocalDate[n]; SHORT_START_STUB4 = new LocalDate[n]; LONG_START_STUB4 = new LocalDate[n]; SHORT_END_STUB4 = new LocalDate[n]; LONG_END_STUB4 = new LocalDate[n]; for (int i = 0; i < n; i++) { NO_STUB2[i] = NO_STUB1[i].toLocalDate(); SHORT_START_STUB4[i] = SHORT_START_STUB3[i].toLocalDate(); LONG_START_STUB4[i] = LONG_START_STUB3[i].toLocalDate(); SHORT_END_STUB4[i] = SHORT_END_STUB3[i].toLocalDate(); LONG_END_STUB4[i] = LONG_END_STUB3[i].toLocalDate(); NO_STUB4[i] = NO_STUB3[i].toLocalDate(); SHORT_START_STUB2[i] = SHORT_START_STUB1[i].toLocalDate(); LONG_START_STUB2[i] = LONG_START_STUB1[i].toLocalDate(); SHORT_END_STUB2[i] = SHORT_END_STUB1[i].toLocalDate(); LONG_END_STUB2[i] = LONG_END_STUB1[i].toLocalDate(); } }
@Test(expectedExceptions = IllegalArgumentException.class) /** Tests the toDerivative method: after payment date */ public void toDerivativeAfterPayment() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 9, 20); final double fixingRate = 0.01; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC( new ZonedDateTime[] { DateUtils.getUTCDate(2011, 9, 7), DateUtils.getUTCDate(2011, 9, 8), DateUtils.getUTCDate(2011, 9, 9), DateUtils.getUTCDate(2011, 9, 12), DateUtils.getUTCDate(2011, 9, 13), DateUtils.getUTCDate(2011, 9, 14), DateUtils.getUTCDate(2011, 9, 15) }, new double[] { fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate, fixingRate }); ON_COMPOUNDED_COUPON_DEFINITION.toDerivative(referenceDate, fixingTS); }
@Test /** Tests toDerivative. */ public void toDerivativeBetweenSettleMaturity() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 12, 20); final DepositZero converted = DEPOSIT_DEFINITION.toDerivative(referenceDate); final double startTime = 0; final double endTime = TimeCalculator.getTimeBetween(referenceDate, END_DATE); final DepositZero expected = new DepositZero( EUR, startTime, endTime, 0.0, NOTIONAL, DEPOSIT_AF, RATE, DEPOSIT_DEFINITION.getInterestAmount()); assertEquals("DepositZeroDefinition: toDerivative", expected, converted); }
@SuppressWarnings("deprecation") @Test /** Tests toDerivative. */ public void toDerivativeBetweenTradeAndSettleDeprecated() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2011, 12, 13); final DepositZero converted = DEPOSIT_DEFINITION.toDerivative(referenceDate, CURVE_NAME); final double startTime = TimeCalculator.getTimeBetween(referenceDate, SPOT_DATE); final double endTime = TimeCalculator.getTimeBetween(referenceDate, END_DATE); final DepositZero expected = new DepositZero( EUR, startTime, endTime, NOTIONAL, NOTIONAL, DEPOSIT_AF, RATE, DEPOSIT_DEFINITION.getInterestAmount(), CURVE_NAME); assertEquals("DepositZeroDefinition: toDerivative", expected, converted); }
@Test public void toDerivativesNoData() { final ZonedDateTime pricingDate = DateUtils.getUTCDate(2011, 7, 29); Coupon yearOnYearCouponConverted = YoY_COUPON_DEFINITION.toDerivative(pricingDate, CURVE_NAMES); double paymentTime = ACT_ACT.getDayCountFraction(pricingDate, PAYMENT_DATE); final double referenceStartTime0 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[0]); final double referenceEndTime0 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[0]); final double referenceStartTime1 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_START_DATE[1]); final double referenceEndTime1 = ACT_ACT.getDayCountFraction(pricingDate, REFERENCE_END_DATE[1]); final double naturalPaymentStartPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_START_DATE); final double naturalPaymentEndPaymentTime = ACT_ACT.getDayCountFraction(pricingDate, ACCRUAL_END_DATE); final double[] referenceStartTime = new double[2]; final double[] referenceEndTime = new double[2]; referenceStartTime[0] = referenceStartTime0; referenceStartTime[1] = referenceStartTime1; referenceEndTime[0] = referenceEndTime0; referenceEndTime[1] = referenceEndTime1; CouponInflationYearOnYearInterpolation yearOnYearCoupon = new CouponInflationYearOnYearInterpolation( CUR, paymentTime, 1.0, NOTIONAL, PRICE_INDEX, referenceStartTime, naturalPaymentStartPaymentTime, referenceEndTime, naturalPaymentEndPaymentTime, false, WEIGHT_START, WEIGHT_END); assertEquals( "Inflation year on year coupon: toDerivative", yearOnYearCouponConverted, yearOnYearCoupon); }
@Test public void priceAfterFixing() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2012, 3, 7); final ZonedDateTime[] dateFixing = new ZonedDateTime[] { DateUtils.getUTCDate(2012, 3, 1), DateUtils.getUTCDate(2012, 3, 2), DateUtils.getUTCDate(2012, 3, 5), DateUtils.getUTCDate(2012, 3, 6), DateUtils.getUTCDate(2012, 3, 7) }; final double[] rateFixing = new double[] {0.0010, 0.0011, 0.0012, 0.0013, 0.0014}; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dateFixing, rateFixing); final FederalFundsFutureSecurity futureSecurity = FUTURE_SECURITY_DEFINITION.toDerivative(referenceDate, fixingTS, CURVE_NAMES); double interest = futureSecurity.getAccruedInterest(); final YieldAndDiscountCurve oisCurve = CURVES.getCurve(CURVE_NAMES[0]); final double[] ratePeriod = new double[futureSecurity.getFixingPeriodAccrualFactor().length]; for (int loopfix = 0; loopfix < futureSecurity.getFixingPeriodAccrualFactor().length; loopfix++) { ratePeriod[loopfix] = (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix]) / oisCurve.getDiscountFactor( futureSecurity.getFixingPeriodTime()[loopfix + 1]) - 1.0) / futureSecurity.getFixingPeriodAccrualFactor()[loopfix]; interest += (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix]) / oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix + 1]) - 1.0); } final double rate = interest / FUTURE_SECURITY_DEFINITION.getFixingTotalAccrualFactor(); final double priceExpected = 1.0 - rate; final double priceComputed = METHOD_SECURITY.price(futureSecurity, CURVES); assertEquals( "Federal Funds Future Security: price", priceExpected, priceComputed, TOLERANCE_PRICE); }
public class FloatingStrikeLookbackOptionDefinitionTest { private static final ZonedDateTime DATE = DateUtils.getUTCDate(2010, 6, 1); private static final Expiry EXPIRY = new Expiry(DATE); private static final FloatingStrikeLookbackOptionDefinition CALL = new FloatingStrikeLookbackOptionDefinition(EXPIRY, true); private static final FloatingStrikeLookbackOptionDefinition PUT = new FloatingStrikeLookbackOptionDefinition(EXPIRY, false); private static final double SPOT = 100; private static final double DIFF = 10; private static final DoubleTimeSeries<?> HIGH_TS = new FastArrayIntDoubleTimeSeries( DateTimeNumericEncoding.DATE_DDMMYYYY, new int[] {20100529, 20100530, 20100531}, new double[] {SPOT, SPOT + DIFF, SPOT}); private static final DoubleTimeSeries<?> LOW_TS = new FastArrayIntDoubleTimeSeries( DateTimeNumericEncoding.DATE_DDMMYYYY, new int[] {20100529, 20100530, 20100531}, new double[] {SPOT, SPOT - DIFF, SPOT}); private static final StandardOptionWithSpotTimeSeriesDataBundle HIGH_DATA = new StandardOptionWithSpotTimeSeriesDataBundle( new YieldCurve(ConstantDoublesCurve.from(0.1)), 0.05, new VolatilitySurface(ConstantDoublesSurface.from(0.2)), SPOT, DateUtils.getUTCDate(2010, 6, 1), HIGH_TS); private static final StandardOptionWithSpotTimeSeriesDataBundle LOW_DATA = new StandardOptionWithSpotTimeSeriesDataBundle( new YieldCurve(ConstantDoublesCurve.from(0.1)), 0.05, new VolatilitySurface(ConstantDoublesSurface.from(0.2)), SPOT, DateUtils.getUTCDate(2010, 6, 1), LOW_TS); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullDataBundle() { CALL.getPayoffFunction().getPayoff(null, null); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullTS() { CALL.getPayoffFunction().getPayoff(HIGH_DATA.withSpotTimeSeries(null), null); } @Test public void testExercise() { assertFalse(CALL.getExerciseFunction().shouldExercise(HIGH_DATA, null)); assertFalse(CALL.getExerciseFunction().shouldExercise(LOW_DATA, null)); assertFalse(PUT.getExerciseFunction().shouldExercise(HIGH_DATA, null)); assertFalse(PUT.getExerciseFunction().shouldExercise(LOW_DATA, null)); } @Test public void testPayoff() { final double eps = 1e-15; OptionPayoffFunction<StandardOptionWithSpotTimeSeriesDataBundle> payoff = CALL.getPayoffFunction(); assertEquals(payoff.getPayoff(LOW_DATA, 0.), DIFF, eps); assertEquals(payoff.getPayoff(HIGH_DATA, 0.), 0, eps); payoff = PUT.getPayoffFunction(); assertEquals(payoff.getPayoff(LOW_DATA, 0.), 0, eps); assertEquals(payoff.getPayoff(HIGH_DATA, 0.), DIFF, 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)); } }
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); } }
/** * Tests related to the pricing of CMS coupons with Hull-White (extended Vasicek) model and * different numerical methods. */ public class CouponCMSHullWhiteMethodsTest { private static final Calendar TARGET = new MondayToFridayCalendar("TARGET"); private static final GeneratorSwapFixedIborMaster GENERATOR_SWAP_MASTER = GeneratorSwapFixedIborMaster.getInstance(); private static final GeneratorSwapFixedIbor GENERATOR_EUR1YEURIBOR6M = GENERATOR_SWAP_MASTER.getGenerator("EUR1YEURIBOR6M", TARGET); private static final Period TENOR_SWAP = Period.ofYears(10); private static final IndexSwap SWAP_EUR10Y = new IndexSwap(GENERATOR_EUR1YEURIBOR6M, TENOR_SWAP); private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2012, 1, 17); // Coupon CMS: 6m fixing in advance (payment in arrears); ACT/360 private static final Period TENOR_COUPON = Period.ofMonths(6); private static final Period TENOR_FIXING = Period.ofMonths(60); private static final DayCount ACT360 = DayCountFactory.INSTANCE.getDayCount("Actual/360"); private static final ZonedDateTime FIXING_DATE = ScheduleCalculator.getAdjustedDate( REFERENCE_DATE, TENOR_FIXING, GENERATOR_EUR1YEURIBOR6M.getBusinessDayConvention(), TARGET, GENERATOR_EUR1YEURIBOR6M.isEndOfMonth()); private static final ZonedDateTime START_DATE = ScheduleCalculator.getAdjustedDate( FIXING_DATE, GENERATOR_EUR1YEURIBOR6M.getSpotLag(), TARGET); private static final ZonedDateTime PAYMENT_DATE = ScheduleCalculator.getAdjustedDate( START_DATE, TENOR_COUPON, GENERATOR_EUR1YEURIBOR6M.getBusinessDayConvention(), TARGET, GENERATOR_EUR1YEURIBOR6M.isEndOfMonth()); private static final double NOTIONAL = 100000000; // 100m private static final double ACCRUAL_FACTOR = ACT360.getDayCountFraction(START_DATE, PAYMENT_DATE); private static final CouponCMSDefinition CPN_CMS_DEFINITION = CouponCMSDefinition.from( PAYMENT_DATE, START_DATE, PAYMENT_DATE, ACCRUAL_FACTOR, NOTIONAL, SWAP_EUR10Y); private static final YieldCurveBundle CURVES = TestsDataSetsSABR.createCurves2(); private static final String[] CURVE_NAMES = TestsDataSetsSABR.curves2Names(); private static final HullWhiteOneFactorPiecewiseConstantParameters PARAMETERS_HW = TestsDataSetHullWhite.createHullWhiteParameters(); private static final HullWhiteOneFactorPiecewiseConstantDataBundle BUNDLE_HW = new HullWhiteOneFactorPiecewiseConstantDataBundle(PARAMETERS_HW, CURVES); private static final CouponCMS CPN_CMS = (CouponCMS) CPN_CMS_DEFINITION.toDerivative( REFERENCE_DATE, new String[] {CURVE_NAMES[0], CURVE_NAMES[2]}); private static final CouponCMSHullWhiteNumericalIntegrationMethod METHOD_NI = CouponCMSHullWhiteNumericalIntegrationMethod.getInstance(); private static final CouponCMSHullWhiteApproximationMethod METHOD_APP = CouponCMSHullWhiteApproximationMethod.getInstance(); private static final CouponCMSDiscountingMethod METHOD_DSC = CouponCMSDiscountingMethod.getInstance(); private static final double TOLERANCE_PRICE = 1.0E-2; private static final double TOLERANCE_PRICE_APP = 5.0E+0; @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 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); } }
public class FederalFundsFutureSecurityDiscountingMethodTest { private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2012, 1, 30); private static final Calendar NYC = new MondayToFridayCalendar("NYC"); private static final IndexON INDEX_FEDFUND = IndexONMaster.getInstance().getIndex("FED FUND"); private static final ZonedDateTime MARCH_1 = DateUtils.getUTCDate(2012, 3, 1); private static final FederalFundsFutureSecurityDefinition FUTURE_SECURITY_DEFINITION = FederalFundsFutureSecurityDefinition.fromFedFund(MARCH_1, INDEX_FEDFUND, NYC); private static final YieldCurveBundle CURVES = TestsDataSetsSABR.createCurves2(); private static final String[] CURVE_NAMES = TestsDataSetsSABR.curves2Names(); private static final FederalFundsFutureSecurity FUTURE_SECURITY = FUTURE_SECURITY_DEFINITION.toDerivative(REFERENCE_DATE, CURVE_NAMES); private static final FederalFundsFutureSecurityDiscountingMethod METHOD_SECURITY = FederalFundsFutureSecurityDiscountingMethod.getInstance(); private static final double TOLERANCE_PRICE = 1.0E-6; @Test public void priceBeforeFixing() { double interest = 0.0; final YieldAndDiscountCurve oisCurve = CURVES.getCurve(CURVE_NAMES[0]); final double[] ratePeriod = new double[FUTURE_SECURITY_DEFINITION.getFixingPeriodAccrualFactor().length]; for (int loopfix = 0; loopfix < FUTURE_SECURITY_DEFINITION.getFixingPeriodAccrualFactor().length; loopfix++) { ratePeriod[loopfix] = (oisCurve.getDiscountFactor(FUTURE_SECURITY.getFixingPeriodTime()[loopfix]) / oisCurve.getDiscountFactor( FUTURE_SECURITY.getFixingPeriodTime()[loopfix + 1]) - 1.0) / FUTURE_SECURITY_DEFINITION.getFixingPeriodAccrualFactor()[loopfix]; interest += (oisCurve.getDiscountFactor(FUTURE_SECURITY.getFixingPeriodTime()[loopfix]) / oisCurve.getDiscountFactor(FUTURE_SECURITY.getFixingPeriodTime()[loopfix + 1]) - 1.0); } final double rate = interest / FUTURE_SECURITY_DEFINITION.getFixingTotalAccrualFactor(); final double priceExpected = 1.0 - rate; final double priceComputed = METHOD_SECURITY.price(FUTURE_SECURITY, CURVES); assertEquals( "Federal Funds Future Security: price", priceExpected, priceComputed, TOLERANCE_PRICE); } @Test public void priceAfterFixing() { final ZonedDateTime referenceDate = DateUtils.getUTCDate(2012, 3, 7); final ZonedDateTime[] dateFixing = new ZonedDateTime[] { DateUtils.getUTCDate(2012, 3, 1), DateUtils.getUTCDate(2012, 3, 2), DateUtils.getUTCDate(2012, 3, 5), DateUtils.getUTCDate(2012, 3, 6), DateUtils.getUTCDate(2012, 3, 7) }; final double[] rateFixing = new double[] {0.0010, 0.0011, 0.0012, 0.0013, 0.0014}; final DoubleTimeSeries<ZonedDateTime> fixingTS = ImmutableZonedDateTimeDoubleTimeSeries.ofUTC(dateFixing, rateFixing); final FederalFundsFutureSecurity futureSecurity = FUTURE_SECURITY_DEFINITION.toDerivative(referenceDate, fixingTS, CURVE_NAMES); double interest = futureSecurity.getAccruedInterest(); final YieldAndDiscountCurve oisCurve = CURVES.getCurve(CURVE_NAMES[0]); final double[] ratePeriod = new double[futureSecurity.getFixingPeriodAccrualFactor().length]; for (int loopfix = 0; loopfix < futureSecurity.getFixingPeriodAccrualFactor().length; loopfix++) { ratePeriod[loopfix] = (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix]) / oisCurve.getDiscountFactor( futureSecurity.getFixingPeriodTime()[loopfix + 1]) - 1.0) / futureSecurity.getFixingPeriodAccrualFactor()[loopfix]; interest += (oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix]) / oisCurve.getDiscountFactor(futureSecurity.getFixingPeriodTime()[loopfix + 1]) - 1.0); } final double rate = interest / FUTURE_SECURITY_DEFINITION.getFixingTotalAccrualFactor(); final double priceExpected = 1.0 - rate; final double priceComputed = METHOD_SECURITY.price(futureSecurity, CURVES); assertEquals( "Federal Funds Future Security: price", priceExpected, priceComputed, TOLERANCE_PRICE); } }
/** Tests on the construction of interest rate future option with up-front payment. */ public class InterestRateFutureOptionMarginSecurityTest { // EURIBOR 3M Index private static final Period TENOR = Period.ofMonths(3); private static final int SETTLEMENT_DAYS = 2; private static final Calendar CALENDAR = new MondayToFridayCalendar("A"); private static final DayCount DAY_COUNT_INDEX = DayCountFactory.INSTANCE.getDayCount("Actual/360"); private static final BusinessDayConvention BUSINESS_DAY = BusinessDayConventionFactory.INSTANCE.getBusinessDayConvention("Modified Following"); private static final boolean IS_EOM = true; private static final Currency CUR = Currency.EUR; private static final IborIndex IBOR_INDEX = new IborIndex(CUR, TENOR, SETTLEMENT_DAYS, DAY_COUNT_INDEX, BUSINESS_DAY, IS_EOM); // Future private static final ZonedDateTime SPOT_LAST_TRADING_DATE = DateUtils.getUTCDate(2012, 9, 19); private static final ZonedDateTime LAST_TRADING_DATE = ScheduleCalculator.getAdjustedDate(SPOT_LAST_TRADING_DATE, -SETTLEMENT_DAYS, CALENDAR); private static final double NOTIONAL = 1000000.0; // 1m private static final double FUTURE_FACTOR = 0.25; private static final String NAME = "EDU2"; private static final double STRIKE = 0.9850; private static final InterestRateFutureSecurityDefinition EDU2_DEFINITION = new InterestRateFutureSecurityDefinition( LAST_TRADING_DATE, IBOR_INDEX, NOTIONAL, FUTURE_FACTOR, NAME, CALENDAR); private static final ZonedDateTime REFERENCE_DATE = DateUtils.getUTCDate(2010, 8, 18); private static final String DISCOUNTING_CURVE_NAME = "Funding"; private static final String FORWARD_CURVE_NAME = "Forward"; private static final String[] CURVES = {DISCOUNTING_CURVE_NAME, FORWARD_CURVE_NAME}; private static final InterestRateFutureSecurity EDU2 = EDU2_DEFINITION.toDerivative(REFERENCE_DATE, CURVES); // Option private static final ZonedDateTime EXPIRATION_DATE = DateUtils.getUTCDate(2011, 9, 16); private static final DayCount ACT_ACT = DayCountFactory.INSTANCE.getDayCount("Actual/Actual ISDA"); private static final double EXPIRATION_TIME = ACT_ACT.getDayCountFraction(REFERENCE_DATE, EXPIRATION_DATE); private static final boolean IS_CALL = true; private static final InterestRateFutureOptionPremiumSecurity OPTION_EDU2 = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, IS_CALL); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullUnderlying() { new InterestRateFutureOptionPremiumSecurity(null, EXPIRATION_TIME, STRIKE, IS_CALL); } @Test public void getter() { assertEquals(EDU2, OPTION_EDU2.getUnderlyingFuture()); assertEquals(EXPIRATION_TIME, OPTION_EDU2.getExpirationTime()); assertEquals(STRIKE, OPTION_EDU2.getStrike()); assertEquals(IS_CALL, OPTION_EDU2.isCall()); assertEquals(DISCOUNTING_CURVE_NAME, OPTION_EDU2.getDiscountingCurveName()); assertEquals(FORWARD_CURVE_NAME, OPTION_EDU2.getForwardCurveName()); } @Test /** Tests the equal and hash code methods. */ public void equalHash() { final InterestRateFutureOptionPremiumSecurity newOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, IS_CALL); assertTrue(OPTION_EDU2.equals(newOption)); assertEquals(OPTION_EDU2.hashCode(), newOption.hashCode()); InterestRateFutureOptionPremiumSecurity modifiedOption; modifiedOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME - 0.01, STRIKE, IS_CALL); assertFalse(OPTION_EDU2.equals(modifiedOption)); modifiedOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE + 0.01, IS_CALL); assertFalse(OPTION_EDU2.equals(modifiedOption)); modifiedOption = new InterestRateFutureOptionPremiumSecurity(EDU2, EXPIRATION_TIME, STRIKE, !IS_CALL); assertFalse(OPTION_EDU2.equals(modifiedOption)); } }