|
From: Ben W. <ben...@ma...> - 2023-04-06 02:12:04
|
Also forgot to say. There may be an issue with the IsdaCdsEngine – I saw some error messages regarding the daycount basis of the discount curve. I think the code has not been updated to allow RFR discounting – can you pls confirm. I would imagine that the simplest thing would be to remove the daycount error checking of curve.
From: Ben Watson <ben...@ma...>
Sent: Thursday, April 6, 2023 11:38 AM
To: 'QuantLib Users' <qua...@li...>
Cc: 'Luigi Ballabio' <lui...@gm...>
Subject: RE: [Quantlib-users] CDS quoted spread v Running/par spread calculator
Sorry to hassle on this – UpfrontCdsHelper is not working. I do need to decide if I need to go another path to convert the upfront CDS to the running spread.
On Tue, 4 Apr 2023, 11:57 Ben Watson, <ben...@ma... <mailto:ben...@ma...> > wrote:
Thank you Luigi,
Thank you for this – looks promising, but not a lot doco on UpfrontCdsHelper to work with. But I have put together a function to test this out. The code also print the all the types of the inputs to the UpfrontCdsHelper to make sure I am passing the correct types.
I got ‘kind of’ close to get it working, but….
If I leave the model (being the MidpointEngine) out of the UpfrontCdsHelper caller function, it throws no error, except that I get the following error when calling impliedQuote
return _QuantLib.DefaultProbabilityHelper_impliedQuote(self)
RuntimeError: Boost assertion failed: px != 0
If I include the MidpointEngine I get the following error
TypeError: Wrong number or type of arguments for overloaded function 'new_UpfrontCdsHelper'.
Possible C/C++ prototypes are:….
…
…
UpfrontCdsHelper::UpfrontCdsHelper(Rate,Rate,Period const &,Integer,Calendar const &,Frequency,BusinessDayConvention,DateGeneration::Rule,DayCounter const &,Real,Handle< YieldTermStructure > const &,Natural,bool,bool,Date const &,DayCounter const &,bool,CreditDefaultSwap::PricingModel)
….
….
The type of the is …. model <QuantLib.QuantLib.MidPointCdsEngine; proxy of <Swig Object of type 'ext::shared_ptr< MidPointCdsEngine > *' at 0x000001150752E4E0> > <class 'QuantLib.QuantLib.MidPointCdsEngine'>
Not sure if there is something that I am doing wrong or there is a bug…
Code below….
import QuantLib as ql
def convert_spreads( upfront, running_spread, recovery_rate, notional, maturity_date, today=None, coupon_frequency=4, day_count=ql.Thirty360(), calendar=ql.TARGET(),):
flat_ts = ql.FlatForward(today, 0.0, day_count, ql.Compounded, ql.Annual)
yield_curve_handle = ql.YieldTermStructureHandle(flat_ts)
upfront_quote = ql.QuoteHandle(ql.SimpleQuote(upfront))
running_spread_quote =running_spread# ql.QuoteHandle(ql.SimpleQuote(running_spread))
hazard_rate_structure = upfront_quote
default_probability_curve = ql.FlatHazardRate(0, calendar, hazard_rate_structure, day_count)
MidpointEngine = ql.MidPointCdsEngine( ql.DefaultProbabilityTermStructureHandle(default_probability_curve),recovery_rate,yield_curve_handle, )
settlementDays=2
tenor=ql.Period(5,ql.Years)
frequency= ql.Quarterly
paymentConvention=ql.Following
rule=ql.DateGeneration.TwentiethIMM
dayCounter=ql.Actual365Fixed()
upfrontSettlementDays=3
settlesAccrual =True
paysAtDefaultTime=True
startDate=today
lastPeriodDayCounter=ql.Actual365Fixed()
rebatesAccrual=True
model=MidpointEngine
print('=============================================================================================================================')
print('upfront_quote',upfront_quote,type(upfront_quote)) # const Handle< Quote > & upfront,
print('upfront',upfront,type(upfront)) # Rate runningSpread
print('running_spread_quote',running_spread_quote,type(running_spread_quote)) # Rate runningSpread,
print('tenor',tenor,type(tenor)) # const Period & tenor,
print('settlementDays',settlementDays,type(settlementDays)) # Integer settlementDays,
print('calendar',calendar,type(calendar)) # const Calendar & calendar,
print('frequency',frequency,type(frequency)) # Frequency frequency,
print('paymentConvention',paymentConvention,type(paymentConvention)) # BusinessDayConvention paymentConvention,
print('rule',rule,type(rule)) # DateGeneration::Rule rule,
print('dayCounter',dayCounter,type(dayCounter)) # const DayCounter & dayCounter,
print('recovery_rate',recovery_rate,type(recovery_rate)) # Real recoveryRate,
print('yield_curve_handle',yield_curve_handle,type(yield_curve_handle)) # const Handle< YieldTermStructure > & discountCurve,
print('upfrontSettlementDays',upfrontSettlementDays,type(upfrontSettlementDays)) # Natural upfrontSettlementDays = 3,
print('settlesAccrual',settlesAccrual,type(settlesAccrual)) # bool settlesAccrual = true,
print('paysAtDefaultTime',paysAtDefaultTime,type(paysAtDefaultTime)) # bool paysAtDefaultTime = true,
print('startDate',startDate,type(startDate)) # const Date & startDate = Date(),
print('lastPeriodDayCounter',lastPeriodDayCounter,type(lastPeriodDayCounter)) # const DayCounter & lastPeriodDayCounter = DayCounter(),
print('rebatesAccrual',rebatesAccrual,type(rebatesAccrual)) # bool rebatesAccrual = true,
print('model',model,type(model)) # CreditDefaultSwap::PricingModel model = CreditDefaultSwap::Midpoint
print('=============================================================================================================================')
helper = ql.UpfrontCdsHelper(
upfront, # Rate runningSpread / const Handle< Quote > & upfront,
running_spread_quote, # Rate runningSpread,
tenor, # const Period & tenor,
settlementDays, # Integer settlementDays,
calendar, # const Calendar & calendar,
frequency, # Frequency frequency,
paymentConvention, # BusinessDayConvention paymentConvention,
rule, # DateGeneration::Rule rule,
dayCounter, # const DayCounter & dayCounter,
recovery_rate, # Real recoveryRate,
yield_curve_handle, # const Handle< YieldTermStructure > & discountCurve,
upfrontSettlementDays, # Natural upfrontSettlementDays = 3,
settlesAccrual, # bool settlesAccrual = true,
paysAtDefaultTime, # bool paysAtDefaultTime = true,
startDate, # const Date & startDate = Date(),
lastPeriodDayCounter, # const DayCounter & lastPeriodDayCounter = DayCounter(),
rebatesAccrual, # bool rebatesAccrual = true,
# model, # CreditDefaultSwap::PricingModel model = CreditDefaultSwap::Midpoint
)
fair_running_spread = helper.impliedQuote()
return fair_running_spread
if __name__ == "__main__":
upfront = 0.01
running_spread = 0.012
recovery_rate = 0.4
notional = 1e7
maturity_date = ql.Date(20,12,2028)
today = ql.Date(3,4,2023)
ql.Settings.instance().setEvaluationDate(today)
fair_upfront, fair_running_spread = convert_spreads(upfront, running_spread, recovery_rate, notional, maturity_date, today )
print(f"Fair Running Spread: {fair_running_spread:.4f}")
From: Luigi Ballabio <lui...@gm... <mailto:lui...@gm...> >
Sent: Monday, April 3, 2023 6:04 PM
To: Ben Watson <ben...@ma... <mailto:ben...@ma...> >
Cc: QuantLib Users <qua...@li... <mailto:qua...@li...> >
Subject: Re: CDS quoted spread v Running/par spread calculator
Hello Ben,
you can use the UpfrontCdsHelper class instead. It allows you to specify both the spread and the quoted upfront.
Best,
Luigi
On Mon, Apr 3, 2023, 06:44 Ben Watson <ben...@ma... <mailto:ben...@ma...> > wrote:
Just trying to get a bit of guidance on this.
The documentation talks about running spread – which would be the case when coupon=spread. This is not quoted in the market as they quote 100 or 500 coupon.
ql.SpreadCdsHelper( runningSpread, tenor, settlementDays, calendar, frequency, paymentConvention, rule, dayCounter, recoveryRate, yts)
Example in Git hub (https://github.com/lballabio/QuantLib-SWIG/blob/master/Python/examples/cds.py) talks about quoted spread which would in the market come to mean a fixed coupon. The CDS helper however does not have a coupon.
quoted_spreads = [0.0150, 0.0150, 0.0150, 0.0150]
tenors = [ql.Period(3, ql.Months), ql.Period(6, ql.Months), ql.Period(1, ql.Years), ql.Period(2, ql.Years)]
maturities = [calendar.adjust(todaysDate + x, ql.Following) for x in tenors]
instruments = [ ql.SpreadCdsHelper( ql.QuoteHandle(ql.SimpleQuote(s)), tenor, 0, calendar, ql.Quarterly, ql.Following, l.DateGeneration.TwentiethIMM, ql.Actual365Fixed(), recovery_rate, risk_free_rate, )
So not so clear, but it looks like it is running spread
In light of this is there any function that converts the market quote (with 100 or 500 coupon) to the running spread that I can use to bootstrap a CDS curve?
Regards
Ben
From: Ben Watson <ben...@ma... <mailto:ben...@ma...> >
Sent: Thursday, March 30, 2023 10:54 AM
To: 'QuantLib Users' <qua...@li... <mailto:qua...@li...> >; 'Luigi Ballabio' <lui...@gm... <mailto:lui...@gm...> >
Subject: CDS quoted spread v Running/par spread calculator
Hi,
Noticed that the CDS curve builder uses the running spread to boot strap the curve. However the quotes I am working with is basis 100 or 500 coupon with an up front. Does Quantlib have a spread converter to change the quoted spreads to the running spreads?
Ben
_______________________________________________
QuantLib-users mailing list
Qua...@li... <mailto:Qua...@li...>
https://lists.sourceforge.net/lists/listinfo/quantlib-users
|