|
From: Giuseppe T. <tr...@gm...> - 2023-08-17 16:16:28
|
Good evening everyone,
I am working with QuantLib python (version 1.31 from pypi). I'm trying to
instantiate *MarkovFunctional to be calibrated on a single expiry / smile*
and I noticed the following RuntimeError:
RuntimeError: year 2200 out of bounds. It must be in [1901,2199]
The error is raised in the following case:
- The SwapIndex passed to MarkovFunctional has a certain fixed leg tenor
(e.g., 1y)
- The swaptionTenors (that is, the smile to be calibrated to) is greater
than that of the fixed leg tenor of the SwapIndex (from the example above,
> 1y).
Notice that *this happens only for SwapIndex with a fixed leg tenor greater
or equal than 1y*: if I create a SwapIndex with fixed leg tenor smaller
than 1y, the MarkovFunctional object gets instantiated correctly with
whatever smile I choose.
*Another weird thing*: if I use a standard EuriborSwapIsdaFixA (that has a
fixed leg tenor of 1y), I can also correctly instantiate the
MarkovFunctional object with whatever smile I choose.
Is this behaviour expected? Please, find below a minimum replication code.
Thanks in advance for your time and availability.
ivol = 0.25
>
> ivol_quote = ql.SimpleQuote(ivol)
>
> ln_shift = 0.02
>
>
>> forward_rate = 0.02
>
> forward_rate_quote = ql.SimpleQuote(forward_rate)
>
>
>> calendar = ql.UnitedStates(ql.UnitedStates.SOFR)
>
>
>> oswp_blackvols = ql.ConstantSwaptionVolatility(2, calendar, ql.Following,
>> ql.QuoteHandle(ivol_quote), ql.Actual365Fixed(), ql.ShiftedLognormal,
>> ln_shift)
>
> forward_curve = ql.FlatForward(2, calendar,
>> ql.QuoteHandle(forward_rate_quote), ql.Actual360())
>
>
>> #swap_index = ql.EuriborSwapIsdaFixA(
>
> # ql.Period("10y"),
>
> # ql.YieldTermStructureHandle(forward_curve),
>
> # ql.YieldTermStructureHandle(forward_curve)
>
> #)
>
>
>>
>> floating_leg_tenor = ql.Period("6m")
>
> fixed_leg_tenor = ql.Period("1y")
>
> ibor_index = ql.Libor("DummyIborIndex", floating_leg_tenor, 2,
>> ql.USDCurrency(), calendar, ql.Actual360(),
>> ql.YieldTermStructureHandle(forward_curve))
>
> swap_index = ql.SwapIndex("DummySwapIndex", ql.Period("10y"), 2,
>> ql.USDCurrency(), calendar, fixed_leg_tenor, ql.ModifiedFollowing,
>> ql.Actual360(), ibor_index)
>
>
>> mean_reversion = 0.05
>
>
>> exercise_dates = [ql.Date(30, 5, 2025)]
>
> swaption_dates = [ql.Date(30, 5, 2025)]
>
>
>>
>> ## smile_tenors > then fixed_leg_tenor => ERROR
>
> smile_tenors = [ql.Period("5y")]
>
>
>> ## smile_tenors <= fixed_leg_tenor => NO ERROR
>
> # smile_tenors = [ql.Period("1y")]
>
>
>> mm = ql.MarkovFunctional(
>
> ql.YieldTermStructureHandle(forward_curve),
>
> mean_reversion,
>
> exercise_dates,
>
> [0.01, 0.01],
>
> ql.SwaptionVolatilityStructureHandle(oswp_blackvols),
>
> swaption_dates,
>
> smile_tenors,
>
> swap_index
>
> )
>
>
--
*Giuseppe Trapani*
|