def loadHeterogeneousSpreadCurves(valuation_date, libor_curve): maturity3Y = valuation_date.nextCDSDate(36) maturity5Y = valuation_date.nextCDSDate(60) maturity7Y = valuation_date.nextCDSDate(84) maturity10Y = valuation_date.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() issuer_curves = [] 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 recovery_rate = float(splitRow[5]) cds3Y = FinCDS(valuation_date, maturity3Y, spd3Y) cds5Y = FinCDS(valuation_date, maturity5Y, spd5Y) cds7Y = FinCDS(valuation_date, maturity7Y, spd7Y) cds10Y = FinCDS(valuation_date, maturity10Y, spd10Y) cds_contracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuer_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve, recovery_rate) issuer_curves.append(issuer_curve) return issuer_curves
def loadHomogeneousSpreadCurves(valuation_date, libor_curve, cdsSpread3Y, cdsSpread5Y, cdsSpread7Y, cdsSpread10Y, num_credits): maturity3Y = valuation_date.nextCDSDate(36) maturity5Y = valuation_date.nextCDSDate(60) maturity7Y = valuation_date.nextCDSDate(84) maturity10Y = valuation_date.nextCDSDate(120) recovery_rate = 0.40 cds3Y = FinCDS(valuation_date, maturity3Y, cdsSpread3Y) cds5Y = FinCDS(valuation_date, maturity5Y, cdsSpread5Y) cds7Y = FinCDS(valuation_date, maturity7Y, cdsSpread7Y) cds10Y = FinCDS(valuation_date, maturity10Y, cdsSpread10Y) contracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuer_curve = FinCDSCurve(valuation_date, contracts, libor_curve, recovery_rate) issuer_curves = [] for _ in range(0, num_credits): issuer_curves.append(issuer_curve) return issuer_curves
def test_valueCDSIndex(): # We treat an index as a CDS contract with a flat CDS curve tradeDate = Date(7, 2, 2006) libor_curve = buildIborCurve(tradeDate) issuer_curve = buildIssuerCurve(tradeDate, libor_curve) step_in_date = tradeDate.addDays(1) valuation_date = step_in_date maturity_date = Date(20, 6, 2010) cdsRecovery = 0.40 notional = 10.0 * ONE_MILLION long_protection = True index_coupon = 0.004 cdsIndexContract = FinCDS(step_in_date, maturity_date, index_coupon, notional, long_protection) # cdsIndexContract.print(valuation_date) testCases.header("LABEL", "VALUE") spd = cdsIndexContract.parSpread(valuation_date, issuer_curve, cdsRecovery) * 10000.0 testCases.print("PAR SPREAD", spd) v = cdsIndexContract.value(valuation_date, issuer_curve, cdsRecovery) testCases.print("FULL VALUE", v['full_pv']) testCases.print("CLEAN VALUE", v['clean_pv']) p = cdsIndexContract.clean_price(valuation_date, issuer_curve, cdsRecovery) testCases.print("CLEAN PRICE", p) accrued_days = cdsIndexContract.accrued_days() testCases.print("ACCRUED DAYS", accrued_days) accruedInterest = cdsIndexContract.accruedInterest() testCases.print("ACCRUED COUPON", accruedInterest) prot_pv = cdsIndexContract.protectionLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PROTECTION LEG PV", prot_pv) premPV = cdsIndexContract.premiumLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PREMIUM LEG PV", premPV) fullRPV01, cleanRPV01 = cdsIndexContract.riskyPV01(valuation_date, issuer_curve) testCases.print("FULL RPV01", fullRPV01) testCases.print("CLEAN RPV01", cleanRPV01)
def test_CDSFastApproximation(): valuation_date = Date(20, 6, 2018) # I build a discount curve that requires no bootstrap times = np.linspace(0, 10.0, 11) r = 0.05 discount_factors = np.power((1.0 + r), -times) dates = valuation_date.addYears(times) libor_curve = DiscountCurve(valuation_date, dates, discount_factors, FinInterpTypes.FLAT_FWD_RATES) ########################################################################## maturity_date = valuation_date.nextCDSDate(120) t = (maturity_date - valuation_date) / 365.242 z = libor_curve.df(maturity_date) r = -np.log(z) / t recovery_rate = 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): cds_contracts = [] cdsMkt = FinCDS(valuation_date, maturity_date, mktCoupon, ONE_MILLION) cds_contracts.append(cdsMkt) issuer_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve, recovery_rate) cds_contract = FinCDS(valuation_date, maturity_date, contractCoupon) v_exact = cds_contract.value(valuation_date, issuer_curve, recovery_rate)['full_pv'] v_approx = cds_contract.valueFastApprox(valuation_date, r, mktCoupon, recovery_rate)[0] pctdiff = (v_exact - v_approx) / ONE_MILLION * 100.0 testCases.print(mktCoupon * 10000, v_exact, v_approx, pctdiff)
def test_full_priceCDSConvergence(): _, issuer_curve = buildFullIssuerCurve1(0.0, 0.0) # This is the 10 year contract at an off market coupon maturity_date = Date(20, 6, 2029) cdsCoupon = 0.0150 notional = ONE_MILLION long_protection = False tradeDate = Date(9, 8, 2019) valuation_date = tradeDate.addDays(1) cds_contract = FinCDS(valuation_date, maturity_date, cdsCoupon, notional, long_protection) cdsRecovery = 0.40 testCases.header("NumSteps", "Value") for n in [10, 50, 100, 500, 1000]: v_full = cds_contract.value(valuation_date, issuer_curve, cdsRecovery, 0, 1, n)['full_pv'] testCases.print(n, v_full)
def buildFlatIssuerCurve(tradeDate, libor_curve, spread, recovery_rate): valuation_date = tradeDate.addDays(1) cdsMarketContracts = [] maturity_date = Date(29, 6, 2010) cds = FinCDS(valuation_date, maturity_date, spread) cdsMarketContracts.append(cds) issuer_curve = FinCDSCurve(valuation_date, cdsMarketContracts, libor_curve, recovery_rate) return issuer_curve
def buildIssuerCurve(tradeDate, libor_curve): valuation_date = tradeDate.addDays(1) cdsMarketContracts = [] cdsCoupon = 0.0048375 maturity_date = Date(20, 6, 2010) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) recovery_rate = 0.40 issuer_curve = FinCDSCurve(valuation_date, cdsMarketContracts, libor_curve, recovery_rate) return issuer_curve
def test_IssuerCurveBuild(): """ Test issuer curve build with simple libor curve to isolate cds curve building time cost. """ valuation_date = Date(20, 6, 2018) times = np.linspace(0.0, 10.0, 11) r = 0.05 discount_factors = np.power((1.0 + r), -times) dates = valuation_date.addYears(times) libor_curve = DiscountCurve(valuation_date, dates, discount_factors, FinInterpTypes.FLAT_FWD_RATES) recovery_rate = 0.40 cds_contracts = [] cdsCoupon = 0.005 # 50 bps maturity_date = valuation_date.addMonths(12) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cds_contracts.append(cds) cdsCoupon = 0.0055 maturity_date = valuation_date.addMonths(24) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cds_contracts.append(cds) cdsCoupon = 0.0060 maturity_date = valuation_date.addMonths(36) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cds_contracts.append(cds) cdsCoupon = 0.0065 maturity_date = valuation_date.addMonths(60) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cds_contracts.append(cds) cdsCoupon = 0.0070 maturity_date = valuation_date.addMonths(84) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cds_contracts.append(cds) cdsCoupon = 0.0073 maturity_date = valuation_date.addMonths(120) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cds_contracts.append(cds) issuer_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve, recovery_rate) return cds_contracts, issuer_curve
def test_CDSDateGeneration(): # This is the 10 year contract at an off market coupon maturity_date = Date(20, 6, 2029) cdsCoupon = 0.0100 tradeDate = Date(9, 8, 2019) valuation_date = tradeDate.addDays(1) cds_contract = FinCDS(valuation_date, maturity_date, cdsCoupon, ONE_MILLION, True, FrequencyTypes.QUARTERLY, DayCountTypes.ACT_360, CalendarTypes.WEEKEND, BusDayAdjustTypes.FOLLOWING, DateGenRuleTypes.BACKWARD) testCases.header("Flow Date", "AccrualFactor", "Flow") num_flows = len(cds_contract._adjusted_dates) for n in range(0, num_flows): testCases.print(str(cds_contract._adjusted_dates[n]), cds_contract._accrual_factors[n], cds_contract._flows[n])
def buildFullIssuerCurve2(mktSpreadBump, irBump): # https://www.markit.com/markit.jsp?jsppage=pv.jsp # YIELD CURVE 20 August 2020 SNAP AT 1600 m = 1.0 valuation_date = Date(24, 8, 2020) settlement_date = Date(24, 8, 2020) dcType = DayCountTypes.ACT_360 depos = [] maturity_date = settlement_date.addMonths(1) depo1 = FinIborDeposit(settlement_date, maturity_date, m * 0.001709, dcType) maturity_date = settlement_date.addMonths(2) depo2 = FinIborDeposit(settlement_date, maturity_date, m * 0.002123, dcType) maturity_date = settlement_date.addMonths(3) depo3 = FinIborDeposit(settlement_date, maturity_date, m * 0.002469, dcType) maturity_date = settlement_date.addMonths(6) depo4 = FinIborDeposit(settlement_date, maturity_date, m * 0.003045, dcType) maturity_date = settlement_date.addMonths(12) depo5 = FinIborDeposit(settlement_date, maturity_date, m * 0.004449, dcType) depos.append(depo1) depos.append(depo2) depos.append(depo3) depos.append(depo4) depos.append(depo5) swaps = [] dcType = DayCountTypes.THIRTY_E_360_ISDA fixedFreq = FrequencyTypes.SEMI_ANNUAL maturity_date = settlement_date.addMonths(24) swap1 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.002155 + irBump, fixedFreq, dcType) swaps.append(swap1) maturity_date = settlement_date.addMonths(36) swap2 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.002305 + irBump, fixedFreq, dcType) swaps.append(swap2) maturity_date = settlement_date.addMonths(48) swap3 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.002665 + irBump, fixedFreq, dcType) swaps.append(swap3) maturity_date = settlement_date.addMonths(60) swap4 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.003290 + irBump, fixedFreq, dcType) swaps.append(swap4) libor_curve = IborSingleCurve(valuation_date, depos, [], swaps) cdsCoupon = 0.01 + mktSpreadBump cdsMarketContracts = [] effective_date = Date(21, 8, 2020) cds = FinCDS(effective_date, "6M", cdsCoupon) cdsMarketContracts.append(cds) cds = FinCDS(effective_date, "1Y", cdsCoupon) cdsMarketContracts.append(cds) cds = FinCDS(effective_date, "2Y", cdsCoupon) cdsMarketContracts.append(cds) cds = FinCDS(effective_date, "3Y", cdsCoupon) cdsMarketContracts.append(cds) cds = FinCDS(effective_date, "4Y", cdsCoupon) cdsMarketContracts.append(cds) cds = FinCDS(effective_date, "5Y", cdsCoupon) cdsMarketContracts.append(cds) cds = FinCDS(effective_date, "7Y", cdsCoupon) cdsMarketContracts.append(cds) cds = FinCDS(effective_date, "10Y", cdsCoupon) cdsMarketContracts.append(cds) recovery_rate = 0.40 issuer_curve = FinCDSCurve(settlement_date, cdsMarketContracts, libor_curve, recovery_rate) testCases.header("DATE", "DISCOUNT_FACTOR", "SURV_PROB") years = np.linspace(0.0, 10.0, 20) dates = settlement_date.addYears(years) for dt in dates: df = libor_curve.df(dt) q = issuer_curve.survProb(dt) testCases.print("%16s" % dt, "%12.8f" % df, "%12.8f" % q) return libor_curve, issuer_curve
def test_performCDSIndexHazardRateAdjustment(): tradeDate = Date(1, 8, 2007) step_in_date = tradeDate.addDays(1) valuation_date = step_in_date libor_curve = 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() issuer_curves = [] 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 recovery_rate = float(splitRow[5]) cds3Y = FinCDS(step_in_date, maturity3Y, spd3Y) cds5Y = FinCDS(step_in_date, maturity5Y, spd5Y) cds7Y = FinCDS(step_in_date, maturity7Y, spd7Y) cds10Y = FinCDS(step_in_date, maturity10Y, spd10Y) cds_contracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuer_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve, recovery_rate) issuer_curves.append(issuer_curve) ########################################################################## # Now determine the average spread of the index ########################################################################## cdsIndex = FinCDSIndexPortfolio() averageSpd3Y = cdsIndex.averageSpread(valuation_date, step_in_date, maturity3Y, issuer_curves) * 10000.0 averageSpd5Y = cdsIndex.averageSpread(valuation_date, step_in_date, maturity5Y, issuer_curves) * 10000.0 averageSpd7Y = cdsIndex.averageSpread(valuation_date, step_in_date, maturity7Y, issuer_curves) * 10000.0 averageSpd10Y = cdsIndex.averageSpread( valuation_date, step_in_date, maturity10Y, issuer_curves) * 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( valuation_date, step_in_date, maturity3Y, issuer_curves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread( valuation_date, step_in_date, maturity5Y, issuer_curves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread( valuation_date, step_in_date, maturity7Y, issuer_curves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread( valuation_date, step_in_date, maturity10Y, issuer_curves) * 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( "===================================================================") ########################################################################## ########################################################################## index_coupons = [0.002, 0.0037, 0.0050, 0.0063] indexUpfronts = [0.0, 0.0, 0.0, 0.0] indexMaturityDates = [ Date(20, 12, 2009), Date(20, 12, 2011), Date(20, 12, 2013), Date(20, 12, 2016) ] indexRecoveryRate = 0.40 tolerance = 1e-6 import time start = time.time() indexPortfolio = FinCDSIndexPortfolio() adjustedIssuerCurves = indexPortfolio.hazardRateAdjustIntrinsic( valuation_date, issuer_curves, index_coupons, indexUpfronts, indexMaturityDates, indexRecoveryRate, tolerance) end = time.time() testCases.header("TIME") testCases.print(end - start) # num_credits = len(issuer_curves) # testCases.print("#","MATURITY","CDS_UNADJ","CDS_ADJ") # for m in range(0,num_credits): # for cds in cds_contracts: # unadjustedSpread = cds.parSpread(valuation_date,issuer_curves[m]) # adjustedSpread = cds.parSpread(valuation_date,adjustedIssuerCurves[m]) # testCases.print(m,str(cds._maturity_date),"%10.3f"%(unadjustedSpread*10000),"%10.3f" %(adjustedSpread*10000)) cdsIndex = FinCDSIndexPortfolio() intrinsicSpd3Y = cdsIndex.intrinsicSpread(valuation_date, step_in_date, indexMaturityDates[0], adjustedIssuerCurves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread(valuation_date, step_in_date, indexMaturityDates[1], adjustedIssuerCurves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread(valuation_date, step_in_date, indexMaturityDates[2], adjustedIssuerCurves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread(valuation_date, step_in_date, 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_CDSIndexPortfolio(): tradeDate = Date(1, 8, 2007) step_in_date = tradeDate.addDays(1) valuation_date = step_in_date libor_curve = 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() issuer_curves = [] 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 recovery_rate = float(splitRow[5]) cds3Y = FinCDS(step_in_date, maturity3Y, spd3Y) cds5Y = FinCDS(step_in_date, maturity5Y, spd5Y) cds7Y = FinCDS(step_in_date, maturity7Y, spd7Y) cds10Y = FinCDS(step_in_date, maturity10Y, spd10Y) cds_contracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuer_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve, recovery_rate) issuer_curves.append(issuer_curve) ########################################################################## # Now determine the average spread of the index ########################################################################## cdsIndex = FinCDSIndexPortfolio() averageSpd3Y = cdsIndex.averageSpread(valuation_date, step_in_date, maturity3Y, issuer_curves) * 10000.0 averageSpd5Y = cdsIndex.averageSpread(valuation_date, step_in_date, maturity5Y, issuer_curves) * 10000.0 averageSpd7Y = cdsIndex.averageSpread(valuation_date, step_in_date, maturity7Y, issuer_curves) * 10000.0 averageSpd10Y = cdsIndex.averageSpread( valuation_date, step_in_date, maturity10Y, issuer_curves) * 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( valuation_date, step_in_date, maturity3Y, issuer_curves) * 10000.0 intrinsicSpd5Y = cdsIndex.intrinsicSpread( valuation_date, step_in_date, maturity5Y, issuer_curves) * 10000.0 intrinsicSpd7Y = cdsIndex.intrinsicSpread( valuation_date, step_in_date, maturity7Y, issuer_curves) * 10000.0 intrinsicSpd10Y = cdsIndex.intrinsicSpread( valuation_date, step_in_date, maturity10Y, issuer_curves) * 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 buildFullIssuerCurve(valuation_date): dcType = DayCountTypes.ACT_360 depos = [] irBump = 0.0 m = 1.0 # 0.00000000000 spotDays = 0 settlement_date = valuation_date.addDays(spotDays) maturity_date = settlement_date.addMonths(1) depo1 = FinIborDeposit(settlement_date, maturity_date, m * 0.0016, dcType) maturity_date = settlement_date.addMonths(2) depo2 = FinIborDeposit(settlement_date, maturity_date, m * 0.0020, dcType) maturity_date = settlement_date.addMonths(3) depo3 = FinIborDeposit(settlement_date, maturity_date, m * 0.0024, dcType) maturity_date = settlement_date.addMonths(6) depo4 = FinIborDeposit(settlement_date, maturity_date, m * 0.0033, dcType) maturity_date = settlement_date.addMonths(12) depo5 = FinIborDeposit(settlement_date, maturity_date, m * 0.0056, dcType) depos.append(depo1) depos.append(depo2) depos.append(depo3) depos.append(depo4) depos.append(depo5) fras = [] spotDays = 2 settlement_date = valuation_date.addDays(spotDays) swaps = [] dcType = DayCountTypes.THIRTY_E_360_ISDA fixedFreq = FrequencyTypes.SEMI_ANNUAL maturity_date = settlement_date.addMonths(24) swap1 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0044 + irBump, fixedFreq, dcType) swaps.append(swap1) maturity_date = settlement_date.addMonths(36) swap2 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0078 + irBump, fixedFreq, dcType) swaps.append(swap2) maturity_date = settlement_date.addMonths(48) swap3 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0119 + irBump, fixedFreq, dcType) swaps.append(swap3) maturity_date = settlement_date.addMonths(60) swap4 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0158 + irBump, fixedFreq, dcType) swaps.append(swap4) maturity_date = settlement_date.addMonths(72) swap5 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0192 + irBump, fixedFreq, dcType) swaps.append(swap5) maturity_date = settlement_date.addMonths(84) swap6 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0219 + irBump, fixedFreq, dcType) swaps.append(swap6) maturity_date = settlement_date.addMonths(96) swap7 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0242 + irBump, fixedFreq, dcType) swaps.append(swap7) maturity_date = settlement_date.addMonths(108) swap8 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0261 + irBump, fixedFreq, dcType) swaps.append(swap8) maturity_date = settlement_date.addMonths(120) swap9 = FinIborSwap( settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.0276 + irBump, fixedFreq, dcType) swaps.append(swap9) libor_curve = IborSingleCurve(valuation_date, depos, fras, swaps) cdsMarketContracts = [] cdsCoupon = 0.005743 maturity_date = valuation_date.nextCDSDate(6) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) cdsCoupon = 0.007497 maturity_date = valuation_date.nextCDSDate(12) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) cdsCoupon = 0.011132 maturity_date = valuation_date.nextCDSDate(24) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) cdsCoupon = 0.013932 maturity_date = valuation_date.nextCDSDate(36) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) cdsCoupon = 0.015764 maturity_date = valuation_date.nextCDSDate(48) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) cdsCoupon = 0.017366 maturity_date = valuation_date.nextCDSDate(60) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) cdsCoupon = 0.020928 maturity_date = valuation_date.nextCDSDate(84) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) cdsCoupon = 0.022835 maturity_date = valuation_date.nextCDSDate(120) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) recovery_rate = 0.40 issuer_curve = FinCDSCurve(valuation_date, cdsMarketContracts, libor_curve, recovery_rate) return libor_curve, issuer_curve
def test_full_priceCDSwaption(): # This reproduces example on page 38 of Open Gamma note on CDS Option tradeDate = Date(5, 2, 2014) _, issuer_curve = buildFullIssuerCurve(tradeDate) step_in_date = tradeDate.addDays(1) valuation_date = step_in_date expiry_date = Date(20, 3, 2014) maturity_date = Date(20, 6, 2019) cdsRecovery = 0.40 notional = 100.0 long_protection = False cdsCoupon = 0.0 # NOT KNOWN cds_contract = FinCDS(step_in_date, maturity_date, cdsCoupon, notional, long_protection) testCases.banner( "=============================== CDS ===============================") # cds_contract.print(valuation_date) testCases.header("LABEL", "VALUE") spd = cds_contract.parSpread( valuation_date, issuer_curve, cdsRecovery) * 10000.0 testCases.print("PAR SPREAD:", spd) v = cds_contract.value(valuation_date, issuer_curve, cdsRecovery) testCases.print("FULL VALUE", v['full_pv']) testCases.print("CLEAN VALUE", v['clean_pv']) p = cds_contract.clean_price(valuation_date, issuer_curve, cdsRecovery) testCases.print("CLEAN PRICE", p) accrued_days = cds_contract.accrued_days() testCases.print("ACCRUED DAYS", accrued_days) accruedInterest = cds_contract.accruedInterest() testCases.print("ACCRUED COUPON", accruedInterest) prot_pv = cds_contract.protectionLegPV( valuation_date, issuer_curve, cdsRecovery) testCases.print("PROTECTION LEG PV", prot_pv) premPV = cds_contract.premiumLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PREMIUM LEG PV", premPV) fullRPV01, cleanRPV01 = cds_contract.riskyPV01(valuation_date, issuer_curve) testCases.print("FULL RPV01", fullRPV01) testCases.print("CLEAN RPV01", cleanRPV01) # cds_contract.printFlows(issuer_curve) testCases.banner( "=========================== FORWARD CDS ===========================") cds_contract = FinCDS(expiry_date, maturity_date, cdsCoupon, notional, long_protection) # cds_contract.print(valuation_date) spd = cds_contract.parSpread( valuation_date, issuer_curve, cdsRecovery) * 10000.0 testCases.print("PAR SPREAD", spd) v = cds_contract.value(valuation_date, issuer_curve, cdsRecovery) testCases.print("FULL VALUE", v['full_pv']) testCases.print("CLEAN VALUE", v['clean_pv']) prot_pv = cds_contract.protectionLegPV( valuation_date, issuer_curve, cdsRecovery) testCases.print("PROTECTION LEG PV", prot_pv) premPV = cds_contract.premiumLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PREMIUM LEG PV", premPV) fullRPV01, cleanRPV01 = cds_contract.riskyPV01(valuation_date, issuer_curve) testCases.print("FULL RPV01", fullRPV01) testCases.print("CLEAN RPV01", cleanRPV01) # cds_contract.printFlows(issuer_curve) testCases.banner( "========================== CDS OPTIONS ============================") cdsCoupon = 0.01 volatility = 0.3 testCases.print("Expiry Date:", str(expiry_date)) testCases.print("Maturity Date:", str(maturity_date)) testCases.print("CDS Coupon:", cdsCoupon) testCases.header("STRIKE", "FULL VALUE", "IMPLIED VOL") for strike in np.linspace(100, 300, 41): cdsOption = FinCDSOption(expiry_date, maturity_date, strike / 10000.0, notional) v = cdsOption.value(valuation_date, issuer_curve, volatility) vol = cdsOption.impliedVolatility(valuation_date, issuer_curve, v) testCases.print(strike, v, vol)
def test_FinCDSCurve(): curveDate = Date(20, 12, 2018) swaps = [] depos = [] fras = [] fixedDCC = DayCountTypes.ACT_365F fixedFreq = FrequencyTypes.SEMI_ANNUAL fixedCoupon = 0.05 for i in range(1, 11): maturity_date = curveDate.addMonths(12 * i) swap = FinIborSwap(curveDate, maturity_date, FinSwapTypes.PAY, fixedCoupon, fixedFreq, fixedDCC) swaps.append(swap) libor_curve = IborSingleCurve(curveDate, depos, fras, swaps) cds_contracts = [] for i in range(1, 11): maturity_date = curveDate.addMonths(12 * i) cds = FinCDS(curveDate, maturity_date, 0.005 + 0.001 * (i - 1)) cds_contracts.append(cds) issuer_curve = FinCDSCurve(curveDate, cds_contracts, libor_curve, recovery_rate=0.40, useCache=False) testCases.header("T", "Q") n = len(issuer_curve._times) for i in range(0, n): testCases.print(issuer_curve._times[i], issuer_curve._values[i]) testCases.header("CONTRACT", "VALUE") for i in range(1, 11): maturity_date = curveDate.addMonths(12 * i) cds = FinCDS(curveDate, maturity_date, 0.005 + 0.001 * (i - 1)) v = cds.value(curveDate, issuer_curve) testCases.print(i, v) if 1 == 0: x = [0.0, 1.2, 1.6, 1.7, 10.0] qs = issuer_curve.survProb(x) print("===>", qs) x = [0.3, 1.2, 1.6, 1.7, 10.0] xx = np.array(x) qs = issuer_curve.survProb(xx) print("===>", qs) x = [0.3, 1.2, 1.6, 1.7, 10.0] dfs = issuer_curve.df(x) print("===>", dfs) x = [0.3, 1.2, 1.6, 1.7, 10.0] xx = np.array(x) dfs = issuer_curve.df(xx) print("===>", dfs)
def test_full_priceCDSModelCheck(): testCases.print("Example", "MARKIT CHECK 19 Aug 2020") libor_curve, issuer_curve = buildFullIssuerCurve2(0.0, 0.0) # This is the 10 year contract at an off market coupon maturity_date = Date(20, 6, 2025) cdsCoupon = 0.050 notional = ONE_MILLION long_protection = True tradeDate = Date(20, 8, 2020) effective_date = Date(21, 8, 2020) valuation_date = tradeDate cds_contract = FinCDS(effective_date, maturity_date, cdsCoupon, notional, long_protection) cdsRecovery = 0.40 testCases.header("LABEL", "VALUE") spd = cds_contract.parSpread(valuation_date, issuer_curve, cdsRecovery) * 10000.0 testCases.print("PAR_SPREAD", spd) v = cds_contract.value(valuation_date, issuer_curve, cdsRecovery) testCases.print("FULL_VALUE", v['full_pv']) testCases.print("CLEAN_VALUE", v['clean_pv']) p = cds_contract.clean_price(valuation_date, issuer_curve, cdsRecovery) testCases.print("CLEAN_PRICE", p) accrued_days = cds_contract.accrued_days() testCases.print("ACCRUED_DAYS", accrued_days) accruedInterest = cds_contract.accruedInterest() testCases.print("ACCRUED_COUPON", accruedInterest) prot_pv = cds_contract.protectionLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PROTECTION_PV", prot_pv) premPV = cds_contract.premiumLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PREMIUM_PV", premPV) rpv01 = cds_contract.riskyPV01(valuation_date, issuer_curve) testCases.print("FULL_RPV01", rpv01['full_rpv01']) testCases.print("CLEAN_RPV01", rpv01['clean_rpv01']) creditDV01 = cds_contract.creditDV01(valuation_date, issuer_curve, cdsRecovery) testCases.print("CREDIT DV01", creditDV01) interestDV01 = cds_contract.interestDV01(valuation_date, issuer_curve, cdsRecovery) testCases.print("INTEREST DV01", interestDV01) # Consider fast approximation t = (maturity_date - valuation_date) / gDaysInYear z = libor_curve.df(maturity_date) r = -np.log(z) / t mktSpread = 0.01 v_approx = cds_contract.valueFastApprox(valuation_date, r, mktSpread, cdsRecovery) testCases.header("FAST VALUATIONS", "VALUE") testCases.print("FULL APPROX VALUE", v_approx[0]) testCases.print("CLEAN APPROX VALUE", v_approx[1]) testCases.print("APPROX CREDIT DV01", v_approx[2]) testCases.print("APPROX INTEREST DV01", v_approx[3])
def test_full_priceCDSIndexOption(): tradeDate = Date(1, 8, 2007) step_in_date = tradeDate.addDays(1) valuation_date = step_in_date libor_curve = 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() issuer_curves = [] 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 recovery_rate = float(splitRow[5]) cds3Y = FinCDS(step_in_date, maturity3Y, spd3Y) cds5Y = FinCDS(step_in_date, maturity5Y, spd5Y) cds7Y = FinCDS(step_in_date, maturity7Y, spd7Y) cds10Y = FinCDS(step_in_date, maturity10Y, spd10Y) cds_contracts = [cds3Y, cds5Y, cds7Y, cds10Y] issuer_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve, recovery_rate) issuer_curves.append(issuer_curve) ########################################################################## ########################################################################## indexUpfronts = [0.0, 0.0, 0.0, 0.0] indexMaturityDates = [ Date(20, 12, 2009), Date(20, 12, 2011), Date(20, 12, 2013), Date(20, 12, 2016) ] indexRecovery = 0.40 testCases.banner( "======================= CDS INDEX OPTION ==========================") index_coupon = 0.004 volatility = 0.50 expiry_date = Date(1, 2, 2008) maturity_date = Date(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): ####################################################################### cds_contracts = [] for dt in indexMaturityDates: cds = FinCDS(valuation_date, dt, index / 10000.0) cds_contracts.append(cds) index_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve, indexRecovery) if 1 == 1: indexSpreads = [index / 10000.0] * 4 indexPortfolio = FinCDSIndexPortfolio() adjustedIssuerCurves = indexPortfolio.hazardRateAdjustIntrinsic( valuation_date, issuer_curves, indexSpreads, indexUpfronts, indexMaturityDates, indexRecovery, tolerance) else: indexSpread = index / 10000.0 issuer_curve = buildFlatIssuerCurve(tradeDate, libor_curve, indexSpread, indexRecovery) adjustedIssuerCurves = [] for iCredit in range(0, 125): adjustedIssuerCurves.append(issuer_curve) ####################################################################### for strike in np.linspace(20, 60, 20): start = time.time() option = FinCDSIndexOption(expiry_date, maturity_date, index_coupon, strike / 10000.0, notional) v_pay_1, v_rec_1, strikeValue, mu, expH = option.valueAnderson( valuation_date, adjustedIssuerCurves, indexRecovery, volatility) end = time.time() elapsed = end - start end = time.time() v_pay_2, v_rec_2 = option.valueAdjustedBlack( valuation_date, index_curve, indexRecovery, libor_curve, 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_full_priceCDS1(): mktSpread = 0.040 testCases.header("Example", "Markit 9 Aug 2019") libor_curve, issuer_curve = buildFullIssuerCurve1(0.0, 0.0) # This is the 10 year contract at an off market coupon maturity_date = Date(20, 6, 2029) cdsCoupon = 0.0150 notional = ONE_MILLION long_protection = True tradeDate = Date(9, 8, 2019) valuation_date = tradeDate.addDays(1) effective_date = valuation_date cds_contract = FinCDS(effective_date, maturity_date, cdsCoupon, notional, long_protection) cdsRecovery = 0.40 testCases.header("LABEL", "VALUE") spd = cds_contract.parSpread(valuation_date, issuer_curve, cdsRecovery) * 10000.0 testCases.print("PAR_SPREAD", spd) v = cds_contract.value(valuation_date, issuer_curve, cdsRecovery) testCases.print("FULL_VALUE", v['full_pv']) testCases.print("CLEAN_VALUE", v['clean_pv']) p = cds_contract.clean_price(valuation_date, issuer_curve, cdsRecovery) testCases.print("CLEAN_PRICE", p) # MARKIT PRICE IS 168517 accrued_days = cds_contract.accrued_days() testCases.print("ACCRUED_DAYS", accrued_days) accruedInterest = cds_contract.accruedInterest() testCases.print("ACCRUED_COUPON", accruedInterest) prot_pv = cds_contract.protectionLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PROTECTION_PV", prot_pv) premPV = cds_contract.premiumLegPV(valuation_date, issuer_curve, cdsRecovery) testCases.print("PREMIUM_PV", premPV) fullRPV01, cleanRPV01 = cds_contract.riskyPV01(valuation_date, issuer_curve) testCases.print("FULL_RPV01", fullRPV01) testCases.print("CLEAN_RPV01", cleanRPV01) # cds_contract.printFlows(issuer_curve) bump = 1.0 / 10000.0 # 1 bp libor_curve, issuer_curve = buildFullIssuerCurve1(bump, 0) v_bump = cds_contract.value(valuation_date, issuer_curve, cdsRecovery) dv = v_bump['full_pv'] - v['full_pv'] testCases.print("CREDIT_DV01", dv) # Interest Rate Bump libor_curve, issuer_curve = buildFullIssuerCurve1(0, bump) v_bump = cds_contract.value(valuation_date, issuer_curve, cdsRecovery) dv = v_bump['full_pv'] - v['full_pv'] testCases.print("INTEREST_DV01", dv) t = (maturity_date - valuation_date) / gDaysInYear z = libor_curve.df(maturity_date) r = -np.log(z) / t v_approx = cds_contract.valueFastApprox(valuation_date, r, mktSpread, cdsRecovery) testCases.print("FULL APPROX VALUE", v_approx[0]) testCases.print("CLEAN APPROX VALUE", v_approx[1]) testCases.print("APPROX CREDIT DV01", v_approx[2]) testCases.print("APPROX INTEREST DV01", v_approx[3])
def buildFullIssuerCurve1(mktSpreadBump, irBump): # https://www.markit.com/markit.jsp?jsppage=pv.jsp # YIELD CURVE 8-AUG-2019 SNAP AT 1600 tradeDate = Date(9, 8, 2019) valuation_date = tradeDate.addDays(1) m = 1.0 # 0.00000000000 dcType = DayCountTypes.ACT_360 depos = [] depo1 = FinIborDeposit(valuation_date, "1D", m * 0.0220, dcType) depos.append(depo1) spotDays = 2 settlement_date = valuation_date.addDays(spotDays) maturity_date = settlement_date.addMonths(1) depo1 = FinIborDeposit(settlement_date, maturity_date, m * 0.022009, dcType) maturity_date = settlement_date.addMonths(2) depo2 = FinIborDeposit(settlement_date, maturity_date, m * 0.022138, dcType) maturity_date = settlement_date.addMonths(3) depo3 = FinIborDeposit(settlement_date, maturity_date, m * 0.021810, dcType) maturity_date = settlement_date.addMonths(6) depo4 = FinIborDeposit(settlement_date, maturity_date, m * 0.020503, dcType) maturity_date = settlement_date.addMonths(12) depo5 = FinIborDeposit(settlement_date, maturity_date, m * 0.019930, dcType) depos.append(depo1) depos.append(depo2) depos.append(depo3) depos.append(depo4) depos.append(depo5) fras = [] swaps = [] dcType = DayCountTypes.THIRTY_E_360_ISDA fixedFreq = FrequencyTypes.SEMI_ANNUAL maturity_date = settlement_date.addMonths(24) swap1 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.015910 + irBump, fixedFreq, dcType) swaps.append(swap1) maturity_date = settlement_date.addMonths(36) swap2 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.014990 + irBump, fixedFreq, dcType) swaps.append(swap2) maturity_date = settlement_date.addMonths(48) swap3 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.014725 + irBump, fixedFreq, dcType) swaps.append(swap3) maturity_date = settlement_date.addMonths(60) swap4 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.014640 + irBump, fixedFreq, dcType) swaps.append(swap4) maturity_date = settlement_date.addMonths(72) swap5 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.014800 + irBump, fixedFreq, dcType) swaps.append(swap5) maturity_date = settlement_date.addMonths(84) swap6 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.014995 + irBump, fixedFreq, dcType) swaps.append(swap6) maturity_date = settlement_date.addMonths(96) swap7 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.015180 + irBump, fixedFreq, dcType) swaps.append(swap7) maturity_date = settlement_date.addMonths(108) swap8 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.015610 + irBump, fixedFreq, dcType) swaps.append(swap8) maturity_date = settlement_date.addMonths(120) swap9 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.015880 + irBump, fixedFreq, dcType) swaps.append(swap9) maturity_date = settlement_date.addMonths(144) swap10 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY, m * 0.016430 + irBump, fixedFreq, dcType) swaps.append(swap10) libor_curve = IborSingleCurve(valuation_date, depos, fras, swaps) cdsMarketContracts = [] cdsCoupon = 0.04 + mktSpreadBump maturity_date = valuation_date.nextCDSDate(6) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(12) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(24) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(36) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(48) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(60) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(84) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(120) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) maturity_date = valuation_date.nextCDSDate(180) cds = FinCDS(valuation_date, maturity_date, cdsCoupon) cdsMarketContracts.append(cds) recovery_rate = 0.40 issuer_curve = FinCDSCurve(valuation_date, cdsMarketContracts, libor_curve, recovery_rate) return libor_curve, issuer_curve