/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.pricer.impl.credit.isda;
import static com.opengamma.strata.pricer.impl.credit.isda.ImmDateLogic.getNextIMMDate;
import static com.opengamma.strata.pricer.impl.credit.isda.ImmDateLogic.getPrevIMMDate;
import static org.testng.AssertJUnit.assertEquals;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.JulianFields;
import java.util.Locale;
import org.testng.annotations.Test;
import com.opengamma.strata.basics.date.BusinessDayConvention;
import com.opengamma.strata.basics.date.BusinessDayConventions;
import com.opengamma.strata.basics.date.DayCount;
import com.opengamma.strata.basics.date.DayCounts;
import com.opengamma.strata.basics.date.HolidayCalendar;
import com.opengamma.strata.basics.date.HolidayCalendars;
import com.opengamma.strata.basics.schedule.StubConvention;
import com.opengamma.strata.collect.ArgChecker;
/**
* Test.
*/
@Test
public class IsdaPremiumLegScheduleTest {
private static final DayCount ACT360 = DayCounts.ACT_360;
private static final BusinessDayConvention FOLLOWING = BusinessDayConventions.FOLLOWING;
private static final HolidayCalendar CALENDAR = HolidayCalendars.SAT_SUN;
// TODO all the null input tests. startDate after endDate etc
@Test(expectedExceptions = IllegalArgumentException.class)
public void undefinedStubTest() {
final LocalDate startDate = LocalDate.of(2012, 6, 7);
final LocalDate endDate = LocalDate.of(2015, 11, 29); // sunday
final Period step = Period.ofMonths(3);
final StubConvention stubType = StubConvention.NONE;
final boolean protectionStart = false;
@SuppressWarnings("unused")
final IsdaPremiumLegSchedule schedule = new IsdaPremiumLegSchedule(startDate, endDate, step, stubType, FOLLOWING, CALENDAR, protectionStart);
}
/**
* short front stub and end on a weekend at EoM
*/
public void scheduleTest1() {
final LocalDate[] accStart = new LocalDate[] {LocalDate.of(2012, 6, 7), LocalDate.of(2012, 8, 29), LocalDate.of(2012, 11, 29), LocalDate.of(2013, 2, 28), LocalDate.of(2013, 5, 29),
LocalDate.of(2013, 8, 29), LocalDate.of(2013, 11, 29), LocalDate.of(2014, 2, 28), LocalDate.of(2014, 5, 29), LocalDate.of(2014, 8, 29), LocalDate.of(2014, 12, 1), LocalDate.of(2015, 3, 2),
LocalDate.of(2015, 5, 29), LocalDate.of(2015, 8, 31) };
final LocalDate[] accEnd = new LocalDate[] {LocalDate.of(2012, 8, 29), LocalDate.of(2012, 11, 29), LocalDate.of(2013, 2, 28), LocalDate.of(2013, 5, 29), LocalDate.of(2013, 8, 29),
LocalDate.of(2013, 11, 29), LocalDate.of(2014, 2, 28), LocalDate.of(2014, 5, 29), LocalDate.of(2014, 8, 29), LocalDate.of(2014, 12, 1), LocalDate.of(2015, 3, 2), LocalDate.of(2015, 5, 29),
LocalDate.of(2015, 8, 31), LocalDate.of(2015, 11, 30) };
final LocalDate[] pay = new LocalDate[] {LocalDate.of(2012, 8, 29), LocalDate.of(2012, 11, 29), LocalDate.of(2013, 2, 28), LocalDate.of(2013, 5, 29), LocalDate.of(2013, 8, 29),
LocalDate.of(2013, 11, 29), LocalDate.of(2014, 2, 28), LocalDate.of(2014, 5, 29), LocalDate.of(2014, 8, 29), LocalDate.of(2014, 12, 1), LocalDate.of(2015, 3, 2), LocalDate.of(2015, 5, 29),
LocalDate.of(2015, 8, 31), LocalDate.of(2015, 11, 30) };
final int n = pay.length;
// data check
ArgChecker.isTrue(n == accStart.length, null);
ArgChecker.isTrue(n == accEnd.length, null);
final LocalDate startDate = LocalDate.of(2012, 6, 7);
final LocalDate endDate = LocalDate.of(2015, 11, 29); // sunday
final Period step = Period.ofMonths(3);
final StubConvention stubType = StubConvention.SHORT_INITIAL;
final boolean protectionStart = true;
final IsdaPremiumLegSchedule schedule = new IsdaPremiumLegSchedule(startDate, endDate, step, stubType, FOLLOWING, CALENDAR, protectionStart);
assertEquals(n, schedule.getNumPayments());
for (int i = 0; i < n; i++) {
assertEquals(accStart[i], schedule.getAccStartDate(i));
assertEquals(accEnd[i], schedule.getAccEndDate(i));
assertEquals(pay[i], schedule.getPaymentDate(i));
}
}
/**
* Long front stub, start on weekend and end on IMM date
*/
public void scheduleTest2() {
final LocalDate[] accStart = new LocalDate[] {LocalDate.of(2012, 6, 30), LocalDate.of(2012, 12, 20), LocalDate.of(2013, 3, 20), LocalDate.of(2013, 6, 20), LocalDate.of(2013, 9, 20) };
final LocalDate[] accEnd = new LocalDate[] {LocalDate.of(2012, 12, 20), LocalDate.of(2013, 3, 20), LocalDate.of(2013, 6, 20), LocalDate.of(2013, 9, 20), LocalDate.of(2013, 12, 21) };
final LocalDate[] pay = new LocalDate[] {LocalDate.of(2012, 12, 20), LocalDate.of(2013, 3, 20), LocalDate.of(2013, 6, 20), LocalDate.of(2013, 9, 20), LocalDate.of(2013, 12, 20) };
final int n = pay.length;
// data check
ArgChecker.isTrue(n == accStart.length, null);
ArgChecker.isTrue(n == accEnd.length, null);
final LocalDate startDate = LocalDate.of(2012, 6, 30); // Saturday
final LocalDate endDate = LocalDate.of(2013, 12, 20); // IMM date
final Period step = Period.ofMonths(3);
final StubConvention stubType = StubConvention.LONG_INITIAL;
final boolean protectionStart = true;
final IsdaPremiumLegSchedule schedule = new IsdaPremiumLegSchedule(startDate, endDate, step, stubType, FOLLOWING, CALENDAR, protectionStart);
assertEquals(n, schedule.getNumPayments());
for (int i = 0; i < n; i++) {
assertEquals(accStart[i], schedule.getAccStartDate(i));
assertEquals(accEnd[i], schedule.getAccEndDate(i));
assertEquals(pay[i], schedule.getPaymentDate(i));
}
}
/**
* short back stub, start and end on IMM date
*/
public void scheduleTest3() {
final LocalDate[] accStart = new LocalDate[] {LocalDate.of(2012, 6, 20), LocalDate.of(2012, 9, 20), LocalDate.of(2012, 12, 20), LocalDate.of(2013, 3, 20), LocalDate.of(2013, 6, 20) };
final LocalDate[] accEnd = new LocalDate[] {LocalDate.of(2012, 9, 20), LocalDate.of(2012, 12, 20), LocalDate.of(2013, 3, 20), LocalDate.of(2013, 6, 20), LocalDate.of(2013, 9, 21) };
final LocalDate[] pay = new LocalDate[] {LocalDate.of(2012, 9, 20), LocalDate.of(2012, 12, 20), LocalDate.of(2013, 3, 20), LocalDate.of(2013, 6, 20), LocalDate.of(2013, 9, 20) };
final int n = pay.length;
// data check
ArgChecker.isTrue(n == accStart.length, null);
ArgChecker.isTrue(n == accEnd.length, null);
final LocalDate startDate = LocalDate.of(2012, 6, 20); // IMM date
final LocalDate endDate = LocalDate.of(2013, 9, 20); // IMM date
final Period step = Period.ofMonths(3);
final StubConvention stubType = StubConvention.SHORT_FINAL;
final boolean protectionStart = true;
final IsdaPremiumLegSchedule schedule = new IsdaPremiumLegSchedule(startDate, endDate, step, stubType, FOLLOWING, CALENDAR, protectionStart);
assertEquals(n, schedule.getNumPayments());
for (int i = 0; i < n; i++) {
assertEquals(accStart[i], schedule.getAccStartDate(i));
assertEquals(accEnd[i], schedule.getAccEndDate(i));
assertEquals(pay[i], schedule.getPaymentDate(i));
}
}
/**
* long back stub, start and end NOT on IMM date
*/
public void scheduleTest4() {
final LocalDate[] accStart = new LocalDate[] {LocalDate.of(2012, 5, 10), LocalDate.of(2012, 8, 10), LocalDate.of(2012, 11, 12), LocalDate.of(2013, 2, 11), LocalDate.of(2013, 5, 10) };
final LocalDate[] accEnd = new LocalDate[] {LocalDate.of(2012, 8, 10), LocalDate.of(2012, 11, 12), LocalDate.of(2013, 2, 11), LocalDate.of(2013, 5, 10), LocalDate.of(2013, 10, 21) };
final LocalDate[] pay = new LocalDate[] {LocalDate.of(2012, 8, 10), LocalDate.of(2012, 11, 12), LocalDate.of(2013, 2, 11), LocalDate.of(2013, 5, 10), LocalDate.of(2013, 10, 21) };
final int n = pay.length;
// data check
ArgChecker.isTrue(n == accStart.length, null);
ArgChecker.isTrue(n == accEnd.length, null);
final LocalDate startDate = LocalDate.of(2012, 5, 10);
final LocalDate endDate = LocalDate.of(2013, 10, 20);
final Period step = Period.ofMonths(3);
final StubConvention stubType = StubConvention.LONG_FINAL;
final boolean protectionStart = true;
final IsdaPremiumLegSchedule schedule = new IsdaPremiumLegSchedule(startDate, endDate, step, stubType, FOLLOWING, CALENDAR, protectionStart);
assertEquals(n, schedule.getNumPayments());
for (int i = 0; i < n; i++) {
assertEquals(accStart[i], schedule.getAccStartDate(i));
assertEquals(accEnd[i], schedule.getAccEndDate(i));
assertEquals(pay[i], schedule.getPaymentDate(i));
}
}
// TODO other inputs: Period different from 3M, convention "proceeding", proctectionStart = false etc.
/**
* This generates a table in the CDS pricing paper
*/
@Test(enabled = false)
public void printTest() {
final LocalDate tradeDate = LocalDate.of(2013, Month.JULY, 30);
final Period tenor = Period.ofYears(2);
final LocalDate stepIn = tradeDate.plusDays(1);
final LocalDate startDate = getPrevIMMDate(stepIn);
final LocalDate endDate = getNextIMMDate(tradeDate).plus(tenor);
final Period paymentInt = Period.ofMonths(3);
final StubConvention stub = StubConvention.SHORT_INITIAL;
final double notional = 1e7;
final double coupon = 1e-2;
final IsdaPremiumLegSchedule schedule = new IsdaPremiumLegSchedule(startDate, endDate, paymentInt, stub, FOLLOWING, CALENDAR, true);
final DateTimeFormatter formatt = DateTimeFormatter.ofPattern("dd-MMM-uu", Locale.ENGLISH);
final int n = schedule.getNumPayments();
System.out.println("\\begin{tabular}{|c|c|c|c|c|}");
System.out.println("\\hline");
System.out.println("Accrual Start & Accrual End & Payment Date & Days in & Amount" + " \\\\");
System.out.println("(Inclusive) & (Exclusive) & & Period & " + " \\\\");
System.out.println("\\hline");
for (int i = 0; i < n; i++) {
final LocalDate start = schedule.getAccStartDate(i);
final LocalDate end = schedule.getAccEndDate(i);
System.out.print(start.format(formatt) + " & ");
System.out.print(end.format(formatt) + " & ");
System.out.print(schedule.getPaymentDate(i).format(formatt) + " & ");
final long firstJulianDate = start.getLong(JulianFields.MODIFIED_JULIAN_DAY);
final long secondJulianDate = end.getLong(JulianFields.MODIFIED_JULIAN_DAY);
final int days = (int) (secondJulianDate - firstJulianDate);
System.out.print(days + " & ");
final double premium = notional * coupon * ACT360.yearFraction(start, end);
System.out.format(Locale.ENGLISH, "%.2f" + " \\\\" + "\n", premium);
}
System.out.println("\\hline");
System.out.println("\\end{tabular}");
}
}