Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDS Schedules #72

Open
AlessandroGnoatto opened this issue May 2, 2019 · 1 comment
Open

CDS Schedules #72

AlessandroGnoatto opened this issue May 2, 2019 · 1 comment

Comments

@AlessandroGnoatto
Copy link
Member

Hi,

I am trying to hack the Schedule generator in order to replicate the coupon of a Credit Default Swap according to the ISDA model. This is what I got so far. Any help in finding bugs/wrong reasonings etc is appreciated.

My source is the following document by ISDA: https://www.isda.org/a/vGiDE/amend-single-name-on-the-run-frequency-faq-revised-as-of-12-10.pdf

Here is my code:

package schedule;

import java.time.LocalDate;
import java.time.Month;
import java.util.StringTokenizer;

import net.finmath.time.Schedule;
import net.finmath.time.ScheduleGenerator;
import net.finmath.time.businessdaycalendar.BusinessdayCalendarExcludingTARGETHolidays;
import net.finmath.time.businessdaycalendar.BusinessdayCalendar.DateOffsetUnit;

public class ScheduleTest {

public static void main(String[] args) {

/*
 * Today is   
 */
LocalDate referenceDate = LocalDate.of(2015, 12, 20);

ScheduleTest test = new ScheduleTest();

String tenor = "5Y";

System.out.println(test.getPreviousRollDate(referenceDate).getDayOfWeek());
System.out.println(test.getFirstImmDateAfterRoll(referenceDate).getDayOfWeek());

System.out.println("Maturity Date of the CDS: this is an unadjusted IMM Date");
LocalDate unadjustedMaturityDate = test.getMaturityDate(referenceDate, tenor);
System.out.println(unadjustedMaturityDate);
System.out.println(unadjustedMaturityDate.getDayOfWeek());

BusinessdayCalendarExcludingTARGETHolidays cal = new BusinessdayCalendarExcludingTARGETHolidays();
if(cal.isBusinessday(unadjustedMaturityDate)==false) {
  System.out.println(unadjustedMaturityDate + " is not a good business day.");
}

Schedule schedule = ScheduleGenerator.createScheduleFromConventions(
    test.getPreviousRollDate(referenceDate)/* referenceDate */,
    test.getFirstImmDateAfterRoll(referenceDate)/* startDate */,
    test.getMaturityDate(referenceDate, tenor) /* maturity */,
    "quarterly" /* frequency */,
    "act/360" /* daycountConvention */,
    "first" /* shortPeriodConvention */,
    "following",
    new BusinessdayCalendarExcludingTARGETHolidays(),
    0,
    0);

System.out.println(schedule);

}

/**

  • CDS maturities are rolled twice a year, on March 20 and September 20
  • For a given trade date, return the previous roll date, this is either
  • March 20 or September 20.
  • @param tradeDate representing the date at which the trade is entered.
  • @return the previous roll date.
    */
    public LocalDate getPreviousRollDate(LocalDate tradeDate) {
    //Date is before march
    if(tradeDate.isBefore(LocalDate.of(tradeDate.getYear(), 3, 19))) {
    return LocalDate.of(tradeDate.getYear() -1, 9, 20);
    }else if(tradeDate.isAfter(LocalDate.of(tradeDate.getYear(), 3, 19)) && tradeDate.isBefore(LocalDate.of(tradeDate.getYear(), 9, 19)) ) {
    return LocalDate.of(tradeDate.getYear(), 3, 20);
    }else {
    return LocalDate.of(tradeDate.getYear(), 9, 20);
    }
    }

/**

  • Find the first IMM date after the previous roll date.
  • From this date we compute the maturity of the contract.
  • @param tradeDate representing the date at which the trade is entered.
  • @return the next IMM date after the previous roll date.
    */
    public LocalDate getFirstImmDateAfterRoll(LocalDate tradeDate) {
LocalDate rollDate = getPreviousRollDate(tradeDate);

//Roll month is march
if(rollDate.getMonth().equals(Month.MARCH)) {
  //The first Imm Date is 20 June of the same year
  return LocalDate.of(rollDate.getYear(), Month.JUNE, 20);
}else {
  //The roll month is September, hence the first IMM date is 20 December.
  return LocalDate.of(rollDate.getYear(), Month.DECEMBER, 20);
}

}

public LocalDate getMaturityDate(LocalDate tradeDate, String dateOffsetCode) {
dateOffsetCode = dateOffsetCode.trim();

StringTokenizer tokenizer = new StringTokenizer(dateOffsetCode);

LocalDate maturityDate = getFirstImmDateAfterRoll(tradeDate);

while(tokenizer.hasMoreTokens()) {
  String maturityCodeSingle = tokenizer.nextToken();
  String[] maturityCodeSingleParts = maturityCodeSingle.split("(?<=[0-9|\\.])(?=[A-Z|a-z])");
  
  if(maturityCodeSingleParts.length == 2) {
    int maturityValue = Integer.valueOf(maturityCodeSingleParts[0]);
    DateOffsetUnit dateOffsetUnit = DateOffsetUnit.getEnum(maturityCodeSingleParts[1]);

    switch(dateOffsetUnit) {
    case DAYS:
    {
      maturityDate = maturityDate.plusDays(maturityValue);
      break;
    }
    case WEEKS:
    {
      maturityDate = maturityDate.plusWeeks(maturityValue);
      break;
    }
    case MONTHS:
    {
      maturityDate = maturityDate.plusMonths(maturityValue);
      break;
    }
    case YEARS:
    {
      maturityDate = maturityDate.plusYears(maturityValue);
      break;
    }
    default:
      throw new IllegalArgumentException("Cannot handle dateOffsetCode '" + dateOffsetCode + "'.");
    }
  }
  else {
    throw new IllegalArgumentException("Cannot handle dateOffsetCode '" + dateOffsetCode + "'.");
  }
}
return maturityDate;

}

}

@quasar-chunawala
Copy link

Hi @AlessandroGnoatto, are you still looking for help on this? I am interested to contribute to the repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants