from quantlib.time.api import ( WeekendsOnly, today, Years, Months, Period, Date, Actual365Fixed, Actual360, Quarterly, Following, Unadjusted, Schedule, DateGeneration, ) from quantlib.instruments.api import CreditDefaultSwap, Protection from quantlib.pricingengines.credit.isda_cds_engine import ( IsdaCdsEngine, ForwardsInCouponPeriod, NumericalFix, AccrualBias, ) from quantlib.termstructures.credit.api import ( SpreadCdsHelper, PiecewiseDefaultCurve, FlatHazardRate, ) from quantlib.settings import Settings from serenitas.analytics.yieldcurve import YC, rate_helpers from pyisda.curve import SpreadCurve from pyisda.utils import build_yc from pyisda.legs import ContingentLeg, FeeLeg import datetime import array import math def snac_pv(spread, term_date, fixed_coupon=0.01, recovery=0.4, ts=YC()): settings = Settings() calendar = WeekendsOnly() cds_helper = SpreadCdsHelper( spread, Period(57, Months), 1, calendar, Quarterly, Following, DateGeneration.CDS, Actual360(), recovery, ts, lastperiod=Actual360(True), ) cds_helper.set_isda_engine_parameters( int(NumericalFix.Taylor), int(AccrualBias.HalfDayBias), int(ForwardsInCouponPeriod.Flat), ) pdc = PiecewiseDefaultCurve( "SurvivalProbability", "LogLinear", settings.evaluation_date, [cds_helper], Actual365Fixed(), ) isda_pricer = IsdaCdsEngine( pdc, recovery, ts, False, forwards_in_coupon_period=ForwardsInCouponPeriod.Piecewise, accrual_bias=AccrualBias.HalfDayBias, ) protect_start = settings.evaluation_date + 1 cds_schedule = Schedule( protect_start, term_date, Period(Quarterly), calendar, Following, Unadjusted, DateGeneration.CDS, ) cds_trade = CreditDefaultSwap( Protection.Buyer, 100, fixed_coupon, cds_schedule, Following, Actual360(), protection_start=protect_start, last_period_day_counter=Actual360(True), ) cds_trade.set_pricing_engine(isda_pricer) return cds_trade, cds_helper, isda_pricer def jpmorgan_curves(trade_date, value_date, start_date, end_date, spread, recovery=0.4): yc = build_yc(trade_date, True) step_in_date = trade_date + datetime.timedelta(days=1) spread = array.array("d", [spread]) recovery = array.array("d", [recovery]) sc = SpreadCurve( trade_date, yc, start_date, step_in_date, value_date, [end_date], spread, recovery, True, ) return yc, sc if __name__ == "__main__": breakpoint() settings = Settings() settings.evaluation_date = Date(21, 5, 2009) yield_helpers = rate_helpers() ts = YC(helpers=yield_helpers) tenor = Period(5, Years) trade_date = datetime.date(2009, 5, 21) stepin_date = trade_date + datetime.timedelta(days=1) value_date = datetime.date(2009, 5, 26) term_date = datetime.date(2019, 6, 20) start_date = datetime.date(2009, 3, 20) spread = 0.001 yc, sc = jpmorgan_curves( trade_date, value_date, start_date, term_date, spread, recovery=0.4 ) sc_data = sc.inspect()["data"] hazard_rate = math.log(1 + sc_data[0][1]) contingent_leg = ContingentLeg(start_date, term_date, 10000000) fee_leg = FeeLeg(start_date, term_date, True, 10000000, 0.01) flat_curve = FlatHazardRate(0, WeekendsOnly(), hazard_rate, Actual365Fixed()) cds_schedule = Schedule( Date.from_datetime(trade_date), Date.from_datetime(term_date), Period(Quarterly), WeekendsOnly(), Following, Unadjusted, DateGeneration.CDS, ) cds_trade = CreditDefaultSwap.from_upfront( Protection.Buyer, 10000000, 0.0, 0.01, cds_schedule, Following, Actual360(), protection_start=Date.from_datetime(trade_date) + 1, last_period_day_counter=Actual360(True), ) isda_pricer = IsdaCdsEngine( flat_curve, 0.4, ts, accrual_bias=AccrualBias.HalfDayBias, forwards_in_coupon_period=ForwardsInCouponPeriod.Piecewise, ) # 795915.9787 cds_trade.set_pricing_engine(isda_pricer) cds_trade2 = CreditDefaultSwap( Protection.Buyer, 10000000, spread, cds_schedule, Following, Actual360(), protection_start=Date.from_datetime(trade_date) + 1, last_period_day_counter=Actual360(True), ) # h = cds_trade2.implied_hazard_rate(0., ts) h = 0.00168276528775 flat_curve2 = FlatHazardRate(0, WeekendsOnly(), h, Actual365Fixed()) isda_pricer2 = IsdaCdsEngine(flat_curve2, 0.4, ts) cds_trade.set_pricing_engine(isda_pricer2) print(cds_trade.fair_upfront) # hazard_rate = 0.12649393489974806 # cds_trade.set_pricing_engine(isda_pricer) # cds_trade2 = CreditDefaultSwap.from_upfront(Buyer, 10000000, 0., 0.01, cds_schedule, # Following, Actual360(), # protection_start = Date.from_datetime(trade_date) + 1, # last_period_day_counter = Actual360(True)) # cds_trade3 = CreditDefaultSwap(Buyer, 10000000, 0.05, cds_schedule, # Following, Actual360(), # protection_start = Date.from_datetime(trade_date) + 1, # last_period_day_counter = Actual360(True))