|
From: Luigi B. <lui...@gm...> - 2021-08-13 17:03:47
|
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
>
>
|