|
From: philippe h. <pha...@ma...> - 2020-07-13 13:56:28
|
Right but say I have a stochastically generated curve whereby the forward rate goes from positive to negative during the life of the floating leg. Using the absolute value of each amount is clearly wrong as the sign could change from one period to the next. Multiplying the sum by swap.Payer or swap.Receiver would multiply a number which is wrong to begin with. Regards Philippe Hatstadt +1-203-252-0408 pha...@ma... https://www.linkedin.com/in/philippe-hatstadt > On Jul 13, 2020, at 9:36 AM, Amine Ifri <ami...@gm...> wrote: > > Hi Philippe, > > The discounting price engine for the swap calculates the amount() of each Coupon using a class method called Cashflows::npvbps(….) that computes the absolute values for cashflows depending on their “type” (Ibor coupons, CPI coupons, etc….) > > Once these are calculated, then they get multiplied by the swap::argument::payer[] flag which is set to -1 or 1 depending on the type payer or receiver. I suspect what you are calling is the amount() method on the coupons. The correct flag of the leg is handled after calculation of the absolute amount. > > Hope it helps. > Amine > > >> On 13 Jul 2020, at 11:11, philippe hatstadt <pha...@ma...> wrote: >> >> It’s the underlying swap of a swaption. US curve. Swap starts in 2y and ends in 12y. Semi annual fixed act/act versus USDLibor 3M floating a/360. >> The Hull White path is harder to share other than by providing daily discount factors. >> Defining dfs and dfe as the discount factors at 2y and 12y, I was able to get the correct fairRate manually by stating that floating leg NPV is equal to dfs - dfe. swap.fixedLegNPV() is correct but not swap.flioatingLeg.NPV(). >> I used today as evaluation date. >> As you can see below, the floating leg cash flow amounts never change in sign even when the forward rate does. I realize my graph is the instantaneous forward, but the 3M can easily be calculated from the discount factors. >> >> Regards >> >> Philippe Hatstadt >> +1-203-252-0408 >> pha...@ma... >> https://www.linkedin.com/in/philippe-hatstadt >> >> >>> On Jul 13, 2020, at 5:57 AM, Amine Ifri <ami...@gm...> wrote: >>> >>> I use the C++ library and never had an issue with swap.fairRate(). It gives me positive as well as negative values depending on the term structures. >>> >>> As far as checking the CPP code, it looks correct to me. Do you mind sharing the swap details you are trying to price/simulate? >>> >>> Amine >>> >>>> On 12 Jul 2020, at 03:02, Philippe Hatstadt <phi...@ex...> wrote: >>>> >>>> I'm using a Hull-White model to generate forward paths of the short rate, from which I then build a discounting curve, from which I compute forward swap values towards Monte-carlo integration of certain path dependent swap rate linked derivatives. Here, I am looking at a 2y into 10y swaption, and for each path, I want to calculate the forward swap rate and the swap NPV. >>>> My problem is that I have a curve that has negative rates on a certain path, the 2y into 10y forward swap.fairRate() function returns like 94bp. Since all rates are negative, it's pretty clear that fairRate() should be negative, and if I use the curve's discount factors and use the good old approximation for the swap rate with the formula C/2 * Sum_i(FixedLegDiscountFactor(i))/(1-DiscountFactor(TMat)) then I get the correct -250bp forward swap rate (where i=1 to 20 corresponding to 20 forward semi-annual fixed payments). >>>> So I am wondering if the swap cash flows do not work with negative rates or else, but as it stands right now, the swap.fairRate() function doesn't work at all. I also checked that by solving for the fixed rate that would make the swap net cash-flows to be equal to zero, then I get the value returned by swap.fairRate(). This would further indicate that the latter function is correct, but that the cash flows are not. lastly, whether I select a path with positive or negative forward rates, the cf.amount() is always positive. >>>> This is the code I use to generate the cash-flows: >>>> def swap_cash_flows(swap: ql.Swap, >>>> crvh, >>>> ): >>>> output_list = [] >>>> for i, cf in enumerate(swap.leg(0)): >>>> dt = cf.date() >>>> dfact = crvh.discount(dt) >>>> output_list.append(['leg0', cf.date(), dfact, cf.amount()]) >>>> for i, cf in enumerate(swap.leg(1)): >>>> dt = cf.date() >>>> dfact = crvh.discount(dt) >>>> output_list.append(['leg1', cf.date(), dfact, cf.amount()]) >>>> df1 = pd.DataFrame(columns=['leg', 'cf_date', 'disc_fact', 'cf_amount'], data=output_list) >>>> return df1 >>>> The short-rate path corresponding to the curve handle crvh is as follows: >>>> <image.png> >>>> and lastly, this is the table of cash flows, dates and discount factors: >>>> leg cf_date disc_fact cf_amount >>>> leg0 2023-01-11 1.031727084 0.004717496 >>>> leg0 2023-07-11 1.044326706 0.004640581 >>>> leg0 2024-01-11 1.056475309 0.004717496 >>>> leg0 2024-07-11 1.067323978 0.004666219 >>>> leg0 2025-01-13 1.080208917 0.004768773 >>>> leg0 2025-07-11 1.095773345 0.004589303 >>>> leg0 2026-01-12 1.107358267 0.004743135 >>>> leg0 2026-07-13 1.119706713 0.004666219 >>>> leg0 2027-01-11 1.134937064 0.004666219 >>>> leg0 2027-07-12 1.148588556 0.004666219 >>>> leg0 2028-01-11 1.164662739 0.004691858 >>>> leg0 2028-07-11 1.184811281 0.004666219 >>>> leg0 2029-01-11 1.202933688 0.004717496 >>>> leg0 2029-07-11 1.22143445 0.004640581 >>>> leg0 2030-01-11 1.244698418 0.004717496 >>>> leg0 2030-07-11 1.268437607 0.004640581 >>>> leg0 2031-01-13 1.289269217 0.004768773 >>>> leg0 2031-07-11 1.310335034 0.004589303 >>>> leg0 2032-01-12 1.330460609 0.004743135 >>>> leg0 2032-07-12 1.351119197 0.004666219 >>>> leg1 2022-10-11 1.025077227 0.000595151 >>>> leg1 2023-01-11 1.031727084 0.000595151 >>>> leg1 2023-04-11 1.037740592 0.000582209 >>>> leg1 2023-07-11 1.044326706 0.00058868 >>>> leg1 2023-10-11 1.050712784 0.001151809 >>>> leg1 2024-01-11 1.056475309 0.001190658 >>>> leg1 2024-04-11 1.062040699 0.001177708 >>>> leg1 2024-07-11 1.067323978 0.001177708 >>>> leg1 2024-10-11 1.073341181 0.001190658 >>>> leg1 2025-01-13 1.080208917 0.001216557 >>>> leg1 2025-04-11 1.087963402 0.00113886 >>>> leg1 2025-07-11 1.095773345 0.001322081 >>>> leg1 2025-10-14 1.102080743 0.002477114 >>>> leg1 2026-01-12 1.107358267 0.002346587 >>>> leg1 2026-04-13 1.112978456 0.002372691 >>>> leg1 2026-07-13 1.119706713 0.002372691 >>>> leg1 2026-10-13 1.127732208 0.002398796 >>>> leg1 2027-01-11 1.134937064 0.002346587 >>>> leg1 2027-04-12 1.141923849 0.002372691 >>>> leg1 2027-07-12 1.148588556 0.002390753 >>>> leg1 2027-10-12 1.155929127 0.002537285 >>>> leg1 2028-01-11 1.164662739 0.002509671 >>>> leg1 2028-04-11 1.174741361 0.002509671 >>>> leg1 2028-07-11 1.184811281 0.002509671 >>>> leg1 2028-10-11 1.194083437 0.002537285 >>>> leg1 2029-01-11 1.202933688 0.002537285 >>>> leg1 2029-04-11 1.211815927 0.002482058 >>>> leg1 2029-07-11 1.22143445 0.002509671 >>>> leg1 2029-10-11 1.232822712 0.002537285 >>>> leg1 2030-01-11 1.244698418 0.002537285 >>>> leg1 2030-04-11 1.256926582 0.002482058 >>>> leg1 2030-07-11 1.268437607 0.003472659 >>>> leg1 2030-10-11 1.278474854 0.004092082 >>>> leg1 2031-01-13 1.289269217 0.004181226 >>>> leg1 2031-04-11 1.299839855 0.003914165 >>>> leg1 2031-07-11 1.310335034 0.004047153 >>>> leg1 2031-10-14 1.320633529 0.004225801 >>>> leg1 2032-01-12 1.330460609 0.004002946 >>>> leg1 2032-04-12 1.340898895 0.004047513 >>>> leg1 2032-07-12 1.351119197 0.004047513 >>>> Regards >>>> >>>> Philippe >>>> >>>> >>>> >>>> Brokerage services offered through Exos Securities LLC, member of SIPC / FINRA. For important disclosures, click here. >>>> _______________________________________________ >>>> 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 > |