|
From: Luigi B. <lui...@gm...> - 2023-04-06 10:49:24
|
The model should be `ql.CreditDefaultSwap.Midpoint`. It's an enumeration.
However, it's the way you're trying to use the helper that doesn't work.
After you create the helper, it's not connected to any probability curve
(hence the "px != 0" error); it should be used to build one. So once you
have your set of helpers, you should create a PiecewiseFlatHazardRate
instance. Once you have a bootstrapped curve, you could ask
helper.impliedQuote() but it will return the upfront (because that's the
quote for the helper) and it will simply match your input. If you want a
corresponding spread, you can create a CreditDefaultSwap, pass the default
probability curve to its engine and ask it for its fair spread.
Hope this helps,
Luigi
On Thu, Apr 6, 2023 at 5:40 AM Ben Watson <ben...@ma...>
wrote:
> 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}")
>
>
>
>
>
|