|
From: Ben W. <ben...@ma...> - 2023-04-06 03:46:58
|
Hi 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}")
|