|
From: Aleksis A. R. <ale...@go...> - 2021-01-19 08:29:45
|
Hi Peter. If I don't recompute and recalibrate the basket after each bump in the swaption vol cube, then I see no sensitivity impact at all when recomputing the bumped NPVs (so the bump risk returns a zero grid).
I have resorted to using 16 points/3.0 std devs in the integration scheme - this has had made the computation bearable without too much loss of accuracy.
Thanks, Aleksis
> On 18 Jan 2021, at 16:57, Peter Caspers <pca...@gm...> wrote:
>
> Hi Aleksis,
>
> computing the calibration basket via 'MaturityStrikeByDeltaGamma' is
> quite time consuming, so I'd try to compute the basket only once
> (under the base scenario) and reuse it for each sensitivity bump
> scenario.
>
> Thanks
> Peter
>
> On Sun, 17 Jan 2021 at 13:52, Aleksis Ali Raza via QuantLib-users
> <qua...@li...> wrote:
>>
>> Hi, a question on optimizing calculation time: the code I’ve written for bermudan swaption valuation in python (see below) takes forever when I run risks using source bumping (bucketed ATM and skew swaption vega are the really killers). I assume it’s the recalibration step I have added for the NPV attribute that’s the issue but I can’t figure a way around that. Any optimization tips would be appreciated (eg. different parameters for a less time-consuming integration scheme??).
>>
>> Thanks, Aleksis
>>
>>
>> class bermudanswaption():
>> 648
>> 649 def __init__(self, calendar,settlement, used_model, swap, ratecurves, index, swvolcube_clean, swapbase,
>> 650 mean_reversion,position,NC_periods):
>> 651
>> 652 discount_curve = ratecurves.loc['discountcurve', 'ratecurves']
>> 653 self.swvolcube = swvolcube_clean
>> 654 self.swapbase = swapbase
>> 655 self.used_model = used_model
>> 656 self.discount_curve = discount_curve
>> 657 self.position=position
>> 658
>> 659 fixed_schedule=swap.fixedSchedule()
>> 660 exerciseDates = [calendar.advance(i, -ql.Period('2D')) for i in fixed_schedule][1+NC_periods:-1]
>> 661 exercise = ql.BermudanExercise(exerciseDates)
>> 662 stepDates = exerciseDates
>> 663 self.exerciseDates=exerciseDates
>> 664 sigmas = [ql.QuoteHandle(ql.SimpleQuote(0.01))]*(1+len(exerciseDates))
>> 665 self.used_model = used_model
>> 666
>> 667 if settlement == 'physical':
>> 668 type = 0
>> 669 method = 1
>> 670 else:
>> 671 type = 1
>> 672 method = 2
>> 673
>> 674 self.nsswaption = ql.NonstandardSwaption(swap, exercise, type, method)
>> 675 gsr = ql.Gsr(ratecurves.loc[index, 'ratecurves'],
>> 676 stepDates, sigmas, [ql.QuoteHandle(ql.SimpleQuote(mean_reversion))])
>> 677 engine = ql.Gaussian1dNonstandardSwaptionEngine(gsr, 64, 7.0, True, False,
>> 678 ql.QuoteHandle(ql.SimpleQuote(0)),
>> 679 discount_curve, 2)
>> 680 self.engine = ql.Gaussian1dSwaptionEngine(gsr, 64, 7.0, True, False, discount_curve)
>> 681 self.nsswaption.setPricingEngine(engine)
>> 682 self.model = gsr
>> 683 def NPV(self):
>> 684 engine = ql.Gaussian1dSwaptionEngine(self.model, 64, 7.0, True, False, self.discount_curve)
>> 685 basket = self.nsswaption.calibrationBasket(self.swapbase, self.swvolcube, 'MaturityStrikeByDeltaGamma')
>> 686 for basket_i in basket:
>> 687 ql.as_black_helper(basket_i).setPricingEngine(engine)
>> 688 method = ql.LevenbergMarquardt()
>> 689 ec = ql.EndCriteria(1000, 10, 1e-8, 1e-8, 1e-8)
>> 690 self.model.calibrateVolatilitiesIterative(basket, method, ec)
>> 691 npv = self.nsswaption.NPV()*self.position
>>
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li...
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
|