def test_CDSFastApproximation(): valueDate = FinDate(2018, 6, 20) # I build a discount curve that requires no bootstrap times = np.linspace(0, 10.0, 11) r = 0.05 discountFactors = np.power((1.0 + r), -times) dates = valueDate.addYears(times) liborCurve = FinDiscountCurve(valueDate, dates, discountFactors, FinInterpTypes.FLAT_FWD_RATES) ########################################################################## maturityDate = valueDate.nextCDSDate(120) t = (maturityDate - valueDate) / 365.242 z = liborCurve.df(maturityDate) r = -np.log(z) / t recoveryRate = 0.40 contractCoupon = 0.010 testCases.header("MKT_SPD", "EXACT_VALUE", "APPROX_VALUE", "DIFF(%NOT)") for mktCoupon in np.linspace(0.000, 0.05, 21): cdsContracts = [] cdsMkt = FinCDS(valueDate, maturityDate, mktCoupon, ONE_MILLION) cdsContracts.append(cdsMkt) issuerCurve = FinCDSCurve(valueDate, cdsContracts, liborCurve, recoveryRate) cdsContract = FinCDS(valueDate, maturityDate, contractCoupon) v_exact = cdsContract.value( valueDate, issuerCurve, recoveryRate)['full_pv'] v_approx = cdsContract.valueFastApprox( valueDate, r, mktCoupon, recoveryRate)[0] pctdiff = (v_exact - v_approx) / ONE_MILLION * 100.0 testCases.print(mktCoupon * 10000, v_exact, v_approx, pctdiff)
def test_FinDate(): startDate = FinDate(1, 1, 2018) testCases.header("DATE", "MONTHS", "CDS DATE") for numMonths in range(0, 120): nextCDSDate = startDate.nextCDSDate(numMonths) testCases.print(str(startDate), numMonths, str(nextCDSDate)) startDate = FinDate(1, 1, 2018) testCases.header("STARTDATE", "MONTHS", "CDS DATE") for numMonths in range(0, 365): startDate = startDate.addDays(1) nextIMMDate = startDate.nextIMMDate() testCases.print(numMonths, str(startDate), str(nextIMMDate))
def test_CDSIndexPortfolio(): tradeDate = FinDate(1, 8, 2007) stepInDate = tradeDate.addDays(1) valuationDate = stepInDate liborCurve = buildIborCurve(tradeDate) maturity3Y = tradeDate.nextCDSDate(36) maturity5Y = tradeDate.nextCDSDate(60) maturity7Y = tradeDate.nextCDSDate(84) maturity10Y = tradeDate.nextCDSDate(120) path = os.path.join(os.path.dirname(__file__), './/data//CDX_NA_IG_S7_SPREADS.csv') f = open(path, 'r') data = f.readlines() f.close() issuerCurves = [] for row in data[1:]: splitRow = row.split(",") spd3Y = float(splitRow[1]) / 10000.0 spd5Y = float(splitRow[2]) / 10000.0 spd7Y = float(splitRow[3]) / 10000.0 spd10Y = float(splitRow[4]) / 10000.0 recoveryRate = float(splitRow[5]) cds3Y = FinCDS(stepInDate, maturity3Y, spd3Y) cds5Y = FinCDS(stepInDate, maturity5Y, spd5Y) cds7Y = FinCDS(stepInDate, maturity7Y, spd7Y) cds10Y = FinCDS(stepInDate, maturity10Y, spd10Y) cdsContracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuerCurve = FinCDSCurve(valuationDate, cdsContracts, liborCurve, recoveryRate) issuerCurves.append(issuerCurve) ########################################################################## # Now determine the average spread of the index ########################################################################## cdsIndex = FinCDSIndexPortfolio() averageSpd3Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity3Y, issuerCurves) * 10000.0 averageSpd5Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity5Y, issuerCurves) * 10000.0 averageSpd7Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity7Y, issuerCurves) * 10000.0 averageSpd10Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity10Y, issuerCurves) * 10000.0 testCases.header("LABEL", "VALUE") testCases.print("AVERAGE SPD 3Y", averageSpd3Y) testCases.print("AVERAGE SPD 5Y", averageSpd5Y) testCases.print("AVERAGE SPD 7Y", averageSpd7Y) testCases.print("AVERAGE SPD 10Y", averageSpd10Y) ########################################################################## # Now determine the intrinsic spread of the index to the same maturity # dates. As the single name CDS contracts ########################################################################## cdsIndex = FinCDSIndexPortfolio() intrinsicSpd3Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity3Y, issuerCurves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity5Y, issuerCurves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity7Y, issuerCurves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity10Y, issuerCurves) * 10000.0 ########################################################################## ########################################################################## testCases.header("LABEL", "VALUE") testCases.print("INTRINSIC SPD 3Y", intrinsicSpd3Y) testCases.print("INTRINSIC SPD 5Y", intrinsicSpd5Y) testCases.print("INTRINSIC SPD 7Y", intrinsicSpd7Y) testCases.print("INTRINSIC SPD 10Y", intrinsicSpd10Y)
def test_performCDSIndexHazardRateAdjustment(): tradeDate = FinDate(2007, 8, 1) stepInDate = tradeDate.addDays(1) valuationDate = stepInDate liborCurve = buildLiborCurve(tradeDate) maturity3Y = tradeDate.nextCDSDate(36) maturity5Y = tradeDate.nextCDSDate(60) maturity7Y = tradeDate.nextCDSDate(84) maturity10Y = tradeDate.nextCDSDate(120) path = dirname(__file__) filename = "CDX_NA_IG_S7_SPREADS.csv" full_filename_path = join(path, "data", filename) f = open(full_filename_path, 'r') data = f.readlines() issuerCurves = [] for row in data[1:]: splitRow = row.split(",") spd3Y = float(splitRow[1]) / 10000.0 spd5Y = float(splitRow[2]) / 10000.0 spd7Y = float(splitRow[3]) / 10000.0 spd10Y = float(splitRow[4]) / 10000.0 recoveryRate = float(splitRow[5]) cds3Y = FinCDS(stepInDate, maturity3Y, spd3Y) cds5Y = FinCDS(stepInDate, maturity5Y, spd5Y) cds7Y = FinCDS(stepInDate, maturity7Y, spd7Y) cds10Y = FinCDS(stepInDate, maturity10Y, spd10Y) cdsContracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuerCurve = FinCDSCurve(valuationDate, cdsContracts, liborCurve, recoveryRate) issuerCurves.append(issuerCurve) ########################################################################## # Now determine the average spread of the index ########################################################################## cdsIndex = FinCDSIndexPortfolio() averageSpd3Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity3Y, issuerCurves) * 10000.0 averageSpd5Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity5Y, issuerCurves) * 10000.0 averageSpd7Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity7Y, issuerCurves) * 10000.0 averageSpd10Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity10Y, issuerCurves) * 10000.0 testCases.header("LABEL", "VALUE") testCases.print("AVERAGE SPD 3Y", averageSpd3Y) testCases.print("AVERAGE SPD 5Y", averageSpd5Y) testCases.print("AVERAGE SPD 7Y", averageSpd7Y) testCases.print("AVERAGE SPD 10Y", averageSpd10Y) testCases.banner( "===================================================================") ########################################################################## # Now determine the intrinsic spread of the index to the same maturity dates # As the single name CDS contracts ########################################################################## cdsIndex = FinCDSIndexPortfolio() intrinsicSpd3Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity3Y, issuerCurves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity5Y, issuerCurves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity7Y, issuerCurves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread( valuationDate, stepInDate, maturity10Y, issuerCurves) * 10000.0 ########################################################################## ########################################################################## testCases.header("LABEL", "VALUE") testCases.print("INTRINSIC SPD 3Y", intrinsicSpd3Y) testCases.print("INTRINSIC SPD 5Y", intrinsicSpd5Y) testCases.print("INTRINSIC SPD 7Y", intrinsicSpd7Y) testCases.print("INTRINSIC SPD 10Y", intrinsicSpd10Y) testCases.banner( "===================================================================") ########################################################################## ########################################################################## indexCoupons = [0.002, 0.0037, 0.0050, 0.0063] indexUpfronts = [0.0, 0.0, 0.0, 0.0] indexMaturityDates = [ FinDate(2009, 12, 20), FinDate(2011, 12, 20), FinDate(2013, 12, 20), FinDate(2016, 12, 20) ] indexRecoveryRate = 0.40 tolerance = 1e-6 import time start = time.time() adjustedIssuerCurves = FinCDSIndexPortfolio.hazardRateAdjustIntrinsic( valuationDate, issuerCurves, indexCoupons, indexUpfronts, indexMaturityDates, indexRecoveryRate, tolerance) end = time.time() testCases.header("TIME") testCases.print(end - start) # numCredits = len(issuerCurves) # testCases.print("#","MATURITY","CDS_UNADJ","CDS_ADJ") # for m in range(0,numCredits): # for cds in cdsContracts: # unadjustedSpread = cds.parSpread(valuationDate,issuerCurves[m]) # adjustedSpread = cds.parSpread(valuationDate,adjustedIssuerCurves[m]) # testCases.print(m,str(cds._maturityDate),"%10.3f"%(unadjustedSpread*10000),"%10.3f" %(adjustedSpread*10000)) cdsIndex = FinCDSIndexPortfolio() intrinsicSpd3Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[0], adjustedIssuerCurves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[1], adjustedIssuerCurves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[2], adjustedIssuerCurves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[3], adjustedIssuerCurves) * 10000.0 # If the adjustment works then this should equal the index spreads testCases.header("LABEL", "VALUE") testCases.print("ADJUSTED INTRINSIC SPD 3Y", intrinsicSpd3Y) testCases.print("ADJUSTED INTRINSIC SPD 5Y", intrinsicSpd5Y) testCases.print("ADJUSTED INTRINSIC SPD 7Y", intrinsicSpd7Y) testCases.print("ADJUSTED INTRINSIC SPD 10Y", intrinsicSpd10Y)
def test_fullPriceCDSIndexOption(): tradeDate = FinDate(1, 8, 2007) stepInDate = tradeDate.addDays(1) valuationDate = stepInDate liborCurve = buildIborCurve(tradeDate) maturity3Y = tradeDate.nextCDSDate(36) maturity5Y = tradeDate.nextCDSDate(60) maturity7Y = tradeDate.nextCDSDate(84) maturity10Y = tradeDate.nextCDSDate(120) path = os.path.join(os.path.dirname(__file__), './/data//CDX_NA_IG_S7_SPREADS.csv') f = open(path, 'r') data = f.readlines() f.close() issuerCurves = [] for row in data[1:]: splitRow = row.split(",") creditName = splitRow[0] spd3Y = float(splitRow[1]) / 10000.0 spd5Y = float(splitRow[2]) / 10000.0 spd7Y = float(splitRow[3]) / 10000.0 spd10Y = float(splitRow[4]) / 10000.0 recoveryRate = float(splitRow[5]) cds3Y = FinCDS(stepInDate, maturity3Y, spd3Y) cds5Y = FinCDS(stepInDate, maturity5Y, spd5Y) cds7Y = FinCDS(stepInDate, maturity7Y, spd7Y) cds10Y = FinCDS(stepInDate, maturity10Y, spd10Y) cdsContracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuerCurve = FinCDSCurve(valuationDate, cdsContracts, liborCurve, recoveryRate) issuerCurves.append(issuerCurve) ########################################################################## ########################################################################## indexUpfronts = [0.0, 0.0, 0.0, 0.0] indexMaturityDates = [ FinDate(20, 12, 2009), FinDate(20, 12, 2011), FinDate(20, 12, 2013), FinDate(20, 12, 2016) ] indexRecovery = 0.40 testCases.banner( "======================= CDS INDEX OPTION ==========================") indexCoupon = 0.004 volatility = 0.50 expiryDate = FinDate(1, 2, 2008) maturityDate = FinDate(20, 12, 2011) notional = 10000.0 tolerance = 1e-6 testCases.header("TIME", "STRIKE", "INDEX", "PAY", "RECEIVER", "G(K)", "X", "EXPH", "ABPAY", "ABREC") for index in np.linspace(20, 60, 10): ####################################################################### cdsContracts = [] for dt in indexMaturityDates: cds = FinCDS(valuationDate, dt, index / 10000.0) cdsContracts.append(cds) indexCurve = FinCDSCurve(valuationDate, cdsContracts, liborCurve, indexRecovery) if 1 == 1: indexSpreads = [index / 10000.0] * 4 indexPortfolio = FinCDSIndexPortfolio() adjustedIssuerCurves = indexPortfolio.hazardRateAdjustIntrinsic( valuationDate, issuerCurves, indexSpreads, indexUpfronts, indexMaturityDates, indexRecovery, tolerance) else: indexSpread = index / 10000.0 issuerCurve = buildFlatIssuerCurve(tradeDate, liborCurve, indexSpread, indexRecovery) adjustedIssuerCurves = [] for iCredit in range(0, 125): adjustedIssuerCurves.append(issuerCurve) ####################################################################### for strike in np.linspace(20, 60, 20): start = time.time() option = FinCDSIndexOption(expiryDate, maturityDate, indexCoupon, strike / 10000.0, notional) v_pay_1, v_rec_1, strikeValue, mu, expH = option.valueAnderson( valuationDate, adjustedIssuerCurves, indexRecovery, volatility) end = time.time() elapsed = end - start end = time.time() v_pay_2, v_rec_2 = option.valueAdjustedBlack( valuationDate, indexCurve, indexRecovery, liborCurve, volatility) elapsed = end - start testCases.print(elapsed, strike, index, v_pay_1, v_rec_1, strikeValue, mu, expH, v_pay_2, v_rec_2)
def test_CDSIndexAdjustSpreads(): tradeDate = FinDate(1, 8, 2007) stepInDate = tradeDate.addDays(1) valuationDate = tradeDate liborCurve = buildIborCurve(tradeDate) maturity3Y = tradeDate.nextCDSDate(36) maturity5Y = tradeDate.nextCDSDate(60) maturity7Y = tradeDate.nextCDSDate(84) maturity10Y = tradeDate.nextCDSDate(120) path = dirname(__file__) filename = "CDX_NA_IG_S7_SPREADS.csv" full_filename_path = join(path, "data", filename) f = open(full_filename_path, 'r') data = f.readlines() issuerCurves = [] for row in data[1:]: splitRow = row.split(",") spd3Y = float(splitRow[1]) / 10000.0 spd5Y = float(splitRow[2]) / 10000.0 spd7Y = float(splitRow[3]) / 10000.0 spd10Y = float(splitRow[4]) / 10000.0 recoveryRate = float(splitRow[5]) cds3Y = FinCDS(stepInDate, maturity3Y, spd3Y) cds5Y = FinCDS(stepInDate, maturity5Y, spd5Y) cds7Y = FinCDS(stepInDate, maturity7Y, spd7Y) cds10Y = FinCDS(stepInDate, maturity10Y, spd10Y) cdsContracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuerCurve = FinCDSCurve(valuationDate, cdsContracts, liborCurve, recoveryRate) issuerCurves.append(issuerCurve) ########################################################################## # Now determine the average spread of the index ########################################################################## cdsIndex = FinCDSIndexPortfolio() averageSpd3Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity3Y, issuerCurves) * 10000.0 averageSpd5Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity5Y, issuerCurves) * 10000.0 averageSpd7Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity7Y, issuerCurves) * 10000.0 averageSpd10Y = cdsIndex.averageSpread(valuationDate, stepInDate, maturity10Y, issuerCurves) * 10000.0 testCases.header("LABEL", "VALUE") testCases.print("AVERAGE SPD 3Y", averageSpd3Y) testCases.print("AVERAGE SPD 5Y", averageSpd5Y) testCases.print("AVERAGE SPD 7Y", averageSpd7Y) testCases.print("AVERAGE SPD 10Y", averageSpd10Y) ########################################################################## # Now determine the intrinsic spread of the index to the same maturity dates # As the single name CDS contracts ########################################################################## cdsIndex = FinCDSIndexPortfolio() intrinsicSpd3Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, maturity3Y, issuerCurves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, maturity5Y, issuerCurves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, maturity7Y, issuerCurves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, maturity10Y, issuerCurves) * 10000.0 ########################################################################## ########################################################################## testCases.header("LABEL", "VALUE") testCases.print("INTRINSIC SPD 3Y", intrinsicSpd3Y) testCases.print("INTRINSIC SPD 5Y", intrinsicSpd5Y) testCases.print("INTRINSIC SPD 7Y", intrinsicSpd7Y) testCases.print("INTRINSIC SPD 10Y", intrinsicSpd10Y) ########################################################################## ########################################################################## indexCoupons = [0.002, 0.0037, 0.0050, 0.0063] indexUpfronts = [0.0, 0.0, 0.0, 0.0] indexMaturityDates = [FinDate(20, 12, 2009), FinDate(20, 12, 2011), FinDate(20, 12, 2013), FinDate(20, 12, 2016)] indexRecoveryRate = 0.40 tolerance = 1e-7 import time start = time.time() indexPortfolio = FinCDSIndexPortfolio() adjustedIssuerCurves = indexPortfolio.spreadAdjustIntrinsic( valuationDate, issuerCurves, indexCoupons, indexUpfronts, indexMaturityDates, indexRecoveryRate, tolerance) end = time.time() testCases.header("TIME") testCases.print(end - start) cdsIndex = FinCDSIndexPortfolio() intrinsicSpd3Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[0], adjustedIssuerCurves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[1], adjustedIssuerCurves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[2], adjustedIssuerCurves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread(valuationDate, stepInDate, indexMaturityDates[3], adjustedIssuerCurves) * 10000.0 # If the adjustment works then this should equal the index spreads testCases.header("LABEL", "VALUE") testCases.print("ADJUSTED INTRINSIC SPD 3Y:", intrinsicSpd3Y) testCases.print("ADJUSTED INTRINSIC SPD 5Y:", intrinsicSpd5Y) testCases.print("ADJUSTED INTRINSIC SPD 7Y", intrinsicSpd7Y) testCases.print("ADJUSTED INTRINSIC SPD 10Y", intrinsicSpd10Y)
# print(dt5) # You can use tenors - a number and a 'd', 'm' or 'y' in upper or lower case print("TENORS") print(dt1.addTenor("1d")) print(dt1.addTenor("2D")) print(dt1.addTenor("3M")) print(dt1.addTenor("4m")) print(dt1.addTenor("5Y")) print(dt1.addTenor("6y")) # You can subtract dates print("SUBTRACT DATES") dt6 = dt1.addTenor("5Y") dt7 = dt1.addTenor("10Y") dd = dt7 - dt6 print(dt6, dt7, dd) # check if a date is on a weekend print("WEEKEND TEST") print(dt1, dt1.isWeekend()) print(dt2, dt2.isWeekend()) # You can get CDS dates now or in the future print("CDS Date") print(dt1, dt1.nextCDSDate()) # You can get the next IMM dates now print("IMM Date") print(dt1, dt1.nextIMMDate())