|
From: Philippe H. <phi...@ex...> - 2021-04-03 03:12:25
|
I was able to build a Jupyter Notebook that generates one factor Hull-White
paths. I checked that the libor setting does change on each path and it
does.
I build a swaption (swaption object below) using the standard method from
the Cookbook, as a 1y maturity into a 3y swap based on US 30/360 and 3m
USDLibor index. I use sigma and mean rev both equal to 0.10, and a flat
forward rate at 5%.
The closed-form Jamshidian pricing comes out at 0.91mm on notional of 10mm.
My problem is that the MC value is too high by about 25%, at 1.2mm. I price
the swaption with the code below, with 10,000 paths and 10 day timestep.
I checked manually that for all paths, swap.NPV() is correct, which returns
the PV as seen as the trade date of a forward starting swap on each
path-dependent curve. I was wondering if I am supposed to apply some
additional numeraire adjustment? Since swap.NPV() computes the NPV of the
swap with full path-wise discounting and forecasting curve, I consider that
the Annuity Measure (At) (which makes the forward swap rate a martingale
under the At measure), is embedded in the swap.NPV() and therefore I do not
need to do anything, or do I?
MC Python Code for MC Swaption
----------------------------------------------------------------------------------------------------------
sum_pv = 0
ql.Settings.instance().evaluationDate = trade_date
swap = swaption.underlyingSwap()
exercise_date = swaption.exercise().date(0)
for i in range(num_paths):
curve = path_discount_curve(i)
forecastHandle.linkTo(curve)
engine = ql.DiscountingSwapEngine(forecastHandle)
swap.setPricingEngine(engine)
swap_npv = swap.NPV()
sum_pv += max(0, swap_npv)
return sum_pv / num_paths
Philippe Hatstadt
On Fri, Apr 2, 2021 at 12:03 PM Luigi Ballabio <lui...@gm...>
wrote:
> Hello,
> I would have guessed that passing the forecastHandle to the index (as
> you did) and relinking it would change the fixings as you expect. I
> understand your code is probably proprietary, but is there any chance you
> can post a simplified or abridged version we can run to reproduce the
> issue? If not, try returning the index as well from the function that
> builds the swaption, so after relinking the curve you can check if its
> fixings change or not, or if the curve it contains is actually the one you
> linked.
>
> Hope this helps,
> Luigi
>
>
> On Fri, Apr 2, 2021 at 1:05 PM Philippe Hatstadt <
> phi...@ex...> wrote:
>
>> Thank you. I’m not sure about the exact steps to clone the libor index? I
>> assume I would create an index inside the MC loop and link its curve to my
>> stochastic curve, but how do I “assign” such index to a swap that already
>> exists?
>>
>> Regards
>>
>> Philippe Hatstadt
>> +1-203-252-0408
>> https://www.linkedin.com/in/philippe-hatstadt
>>
>>
>> On Apr 2, 2021, at 3:23 AM, Amine Ifri <ami...@gm...> wrote:
>>
>> Hi Philippe,
>>
>> I believe your forecastHandle variable - which is set to the MC curve
>> generated for scénario i - is actually used for discounting only.
>> discountingSwapEngine only affects the discounting and not the curves upon
>> which the floating index is dependent.
>>
>> You need to “clone” the libor 3m index for your underlying swap and
>> relink its curve to a MC curve as well.
>>
>> Amine Ifri
>>
>> On 2 Apr 2021, at 04:11, Philippe Hatstadt <
>> phi...@ex...> wrote:
>>
>>
>> I have built a Hull-White sequence via standard method, by following
>> precisely the method in the QuantLib Cookbook, with sigma = 10% and
>> mean_rev = 10%.
>> My goal is to ultimately build an OAS model for some Agency CMOs, for
>> which I am building a Monte-carlo engine.
>> I also built a Jamshidian engine to compute a closed-form value of a
>> european swaption as a test, to make sure that my MC valuation converges to
>> the theoretical value.
>> The convergence doesn't work, and I think it has to do with the
>> floating index of the swaption, so let me explain.
>>
>> I first build a curve name forecastHandle of type
>> ql.RelinkableYieldTermStructureHandle
>> I then build a swaption object via my own build_swaption() function,
>> along the lines of the swaption helpers from the Cookbook approach, which
>> returns a ql.Swaption() object. The curve handle is passed to the
>> build_swaption() call along with tenor, maturity and strike.
>> I build the floating index as follows inside the function:
>> libor_3m = ql.USDLibor(ql.Period('3M'), forecastHandle)
>>
>> Now switching to the MC calculation. I loop on all the sequences of
>> short-term rates generated by my HW sequence. I verified that the expected
>> value and the variance of the short-rate are the same as in the Cookbook.
>> Lastly, in order to calculate the value of the swaption via MC
>> integration, I do the following, which takes place inside a function called
>> swaption_MC(forecastHandle, my_swaption). Importantly, forecastHandle is
>> the same handle that was used to build the swaption, including its libor_3m
>> index.
>>
>> for i in range(num_paths):
>> curve = hw_discount_curve(i)
>> forecastHandle.linkTo(curve)
>> engine = ql.DiscountingSwapEngine(forecastHandle)
>>
>> swap = my_swaption.underlyingSwap()
>>
>> swap.setPricingEngine(engine)
>> swap_npv = swap.NPV()
>> sum_pv += max(0, swap_npv)
>> return sum_pv / num_paths
>>
>> I was therefore hoping that by linking the forecastHandle to each
>> path-wise stochastic curve, the libor 3m index would also be path
>> dependent. but somehow, that doesn't appear to be the case, as the floating
>> rates for each reset do not change with each stochastic curve. So I am
>> wondering what I am doing wrong?
>>
>> Help appreciated.
>>
>> Philippe Hatstadt
>>
>>
>>
>> Broker-Dealer services offered through Exos Securities LLC, member of
>> SIPC <http://www.sipc.org/> / FINRA <http://www.finra.org/> / BrokerCheck
>> <https://brokercheck.finra.org/>/ 2021 Exos, inc. For important
>> disclosures, click here
>> <https://www.exosfinancial.com/general-disclosures>.
>>
>>
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li...
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>>
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li...
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>>
>>
>>
>>
>> Broker-Dealer services offered through Exos Securities LLC, member of
>> SIPC <http://www.sipc.org/> / FINRA <http://www.finra.org/> / BrokerCheck
>> <https://brokercheck.finra.org/>/ 2021 Exos, inc. For important
>> disclosures, click here
>> <https://www.exosfinancial.com/general-disclosures>.
>>
>>
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li...
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>>
>
--
Broker-Dealer services offered through Exos Securities LLC, member
of SIPC <http://www.sipc.org/> / FINRA <http://www.finra.org/> /
BrokerCheck <https://brokercheck.finra.org/>/ 2021 Exos, inc. For
important disclosures, click here
<https://www.exosfinancial.com/general-disclosures>.
|