|
From: jian Xu <jia...@gm...> - 2021-08-13 18:07:45
|
Wow, thank you very much, Luigi, Matthias, and Conrad. This is very informative. I have never thought about providing schedule in the day_count constructor, and never thought about the additivity of year fraction. Thanks a lot! On Fri, Aug 13, 2021 at 12:07 PM <mat...@gm...> wrote: > > Hi Luigi, > > > > Indeed, it helps – interesting “edge case”. > > > > Thank you, > > > > Matthias > > > > From: Luigi Ballabio <lui...@gm...> > Sent: Friday, 13 August, 2021 19:03 > To: mat...@gm... > Cc: jian Xu <jia...@gm...>; QuantLib users <qua...@li...> > Subject: Re: [Quantlib-users] Bond dirty price different from discounted cashflow? > > > > Hi Matthias, > > unfortunately the 30/360 day counter is not additive. For instance, in the example in this thread the settlement date is 2021/10/05, the first coupon pays on 2021/12/31, and the second coupon pays on 2022/06/30. When calculating the discount factor for the second coupon, the manual approach calculates the time between settlement and payment date as > > > > day_count.yearFraction(ql.Date(5,10,2021), ql.Date(30,6,2022)) > > > > which gives T = 0.73611111; instead, the dirtyPrice method calculates it, as it iterates over the coupons, as > > > > day_count.yearFraction(ql.Date(5,10,2021), ql.Date(31,12,2021)) + day_count.yearFraction(ql.Date(31,12,2021), ql.Date(30,6,2022)) > > > > which gives T = 0.23888888 + 0.5 = 0.73888888. The difference in time results in a difference in discount. > > > > I'm not sure which one is best, but the second one seems to have the correct accrual time for the coupon. > > > > Hope this helps, > > Luigi > > > > > > > > On Fri, Aug 13, 2021 at 4:28 PM <mat...@gm...> wrote: > > Out of curiosity – hijacking the original question somewhat: > > > > Does any reason come to mind why > > > > day_count = ql.Thirty360(Thirty360.BondBasis) > > > > would give different values? > > > > dirtyPrice(): 103.48181611062914 > > “manual” discounting: 103.48174390787119 > > > > > > > > From: Luigi Ballabio <lui...@gm...> > Sent: Friday, 13 August, 2021 16:20 > To: mat...@gm... > Cc: jian Xu <jia...@gm...>; QuantLib users <qua...@li...> > Subject: Re: [Quantlib-users] Bond dirty price different from discounted cashflow? > > > > Hello, > > > > to work correctly, act/act(ISMA) needs to know the reference period for a given coupon. The bond has the information and knows how to pass it, but the InterestRate object doesn't. To fix that, you can pass the bond schedule when you build the day counter, as in: > > > > day_count = ql.ActualActual(ql.ActualActual.ISMA, schedule) > > > > so the day counter itself has the information. Using this day counter should give you the same result in both cases. > > > > Luigi > > > > > > > > On Fri, Aug 13, 2021 at 4:15 PM <mat...@gm...> wrote: > > On first glance, I was also wondering about the impact of the reference period, see https://quant.stackexchange.com/questions/12707/pricing-a-fixedratebond-in-quantlib-yield-vs-termstructure/12715#12715 > > But being thrown off by a difference in NPVs when using ql.Thirty360(Thirty360.BondBasis). Not quite clear about that one. > > > -----Original Message----- > From: jian Xu <jia...@gm...> > Sent: Friday, 13 August, 2021 15:53 > To: QuantLib users <qua...@li...> > Subject: Re: [Quantlib-users] Bond dirty price different from discounted cashflow? > > One thing I noticed is that if I set "day_count" to ql.ActualActual() instead of ql.ActualActual(ql.ActualActual.ISMA), then the dirty price matches the npv exactly. This is very strange. The "day_count" > variable is consistently used in the bond's constructor, dirtyPrice(), and InterestRate's constructor. Why would ql.ActualActual.ISMA causing dirty price and the npv to be different? Am I missing something? > > On Fri, Aug 13, 2021 at 7:57 AM jian Xu <jia...@gm...> wrote: > > > > Hi, > > I saw some difference between a bond's dirty price and the discounted > > cashflow to the settlement date. Cannot figure out why. > > > > For example, in the following code, the dirty price is 103.4815, while > > my discounted cashflow is 103.4674, why? Thanks a lot. > > > > =============================== > > import QuantLib as ql > > > > ## setup the security > > schedule = ql.MakeSchedule(effectiveDate = ql.Date(30, 6, 2018), > > terminationDate = ql.Date(30, 6, 2023), > > tenor = ql.Period(2), > > calendar = > > ql.UnitedStates(ql.UnitedStates.GovernmentBond), > > convention = ql.Unadjusted, > > terminalDateConvention=ql.Unadjusted, > > rule = ql.DateGeneration.Backward, > > endOfMonth = True) > > > > day_count = ql.ActualActual(ql.ActualActual.ISMA) # US market > > convention, not the QuantLib default !!! > > face = 100 > > redemption = 100 > > issue_date = ql.Date(2, 7, 2018) > > days_settle = 1 > > coupon = 2.625/100 > > payment_convention = ql.Unadjusted > > bond = ql.FixedRateBond(days_settle, > > face, > > schedule, > > [coupon], > > day_count, > > payment_convention, > > redemption, > > issue_date) > > > > ## Dirty price > > settle_date = ql.Date(5, 10, 2021) > > yld = 0.01 > > freq = ql.Semiannual > > print(bond.dirtyPrice(yld, day_count, ql.Compounded, freq, > > settle_date)) > > > > ## my discount cash flow > > disc = ql.InterestRate(yld, day_count, ql.Compounded, freq) npv = 0 > > for cf in bond.cashflows(): > > if cf.date() < settle_date: > > continue > > df = disc.discountFactor(settle_date, cf.date()) > > npv += cf.amount() * df > > print(npv) > > > _______________________________________________ > 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 |