Package com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.isdanew

Source Code of com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.isdanew.ISDACompliantPresentValueCreditDefaultSwapTest

/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.isdanew;

import static com.opengamma.financial.convention.businessday.BusinessDayDateUtils.addWorkDays;
import static org.testng.AssertJUnit.assertEquals;

import java.util.Arrays;

import org.testng.annotations.Test;
import org.threeten.bp.LocalDate;
import org.threeten.bp.Period;

import com.opengamma.analytics.financial.credit.PriceType;
import com.opengamma.analytics.financial.credit.StubType;
import com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.isdanew.ISDAModelDatasets.ISDA_Results;
import com.opengamma.financial.convention.calendar.Calendar;
import com.opengamma.financial.convention.calendar.MondayToFridayCalendar;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.financial.convention.daycount.DayCountFactory;

/**
*
*/
public class ISDACompliantPresentValueCreditDefaultSwapTest {

  private static final double NOTIONAL = 1e7;
  private static final Calendar DEFAULT_CALENDAR = new MondayToFridayCalendar("Weekend_Only");
  private static final ISDACompliantPresentValueCreditDefaultSwap PRICER = new ISDACompliantPresentValueCreditDefaultSwap();

  private static final LocalDate TODAY = LocalDate.of(2013, 4, 21);
  private static final LocalDate BASE_DATE = TODAY;
  // private static final HazardRateCurve HAZARD_RATE_CURVE;
  private static final double RECOVERY_RATE = 0.4;

  // points related to the yield curve (note: here we use yield curve points directly rather than fit from IR instruments)
  private static final LocalDate[] YC_DATES = new LocalDate[] {LocalDate.of(2013, 6, 27), LocalDate.of(2013, 8, 27), LocalDate.of(2013, 11, 27), LocalDate.of(2014, 5, 27), LocalDate.of(2015, 5, 27),
      LocalDate.of(2016, 5, 27), LocalDate.of(2018, 5, 27), LocalDate.of(2020, 5, 27), LocalDate.of(2023, 5, 27), LocalDate.of(2028, 5, 27), LocalDate.of(2033, 5, 27), LocalDate.of(2043, 5, 27) };

  private static final double[] DISCOUNT_FACT;
  private static final double[] YC_TIMES;
  // private static final ISDADateCurve YIELD_CURVE_ZERO_FLAT;
  // private static final ISDADateCurve YIELD_CURVE_5PC_FLAT;
  private static final ISDACompliantDateYieldCurve YIELD_CURVE_ZERO_FLAT;
  private static final ISDACompliantDateYieldCurve YIELD_CURVE_5PC_FLAT;

  private static final DayCount ACT365 = DayCountFactory.INSTANCE.getDayCount("ACT/365");
  // examples
  private static final ISDA_Results[] EXAMPLE1 = ISDAModelDatasets.getExample1();
  private static final ISDA_Results[] EXAMPLE3 = ISDAModelDatasets.getExample3();

  static {
    final int ycPoints = YC_DATES.length;

    final double[] zeros = new double[ycPoints];
    final double[] fivePC = new double[ycPoints];
    Arrays.fill(fivePC, 0.05);

    DISCOUNT_FACT = new double[ycPoints];
    Arrays.fill(DISCOUNT_FACT, 1.0);
    YC_TIMES = new double[ycPoints];
    for (int i = 0; i < ycPoints; i++) {
      YC_TIMES[i] = ACT365.getDayCountFraction(BASE_DATE, YC_DATES[i]);
    }
    // YIELD_CURVE_ZERO_FLAT = new ISDADateCurve("ISDA", BASE_DATE, YC_DATES, zeros, OFFSET); // Remake: this constructor assumes ACT/365
    // YIELD_CURVE_5PC_FLAT = new ISDADateCurve("ISDA", BASE_DATE, YC_DATES, fivePC, OFFSET);
    // CURVES = new ISDAYieldCurveAndHazardRateCurveProvider(YIELD_CURVE_ZERO_FLAT, HAZARD_RATE_CURVE);
    YIELD_CURVE_ZERO_FLAT = new ISDACompliantDateYieldCurve(BASE_DATE, YC_DATES, zeros);
    YIELD_CURVE_5PC_FLAT = new ISDACompliantDateYieldCurve(BASE_DATE, YC_DATES, fivePC);

  }

  private void testISDA_Results(final ISDA_Results[] data, final ISDACompliantDateYieldCurve yieldCurve, final boolean debug) {
    if (debug) {
      System.out.println("ISDACompliantPremiumLegCalculatorAgaintISDATest2.testISDA_Results DO NOT PUSH WITH DEBUG ON\n");
    }
    int failCount = 0;
    final int constructionFailCount = 0;

    final int nEx = data.length;
    final int[] failedList = new int[nEx];
    for (int count = 0; count < nEx; count++) {

      final ISDA_Results res = data[count];

      final LocalDate today = res.today;
      final LocalDate stepinDate = today.plusDays(1); // aka effective date
      final LocalDate valueDate = addWorkDays(today, 3, DEFAULT_CALENDAR); // 3 working days on
      final LocalDate startDate = res.startDate;
      final LocalDate endDate = res.endDate;
      final Period tenor = Period.ofMonths(3); // TODO should be part of the CSV
      final StubType stubType = StubType.FRONTSHORT; // TODO ditto
      final boolean protectionStart = true; // TODO ditto

      // build an 'analytic' cds, then price with the new date free pricer
      double protectionLeg_new = 0;
      double premLeg_clean_new = 0;

      if (!today.isAfter(endDate)) {
        final boolean payAccOnDefault = true;
        try {
          final CDSAnalytic cds = new CDSAnalytic(today, stepinDate, valueDate, startDate, endDate, payAccOnDefault, tenor, stubType, protectionStart, RECOVERY_RATE);
          final AnalyticCDSPricer analPricer = new AnalyticCDSPricer();
          protectionLeg_new = NOTIONAL * analPricer.protectionLeg(cds, yieldCurve, res.creditCurve);
          final double rpv01_clean_new = NOTIONAL * analPricer.pvPremiumLegPerUnitSpread(cds, yieldCurve, res.creditCurve, PriceType.CLEAN);
          premLeg_clean_new = res.fracSpread * rpv01_clean_new;
        } catch (final Exception e) {
        }

      }

      // price with code written to mimic ISDA c - i.e. date logic in the analytics
      final double rpv01_clean_ISDA = NOTIONAL *
          PRICER.pvPremiumLegPerUnitSpread(today, stepinDate, valueDate, startDate, endDate, true, tenor, stubType, yieldCurve, res.creditCurve, protectionStart, PriceType.CLEAN);
      final double rpv01_clean_ISDA_noAccOnDefault = NOTIONAL *
          PRICER.pvPremiumLegPerUnitSpread(today, stepinDate, valueDate, startDate, endDate, false, tenor, stubType, yieldCurve, res.creditCurve, protectionStart, PriceType.CLEAN);
      final double rpv01_dirty_ISDA = NOTIONAL *
          PRICER.pvPremiumLegPerUnitSpread(today, stepinDate, valueDate, startDate, endDate, true, tenor, stubType, yieldCurve, res.creditCurve, protectionStart, PriceType.DIRTY);
      final double contLeg_ISDA = NOTIONAL * PRICER.calculateProtectionLeg(today, stepinDate, valueDate, startDate, endDate, yieldCurve, res.creditCurve, RECOVERY_RATE, protectionStart);

      final double premLeg_clean_ISDA = res.fracSpread * rpv01_clean_ISDA;
      final double defaultAcc = res.fracSpread * (rpv01_clean_ISDA - rpv01_clean_ISDA_noAccOnDefault);
      final double rpv01_accrued = rpv01_dirty_ISDA - rpv01_clean_ISDA;
      final double accruedPrem = rpv01_accrued * res.fracSpread;

      // back out the accrued-days by inverting the accrued premium formula (which is ACT/360) - this matched the formula on the ISDA spread sheet
      final int accruedDays = (int) Math.round(360 * rpv01_accrued / NOTIONAL);

      if (debug) {
        System.out.println(count + "\t" + res.premiumLeg + "\t" + premLeg_clean_ISDA + "\t" + premLeg_clean_new + "\t\t" + res.protectionLeg + "\t" + contLeg_ISDA + "\t" + protectionLeg_new + "\t\t" +
            res.defaultAcc + "\t" + defaultAcc + "\t\t" + res.accruedPremium + "\t" + accruedPrem + "\t\t" + res.accruedDays + "\t" + accruedDays);
        try {
          // tests against ISDA c
          assertEquals("Premium Leg:", res.premiumLeg, premLeg_clean_ISDA, 1e-12 * NOTIONAL); // This should be 1e-15*NOTIONAL
          assertEquals("Protection Leg:", res.protectionLeg, contLeg_ISDA, 1e-11 * NOTIONAL); // ditto
          assertEquals("Default Acc:", res.defaultAcc, defaultAcc, 1e-13 * NOTIONAL);
          assertEquals("Accrued Premium: ", res.accruedPremium, accruedPrem, 1e-15 * NOTIONAL); // the accrued is trivial, so should be highly accurate
          assertEquals("Accrued Days: ", res.accruedDays, accruedDays);

          // tests date free vs date-full code
          assertEquals("Premium Leg:", premLeg_clean_ISDA, premLeg_clean_new, 1e-13 * NOTIONAL);
          assertEquals("Protection Leg:", contLeg_ISDA, protectionLeg_new, 1e-16 * NOTIONAL);
        } catch (final AssertionError e) {
          failedList[failCount++] = count;
        }
      } else {
        // tests against ISDA c
        assertEquals("Premium Leg:", res.premiumLeg, premLeg_clean_ISDA, 1e-12 * NOTIONAL); // This should be 1e-15*NOTIONAL
        assertEquals("Protection Leg:", res.protectionLeg, contLeg_ISDA, 1e-11 * NOTIONAL); // ditto
        assertEquals("Default Acc:", res.defaultAcc, defaultAcc, 1e-13 * NOTIONAL);
        assertEquals("Accrued Premium: ", res.accruedPremium, accruedPrem, 1e-15 * NOTIONAL); // the accrued is trivial, so should be highly accurate
        assertEquals("Accrued Days: ", res.accruedDays, accruedDays);

        // tests date free vs date-full code
        assertEquals("Premium Leg:", premLeg_clean_ISDA, premLeg_clean_new, 1e-13 * NOTIONAL);
        assertEquals("Protection Leg:", contLeg_ISDA, protectionLeg_new, 1e-15 * NOTIONAL);
      }
    }
    if (debug) {
      System.out.println("\nFailed to construct: " + constructionFailCount + " Failed: " + failCount);
      if (failCount > 0) {
        System.out.print("failed index:");
        for (int i = 0; i < failCount; i++) {
          System.out.print("\t" + failedList[i]);
        }
        System.out.print("\n");
      }
      System.out.print("\n");

    }
  }

  @Test
  // (enabled = false)
  public void example1Test() {
    testISDA_Results(EXAMPLE1, YIELD_CURVE_ZERO_FLAT, false);
  }

  @Test
  // (enabled = false)
  public void example3Test() {
    testISDA_Results(EXAMPLE3, YIELD_CURVE_ZERO_FLAT, false);
  }

  @Test
  // (enabled = false)
  public void exampleSheet1Test() {
    testISDA_Results(ISDAModelDatasetsSheetReader.loadSheet("yield_curve_flat_0pc.csv", RECOVERY_RATE), YIELD_CURVE_ZERO_FLAT, false);
  }

  @Test
  // (enabled = false)
  public void exampleSheet2Test() {
    testISDA_Results(ISDAModelDatasetsSheetReader.loadSheet("yield_curve_flat_5pc.csv", RECOVERY_RATE), YIELD_CURVE_5PC_FLAT, false);
  }

  @Test
  public void yieldCurveTest() {
    final int n = YC_TIMES.length;
    for (int i = 0; i < n; i++) {
      final double t = YC_TIMES[i];
      final double df = YIELD_CURVE_ZERO_FLAT.getDiscountFactor(t);
      assertEquals(DISCOUNT_FACT[i], df, 1e-10);
    }
  }

}
TOP

Related Classes of com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.isdanew.ISDACompliantPresentValueCreditDefaultSwapTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.