|
From: jian Xu <jia...@gm...> - 2020-11-23 04:25:06
|
Aha, Thanks for pointing that out, Peter. After I pass the same compounding and bond coupon frequency to the constructor of the ZeroSpreadedTermStructure, the clean price comes back to be the same as the new_clean_prce. >>> ts_spreaded1 = ql.ZeroSpreadedTermStructure(ts_handle, spread_handle1, ql.Compounded, fixed_rate_bond.frequency()) >>> ql.BondFunctions.cleanPrice(fixed_rate_bond, ts_spreaded1, settle_date) 101.00000001031341 As a side note, I think a better practice is to always specify compounding and frequency, no matter constructing the baseline "ts_yield" or the spread curve "ts_spreaded1". I don't understand why there isn't inspectors like compounding()/frequency() for the FlatForward and the ZeroSpreadedTermStructure class. On Sun, Nov 22, 2020 at 12:37 PM Peter Caspers <pca...@gm...> wrote: > > Hi Jian, this might be due to > > - different compounding conventions for the spread in the z-spread > calculation (compounded in your code) vs. the zero-spreaded term > structure (defaults to continuous, you can change it but I am not sure > if this is this possible in Python) > > - different day count conventions for the z-spread (given by day_count > in your code) and for the spread in the zero-spreaded term structure, > which is always the day counter of the underlying rate curve (your > ts_handle) - again you can overwrite this in the zero-spreaded term > structure constructor, but this is unfortunately ignored (a known bug, > or an open to do as we often like to call it) > > Best regards, > Peter > > On Sun, 22 Nov 2020 at 19:00, jian Xu <jia...@gm...> wrote: > > > > Hi, > > I encountered some inconsistency in ZSpread calculation. Basically, I > > calculate the zspread using the BondFunctions.zSpread. But when I add > > this zspread on top of the yield curve, I cannot recover the clean > > price. Following is what I did: > > > > I used the official notebook example at: > > http://gouthamanbalaraman.com/blog/bonds-with-spreads-quantlib-python.html, > > everything the same up to the part which sets the bond_engine. > > > > Then instead of using the engine, I used BondFunctions: > > >>> settle_date = fixed_rate_bond.settlementDate(calc_date) > > >>> ql.BondFunctions.cleanPrice(fixed_rate_bond, ts_yield, settle_date) > > > > This returns the clean price of 114.09294985282332, which translates > > to the same NPV =114.18461651948999 on the official site (by adding > > the accrued interest). So far so good. > > > > Then I ask if the clean price is 101, what's the zspread: > > >>> new_clean_price = 101 > > >>> zspread = ql.BondFunctions.zSpread(fixed_rate_bond, new_clean_price, ts_yield, day_count, ql.Compounded, fixed_rate_bond.frequency(), settle_date) > > print(zspread) > > > > This shows the zspread=0.02592546532075354. > > > > Then I add this zspread on top of the original yield curve to obtain a > > new yield curve. My understanding is that by using this new yield > > curve to price the bond, I should recover the new_clean_price. But it > > does not: > > > > >>> spread1 = ql.SimpleQuote(zspread) > > >>> spread_handle1 = ql.QuoteHandle(spread1) > > >>> ts_spreaded1 = ql.ZeroSpreadedTermStructure(ts_handle, spread_handle1) > > >>> ql.BondFunctions.cleanPrice(fixed_rate_bond, ts_spreaded1, settle_date) > > > > This resulted clean price is 100.91139815763174, which is about 0.0886 > > different from the new_clean_price. I tried to increase the > > "accuracy" parameter in the ql.BondFunctions.zSpread, but doesn't seem > > to help. > > > > Does anyone know why? Did I misunderstood ZSpread? Or did I pass > > wrong parameters in the zSpread function call? Thanks. > > > > Jian > > > > > > _______________________________________________ > > QuantLib-users mailing list > > Qua...@li... > > https://lists.sourceforge.net/lists/listinfo/quantlib-users |