Package com.opengamma.analytics.financial.credit.creditdefaultswap.greeks.vanilla

Source Code of com.opengamma.analytics.financial.credit.creditdefaultswap.greeks.vanilla.IR01CreditDefaultSwap

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.ZonedDateTime;

import com.opengamma.analytics.financial.credit.PriceType;
import com.opengamma.analytics.financial.credit.creditdefaultswap.definition.legacy.LegacyVanillaCreditDefaultSwapDefinition;
import com.opengamma.analytics.financial.credit.creditdefaultswap.pricing.vanilla.PresentValueCreditDefaultSwap;
import com.opengamma.analytics.financial.credit.isdayieldcurve.ISDADateCurve;
import com.opengamma.analytics.financial.credit.isdayieldcurve.InterestRateBumpType;
import com.opengamma.analytics.financial.credit.marketdatachecker.SpreadTermStructureDataChecker;
import com.opengamma.financial.convention.daycount.ActualThreeSixtyFive;
import com.opengamma.financial.convention.daycount.DayCount;
import com.opengamma.util.ArgumentChecker;

/**
* Class containing methods for the computation of IR01 for a vanilla Legacy CDS (parallel and bucketed bumps)
*/
public class IR01CreditDefaultSwap {
  private static final Logger s_logger = LoggerFactory.getLogger(IR01CreditDefaultSwap.class);

  //------------------------------------------------------------------------------------------------------------------------------------------

  private final double _tolerance = 1e-15;

  private static final DayCount ACT365 = new ActualThreeSixtyFive();

  private static final PresentValueCreditDefaultSwap PV_CALCULATOR = new PresentValueCreditDefaultSwap();

  private static final SpreadTermStructureDataChecker DATA_CHECKER = new SpreadTermStructureDataChecker();

  //-------------------------------------------------------------------------------------------------

  // TODO : Lots of ongoing work to do in this class - Work In Progress

  // TODO : Further checks on efficacy of input arguments
  // TODO : Need to get the times[] calculation correct
  // TODO : Need to consider more sophisticated sensitivity calculations e.g. algorithmic differentiation

  // NOTE : We enforce rateBump > 0, therefore if the marketSpreads > 0 (an exception is thrown if this is not the case) then bumpedMarketSpreads > 0 by construction

  // ------------------------------------------------------------------------------------------------------------------------------------------

  // Compute the IR01 by a parallel bump of each point on the yield curve

  public double getIR01ParallelShiftCreditDefaultSwap(
      final ZonedDateTime valuationDate,
      final LegacyVanillaCreditDefaultSwapDefinition cds,
      final ISDADateCurve yieldCurve,
      final ZonedDateTime[] marketTenors,
      final double[] marketSpreads,
      final double interestRateBump,
      final InterestRateBumpType interestRateBumpType,
      final PriceType priceType) {

    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Check input objects are not null

    ArgumentChecker.notNull(valuationDate, "Valuation date");
    ArgumentChecker.notNull(cds, "LegacyCreditDefaultSwapDefinition");
    ArgumentChecker.notNull(yieldCurve, "YieldCurve");
    ArgumentChecker.notNull(marketTenors, "Market tenors");
    ArgumentChecker.notNull(marketSpreads, "Market spreads");
    ArgumentChecker.notNull(interestRateBumpType, "Interest rate bump type");
    ArgumentChecker.notNull(priceType, "price type");

    ArgumentChecker.notNegative(interestRateBump, "Interest rate bump");

    // Check the efficacy of the input market data
    DATA_CHECKER.checkSpreadData(valuationDate, /*cds, */marketTenors, marketSpreads);

    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Vector to hold the bumped market spreads
    final int nRates = yieldCurve.getNumberOfCurvePoints();
    final Double[] interestRates = yieldCurve.getCurve().getYData();
    final double[] bumpedInterestRates = new double[nRates];

    // ----------------------------------------------------------------------------------------------------------------------------------------

    final double bumpInBp = interestRateBump / 10000;
    // Calculate the bumped spreads
    switch (interestRateBumpType) {
      case ADDITIVE_PARALLEL:
        for (int m = 0; m < nRates; m++) {
          bumpedInterestRates[m] = interestRates[m] + bumpInBp;
        }
        break;
      case MULTIPLICATIVE_PARALLEL:
        for (int m = 0; m < nRates; m++) {
          bumpedInterestRates[m] = interestRates[m] * (1 + bumpInBp);
        }
        break;
      default:
        throw new IllegalArgumentException("Cannot support bumps of type " + interestRateBumpType);
    }

    final ISDADateCurve bumpedYieldCurve = new ISDADateCurve("Bumped", yieldCurve.getCurveDates(), yieldCurve.getTimePoints(), bumpedInterestRates, yieldCurve.getOffset());

    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Calculate the unbumped CDS PV
    final double presentValue = PV_CALCULATOR.calibrateAndGetPresentValue(valuationDate, cds, marketTenors, marketSpreads, yieldCurve, priceType);

    // Calculate the bumped (up) CDS PV
    final double bumpedPresentValue = PV_CALCULATOR.calibrateAndGetPresentValue(valuationDate, cds, marketTenors, marketSpreads, bumpedYieldCurve, priceType);

    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Calculate the parallel CS01
    return (bumpedPresentValue - presentValue) / interestRateBump;
  }

  // ------------------------------------------------------------------------------------------------------------------------------------------

  // Compute the IR01 by bumping each point on the yield curve individually by interestRateBump (bump is same for all tenors)

  public double[] getIR01BucketedCreditDefaultSwap(
      final ZonedDateTime valuationDate,
      final LegacyVanillaCreditDefaultSwapDefinition cds,
      final ISDADateCurve yieldCurve,
      final ZonedDateTime[] marketTenors,
      final double[] marketSpreads,
      final double interestRateBump,
      final InterestRateBumpType interestRateBumpType,
      final PriceType priceType) {

    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Check input objects are not null

    ArgumentChecker.notNull(valuationDate, "Valuation date");
    ArgumentChecker.notNull(cds, "LegacyCreditDefaultSwapDefinition");
    ArgumentChecker.notNull(yieldCurve, "YieldCurve");
    ArgumentChecker.notNull(marketTenors, "Market tenors");
    ArgumentChecker.notNull(marketSpreads, "Market spreads");
    ArgumentChecker.notNull(interestRateBumpType, "interest rate bump type");

    ArgumentChecker.notNegative(interestRateBump, "interest rate bump");

    // Check the efficacy of the input market data
    DATA_CHECKER.checkSpreadData(valuationDate, /*cds, */marketTenors, marketSpreads);

    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Vector of bucketed CS01 sensitivities (per tenor)
    final int nRates = yieldCurve.getNumberOfCurvePoints();
    final double[] bucketedIR01 = new double[nRates];
    final double bumpInBp = interestRateBump / 10000;

    // Vector to hold the bumped market spreads
    final Double[] interestRates = yieldCurve.getCurve().getYData();
    final double[] bumpedInterestRates = new double[nRates];
    for (int i = 0; i < nRates; i++) {
      bumpedInterestRates[i] = interestRates[i];
    }
    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Calculate the unbumped CDS PV
    final double presentValue = PV_CALCULATOR.calibrateAndGetPresentValue(valuationDate, cds, marketTenors, marketSpreads, yieldCurve, priceType);

    // ----------------------------------------------------------------------------------------------------------------------------------------

    // Loop through and bump each of the spreads at each tenor
    ISDADateCurve bumpedYieldCurve;
    double bumpedPresentValue;
    for (int m = 0; m < nRates; m++) {
      switch (interestRateBumpType) {
        case ADDITIVE:
          bumpedInterestRates[m] += bumpInBp;
          try {
            bumpedYieldCurve = new ISDADateCurve("Bumped", marketTenors, yieldCurve.getTimePoints(), bumpedInterestRates, yieldCurve.getOffset());
          } catch (ArrayIndexOutOfBoundsException aioobe) {
            s_logger.error("AIOOBE", aioobe);
            throw aioobe;
          }
          bumpedPresentValue = PV_CALCULATOR.calibrateAndGetPresentValue(valuationDate, cds, marketTenors, marketSpreads, bumpedYieldCurve, priceType);
          bucketedIR01[m] = (bumpedPresentValue - presentValue) / interestRateBump;
          bumpedInterestRates[m] -= bumpInBp;
          break;
        case MULTIPLICATIVE:
          bumpedInterestRates[m] *= 1 + bumpInBp;
          bumpedYieldCurve = new ISDADateCurve("Bumped", marketTenors, yieldCurve.getTimePoints(), bumpedInterestRates, yieldCurve.getOffset());
          bumpedPresentValue = PV_CALCULATOR.calibrateAndGetPresentValue(valuationDate, cds, marketTenors, marketSpreads, bumpedYieldCurve, priceType);
          bucketedIR01[m] = (bumpedPresentValue - presentValue) / interestRateBump;
          bumpedInterestRates[m] /= 1 + bumpInBp;
          break;
        default:
          throw new IllegalArgumentException("Cannot handle bumps of type " + interestRateBumpType);
      }
    }
    // ----------------------------------------------------------------------------------------------------------------------------------------

    return bucketedIR01;
  }

  // ------------------------------------------------------------------------------------------------------------------------------------------

}
TOP

Related Classes of com.opengamma.analytics.financial.credit.creditdefaultswap.greeks.vanilla.IR01CreditDefaultSwap

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.