|
From: Peter C. <pca...@gm...> - 2021-01-19 08:37:59
|
HI Aleksis, what I meant was to keep the basket (i.e. strike,
maturity) constant, but still recalibrate the model under each
scenario.
Thanks, Peter
On Tue, 19 Jan 2021 at 09:29, Aleksis Ali Raza
<ale...@go...> wrote:
>
> 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
>
|