You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
(60) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(18) |
Feb
(4) |
Mar
(6) |
Apr
(2) |
May
|
Jun
(12) |
Jul
(48) |
Aug
(6) |
Sep
(3) |
Oct
(24) |
Nov
(15) |
Dec
(18) |
| 2002 |
Jan
(39) |
Feb
(12) |
Mar
(80) |
Apr
(72) |
May
(46) |
Jun
(27) |
Jul
(23) |
Aug
(34) |
Sep
(65) |
Oct
(71) |
Nov
(19) |
Dec
(14) |
| 2003 |
Jan
(44) |
Feb
(59) |
Mar
(18) |
Apr
(62) |
May
(54) |
Jun
(27) |
Jul
(46) |
Aug
(15) |
Sep
(44) |
Oct
(36) |
Nov
(19) |
Dec
(12) |
| 2004 |
Jan
(26) |
Feb
(33) |
Mar
(47) |
Apr
(63) |
May
(36) |
Jun
(65) |
Jul
(80) |
Aug
(163) |
Sep
(65) |
Oct
(39) |
Nov
(36) |
Dec
(39) |
| 2005 |
Jan
(97) |
Feb
(78) |
Mar
(64) |
Apr
(64) |
May
(48) |
Jun
(55) |
Jul
(89) |
Aug
(57) |
Sep
(51) |
Oct
(111) |
Nov
(86) |
Dec
(76) |
| 2006 |
Jan
(84) |
Feb
(103) |
Mar
(143) |
Apr
(92) |
May
(55) |
Jun
(58) |
Jul
(71) |
Aug
(57) |
Sep
(74) |
Oct
(59) |
Nov
(8) |
Dec
(32) |
| 2007 |
Jan
(60) |
Feb
(40) |
Mar
(50) |
Apr
(26) |
May
(61) |
Jun
(120) |
Jul
(119) |
Aug
(48) |
Sep
(121) |
Oct
(66) |
Nov
(103) |
Dec
(43) |
| 2008 |
Jan
(60) |
Feb
(109) |
Mar
(92) |
Apr
(106) |
May
(82) |
Jun
(59) |
Jul
(67) |
Aug
(118) |
Sep
(131) |
Oct
(56) |
Nov
(37) |
Dec
(69) |
| 2009 |
Jan
(75) |
Feb
(76) |
Mar
(103) |
Apr
(78) |
May
(61) |
Jun
(35) |
Jul
(66) |
Aug
(69) |
Sep
(166) |
Oct
(46) |
Nov
(72) |
Dec
(65) |
| 2010 |
Jan
(48) |
Feb
(57) |
Mar
(93) |
Apr
(85) |
May
(123) |
Jun
(82) |
Jul
(98) |
Aug
(121) |
Sep
(146) |
Oct
(86) |
Nov
(72) |
Dec
(34) |
| 2011 |
Jan
(96) |
Feb
(55) |
Mar
(73) |
Apr
(57) |
May
(33) |
Jun
(74) |
Jul
(89) |
Aug
(71) |
Sep
(103) |
Oct
(76) |
Nov
(52) |
Dec
(61) |
| 2012 |
Jan
(48) |
Feb
(54) |
Mar
(78) |
Apr
(60) |
May
(75) |
Jun
(59) |
Jul
(33) |
Aug
(66) |
Sep
(43) |
Oct
(46) |
Nov
(75) |
Dec
(51) |
| 2013 |
Jan
(112) |
Feb
(72) |
Mar
(49) |
Apr
(48) |
May
(42) |
Jun
(44) |
Jul
(80) |
Aug
(19) |
Sep
(33) |
Oct
(37) |
Nov
(38) |
Dec
(98) |
| 2014 |
Jan
(113) |
Feb
(93) |
Mar
(49) |
Apr
(106) |
May
(97) |
Jun
(155) |
Jul
(87) |
Aug
(127) |
Sep
(85) |
Oct
(48) |
Nov
(41) |
Dec
(37) |
| 2015 |
Jan
(34) |
Feb
(50) |
Mar
(104) |
Apr
(80) |
May
(82) |
Jun
(66) |
Jul
(41) |
Aug
(84) |
Sep
(37) |
Oct
(65) |
Nov
(83) |
Dec
(52) |
| 2016 |
Jan
(68) |
Feb
(35) |
Mar
(42) |
Apr
(35) |
May
(54) |
Jun
(75) |
Jul
(45) |
Aug
(52) |
Sep
(60) |
Oct
(52) |
Nov
(36) |
Dec
(64) |
| 2017 |
Jan
(92) |
Feb
(59) |
Mar
(35) |
Apr
(53) |
May
(83) |
Jun
(43) |
Jul
(65) |
Aug
(68) |
Sep
(46) |
Oct
(75) |
Nov
(40) |
Dec
(49) |
| 2018 |
Jan
(68) |
Feb
(54) |
Mar
(48) |
Apr
(58) |
May
(51) |
Jun
(44) |
Jul
(40) |
Aug
(68) |
Sep
(35) |
Oct
(15) |
Nov
(7) |
Dec
(37) |
| 2019 |
Jan
(43) |
Feb
(7) |
Mar
(22) |
Apr
(21) |
May
(31) |
Jun
(39) |
Jul
(73) |
Aug
(45) |
Sep
(47) |
Oct
(89) |
Nov
(19) |
Dec
(69) |
| 2020 |
Jan
(52) |
Feb
(63) |
Mar
(45) |
Apr
(59) |
May
(42) |
Jun
(57) |
Jul
(30) |
Aug
(29) |
Sep
(75) |
Oct
(64) |
Nov
(96) |
Dec
(22) |
| 2021 |
Jan
(14) |
Feb
(24) |
Mar
(35) |
Apr
(58) |
May
(36) |
Jun
(15) |
Jul
(18) |
Aug
(31) |
Sep
(30) |
Oct
(33) |
Nov
(27) |
Dec
(16) |
| 2022 |
Jan
(35) |
Feb
(22) |
Mar
(14) |
Apr
(20) |
May
(44) |
Jun
(53) |
Jul
(25) |
Aug
(56) |
Sep
(11) |
Oct
(47) |
Nov
(22) |
Dec
(36) |
| 2023 |
Jan
(30) |
Feb
(17) |
Mar
(31) |
Apr
(48) |
May
(31) |
Jun
(7) |
Jul
(25) |
Aug
(26) |
Sep
(61) |
Oct
(66) |
Nov
(19) |
Dec
(21) |
| 2024 |
Jan
(37) |
Feb
(29) |
Mar
(26) |
Apr
(26) |
May
(34) |
Jun
(9) |
Jul
(27) |
Aug
(13) |
Sep
(15) |
Oct
(25) |
Nov
(13) |
Dec
(8) |
| 2025 |
Jan
(13) |
Feb
(1) |
Mar
(16) |
Apr
(17) |
May
(8) |
Jun
(6) |
Jul
(9) |
Aug
|
Sep
(6) |
Oct
(15) |
Nov
(6) |
Dec
|
| 2026 |
Jan
(6) |
Feb
(4) |
Mar
(20) |
Apr
(2) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Luigi B. <lui...@gm...> - 2021-04-12 07:24:56
|
Hello,
the term structure that you can retrieve from the index can't be
relinked. Instead, you should keep hold of the one you originally used to
build the index and bump that one. The index will react accordingly.
Hope this helps,
Luigi
On Sun, Apr 11, 2021 at 4:42 PM jian Xu <jia...@gm...> wrote:
> Can anyone help here? I think I'm already very close. There ought to
> be a way to bump the index, either buy relink it to a bumped curve, or
> by some other means. This should be a common practice when we want to
> calculate the interest rate sensitivity of a floating rate bond,
> shouldn't it?
>
> Thanks.
>
> On Fri, Apr 9, 2021 at 2:49 PM jian Xu <jia...@gm...> wrote:
> >
> > But after I get the index, how to bump the index? What I'm trying to
> > do is to calculate the cashflows when the index curve is bumped up,
> > say 0.0001, in parallel. I have the floating rate bond already
> > constructed, then
> >
> > bond = ql.FloatingRateBond(...)
> > cpn = ql.as_floating_rate_coupon(bond.cashflows()[0])
> > ibor = ql.as_iborindex(cpn.index())
> > forecast_curve = ibor.forwardingTermStructure()
> >
> > But how do I bump the forecast_curve? I can create a bumped forecast
> > curve like the following:
> >
> > forecast_curve_bumped = ql.ZeroSpreadedTermStructure(forecast_curve,
> > ql.QuoteHandle(ql.SimpleQuote(.0001)))
> >
> > But then how do I link the index to this bumped curve, so that the
> > bond's cashflow will be impacted? Thanks.
> >
> >
> > On Fri, Apr 9, 2021 at 11:57 AM jian Xu <jia...@gm...> wrote:
> > >
> > > I see. Thanks!
> > >
> > > On Fri, Apr 9, 2021 at 4:31 AM Luigi Ballabio <
> lui...@gm...> wrote:
> > > >
> > > > As David said — or you can avoid the map by selecting the first
> coupon before conversion:
> > > >
> > > > c = ql.as_floating_rate_coupon(bnd.cashflows()[0])
> > > > myindex = c.index()
> > > >
> > > >
> > > > On Fri, Apr 9, 2021 at 10:25 AM David Duarte <nh...@gm...>
> wrote:
> > > >>
> > > >> Hi,
> > > >>
> > > >> I'm not sure the index is exposed for the bond object, but you can
> extract it from the cashflows.
> > > >> Maybe not the easiest way to go about it, but hopefully you'll get
> the idea:
> > > >>
> > > >> bnd = ql.FloatingRateBond(...)
> > > >> c = [*map(ql.as_floating_rate_coupon, bnd.cashflows())][0]
> > > >> myindex = c.index()
> > > >>
> > > >> Regards,
> > > >> David
> > > >>
> > > >> On Fri, 9 Apr 2021 at 03:03, jian Xu <jia...@gm...> wrote:
> > > >>>
> > > >>> Hi,
> > > >>>
> > > >>> An index is passed in duration the construction of a
> FloatingRateBond,
> > > >>> But after that, given the FloatingRateBond object, how do I get
> the
> > > >>> index back (in Python)? Thanks.
> > > >>>
> > > >>> Jian
> > > >>>
> > > >>>
> > > >>> _______________________________________________
> > > >>> 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
>
|
|
From: Arun K. S. <aru...@gm...> - 2021-04-11 17:11:58
|
If your purpose is to calculate Sensitivities, you may have a look into Quantlib Python Cookbook by Luigi and Gautham Balaraman. They have a ready to use example of how to bump term structure to calculate sensitivities for Floating rate bonds. Thanks, On Sun, 11 Apr 2021 at 20:13, jian Xu <jia...@gm...> wrote: > Can anyone help here? I think I'm already very close. There ought to > be a way to bump the index, either buy relink it to a bumped curve, or > by some other means. This should be a common practice when we want to > calculate the interest rate sensitivity of a floating rate bond, > shouldn't it? > > Thanks. > > On Fri, Apr 9, 2021 at 2:49 PM jian Xu <jia...@gm...> wrote: > > > > But after I get the index, how to bump the index? What I'm trying to > > do is to calculate the cashflows when the index curve is bumped up, > > say 0.0001, in parallel. I have the floating rate bond already > > constructed, then > > > > bond = ql.FloatingRateBond(...) > > cpn = ql.as_floating_rate_coupon(bond.cashflows()[0]) > > ibor = ql.as_iborindex(cpn.index()) > > forecast_curve = ibor.forwardingTermStructure() > > > > But how do I bump the forecast_curve? I can create a bumped forecast > > curve like the following: > > > > forecast_curve_bumped = ql.ZeroSpreadedTermStructure(forecast_curve, > > ql.QuoteHandle(ql.SimpleQuote(.0001))) > > > > But then how do I link the index to this bumped curve, so that the > > bond's cashflow will be impacted? Thanks. > > > > > > On Fri, Apr 9, 2021 at 11:57 AM jian Xu <jia...@gm...> wrote: > > > > > > I see. Thanks! > > > > > > On Fri, Apr 9, 2021 at 4:31 AM Luigi Ballabio < > lui...@gm...> wrote: > > > > > > > > As David said — or you can avoid the map by selecting the first > coupon before conversion: > > > > > > > > c = ql.as_floating_rate_coupon(bnd.cashflows()[0]) > > > > myindex = c.index() > > > > > > > > > > > > On Fri, Apr 9, 2021 at 10:25 AM David Duarte <nh...@gm...> > wrote: > > > >> > > > >> Hi, > > > >> > > > >> I'm not sure the index is exposed for the bond object, but you can > extract it from the cashflows. > > > >> Maybe not the easiest way to go about it, but hopefully you'll get > the idea: > > > >> > > > >> bnd = ql.FloatingRateBond(...) > > > >> c = [*map(ql.as_floating_rate_coupon, bnd.cashflows())][0] > > > >> myindex = c.index() > > > >> > > > >> Regards, > > > >> David > > > >> > > > >> On Fri, 9 Apr 2021 at 03:03, jian Xu <jia...@gm...> wrote: > > > >>> > > > >>> Hi, > > > >>> > > > >>> An index is passed in duration the construction of a > FloatingRateBond, > > > >>> But after that, given the FloatingRateBond object, how do I get > the > > > >>> index back (in Python)? Thanks. > > > >>> > > > >>> Jian > > > >>> > > > >>> > > > >>> _______________________________________________ > > > >>> 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 > > > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: jian Xu <jia...@gm...> - 2021-04-11 14:43:01
|
Can anyone help here? I think I'm already very close. There ought to be a way to bump the index, either buy relink it to a bumped curve, or by some other means. This should be a common practice when we want to calculate the interest rate sensitivity of a floating rate bond, shouldn't it? Thanks. On Fri, Apr 9, 2021 at 2:49 PM jian Xu <jia...@gm...> wrote: > > But after I get the index, how to bump the index? What I'm trying to > do is to calculate the cashflows when the index curve is bumped up, > say 0.0001, in parallel. I have the floating rate bond already > constructed, then > > bond = ql.FloatingRateBond(...) > cpn = ql.as_floating_rate_coupon(bond.cashflows()[0]) > ibor = ql.as_iborindex(cpn.index()) > forecast_curve = ibor.forwardingTermStructure() > > But how do I bump the forecast_curve? I can create a bumped forecast > curve like the following: > > forecast_curve_bumped = ql.ZeroSpreadedTermStructure(forecast_curve, > ql.QuoteHandle(ql.SimpleQuote(.0001))) > > But then how do I link the index to this bumped curve, so that the > bond's cashflow will be impacted? Thanks. > > > On Fri, Apr 9, 2021 at 11:57 AM jian Xu <jia...@gm...> wrote: > > > > I see. Thanks! > > > > On Fri, Apr 9, 2021 at 4:31 AM Luigi Ballabio <lui...@gm...> wrote: > > > > > > As David said — or you can avoid the map by selecting the first coupon before conversion: > > > > > > c = ql.as_floating_rate_coupon(bnd.cashflows()[0]) > > > myindex = c.index() > > > > > > > > > On Fri, Apr 9, 2021 at 10:25 AM David Duarte <nh...@gm...> wrote: > > >> > > >> Hi, > > >> > > >> I'm not sure the index is exposed for the bond object, but you can extract it from the cashflows. > > >> Maybe not the easiest way to go about it, but hopefully you'll get the idea: > > >> > > >> bnd = ql.FloatingRateBond(...) > > >> c = [*map(ql.as_floating_rate_coupon, bnd.cashflows())][0] > > >> myindex = c.index() > > >> > > >> Regards, > > >> David > > >> > > >> On Fri, 9 Apr 2021 at 03:03, jian Xu <jia...@gm...> wrote: > > >>> > > >>> Hi, > > >>> > > >>> An index is passed in duration the construction of a FloatingRateBond, > > >>> But after that, given the FloatingRateBond object, how do I get the > > >>> index back (in Python)? Thanks. > > >>> > > >>> Jian > > >>> > > >>> > > >>> _______________________________________________ > > >>> 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 |
|
From: Brian S. <bri...@gm...> - 2021-04-09 23:44:51
|
Hi,
I have below code to price a floating rate bond:
import math
import datetime
mydate = Date(8, 10, 2014)
issueDate = Date(8, August, 2014)
maturityDate = Date(8, August, 2019)
Settings.instance().evaluationDate = mydate
spots = [mydate + Period("6m"), mydate + Period("1y"), mydate +
Period("2y"), mydate + Period("5y")]
spotsdate = [0.002, 0.002, 0.002, 0.002]
curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
Actual360(), TARGET(), Linear(), Compounded, Semiannual))
myindex = Euribor6M(curveHandle)
myindex.addFixing(Date(6, August, 2014), spotsdate[1], True)
bond_schedule = Schedule(issueDate, maturityDate, Period(6, Months),
TARGET(), Following, Following, DateGeneration.Backward, False)
mybond = FloatingRateBond(3, 100, bond_schedule, myindex, Actual360())
mybond.setPricingEngine(DiscountingBondEngine(curveHandle))
mybond.NPV()
When I run this code, I get error as
RuntimeError: negative time (-0.161111) given
In one of the earlier discussions, it was suggested to use some dummy
rate corresponding to pricing date, during the curve construction. But
if I use a dummy rate as 0 then I get different value for bond from
using some other rate. So below 2 choices give me 2 different results
-
spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
+ Period("2y"), mydate + Period("5y")]
spotsdate = [0.00, 0.002, 0.002, 0.002, 0.002]
and
spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
+ Period("2y"), mydate + Period("5y")]
spotsdate = [0.002, 0.002, 0.002, 0.002, 0.002]. ### simple backfilling
So I wonder, what is the right way to correct the RuntimeError:
negative time (-0.161111) given?
|
|
From: jian Xu <jia...@gm...> - 2021-04-09 19:50:54
|
But after I get the index, how to bump the index? What I'm trying to do is to calculate the cashflows when the index curve is bumped up, say 0.0001, in parallel. I have the floating rate bond already constructed, then bond = ql.FloatingRateBond(...) cpn = ql.as_floating_rate_coupon(bond.cashflows()[0]) ibor = ql.as_iborindex(cpn.index()) forecast_curve = ibor.forwardingTermStructure() But how do I bump the forecast_curve? I can create a bumped forecast curve like the following: forecast_curve_bumped = ql.ZeroSpreadedTermStructure(forecast_curve, ql.QuoteHandle(ql.SimpleQuote(.0001))) But then how do I link the index to this bumped curve, so that the bond's cashflow will be impacted? Thanks. On Fri, Apr 9, 2021 at 11:57 AM jian Xu <jia...@gm...> wrote: > > I see. Thanks! > > On Fri, Apr 9, 2021 at 4:31 AM Luigi Ballabio <lui...@gm...> wrote: > > > > As David said — or you can avoid the map by selecting the first coupon before conversion: > > > > c = ql.as_floating_rate_coupon(bnd.cashflows()[0]) > > myindex = c.index() > > > > > > On Fri, Apr 9, 2021 at 10:25 AM David Duarte <nh...@gm...> wrote: > >> > >> Hi, > >> > >> I'm not sure the index is exposed for the bond object, but you can extract it from the cashflows. > >> Maybe not the easiest way to go about it, but hopefully you'll get the idea: > >> > >> bnd = ql.FloatingRateBond(...) > >> c = [*map(ql.as_floating_rate_coupon, bnd.cashflows())][0] > >> myindex = c.index() > >> > >> Regards, > >> David > >> > >> On Fri, 9 Apr 2021 at 03:03, jian Xu <jia...@gm...> wrote: > >>> > >>> Hi, > >>> > >>> An index is passed in duration the construction of a FloatingRateBond, > >>> But after that, given the FloatingRateBond object, how do I get the > >>> index back (in Python)? Thanks. > >>> > >>> Jian > >>> > >>> > >>> _______________________________________________ > >>> 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 |
|
From: Philippe H. <phi...@ex...> - 2021-04-09 18:14:03
|
Philippe Hatstadt <phi...@ex...> 2:09 PM (0 minutes ago) to Peter, philippe One problem I am uncovering is that apparently, a ql.DiscountCurve() appears to have no concept of evaluation date, as I am finding out as described below. This seems confirmed by this thread https://stackoverflow.com/questions/45683889/discountcurve-is-not-aware-of-evaluation-date-in-quantlib-python Unfortunately, the way I wrote my code is that I compound the daily short rate from the HW engine to build a path-wise ql.DiscountCurve. In turn, what I was doing is to compute swap.NPV() (where swap is the forward starting swap underlying the swaption) with evalutionDate set at the swaption expiry, then I was deflating such NPV by the value of the numeraire at option expiry. The problem is that swap.NPV() literally doesn't change whether I set the evaluation date to the trade_date versus the option expiry date. So this is a problem. However, I am still perplexed by the following: with the bank account as numeraire, the value at option maturity of such account is effectively 1/DiscountFactor(path curve, option maturity date). So if for a given path the swap.NPV() at option expiry is NPV(Tj), the numeraire deflation would effectively make such number NPV(Tj) * DiscountFactor(path curve, option maturity date). Well, that product should be exactly equal to swap.NPV() where I set the evaluation date to trade date instead of option expiry date, or is that untrue? Assuming so, and given the issue mentioned above related to a DiscountCurve's inability to have an evaluation date other than trade_date, I think I should just take E[swap.NPV(evaluation date = trade date)] multiplied by N(t=0) which equals 1. Philippe Hatstadt On Fri, Apr 9, 2021 at 3:45 AM Peter Caspers <pca...@gm...> wrote: > Hey Philippe, > > so you simulate HW paths under a specific measure (standard HullWhite > = Bank Account, there is a class for T-Forward and the GSR which is > basically = Hull White under T-Forward as well) and compute swap.NPV() > on a simulation node (t, x) where t = simulation time, x = HW state. > You'll want to compute the NPV w.r.t. t as the valuation time, i.e. > discount the cashflows with pay date > t back to t using the > conditional curve at (t,x). Similarly you project floating coupons > with the conditional projection curve at (t,x). Then you'll have to > divide the result by the numeraire, i.e. the bank account B(t) or the > zero bond P(t,T) for the T-forward measure. The average over such > deflated NPVs will give you the NPV at t=0 over the Numeraire at t=0, > i.e. you have to multiply by B(0)=1 (no effect in this case of course) > resp. P(0,T) for T-forward measure. In formulas > > NPV(t=0) = N(0) E ( NPV(t,x) / N(t) ) > > where N = Bank Account or zero bond with maturity T. And yes, a change > in measure corresponds to a change in the drift of the simulated > process (Girsanov Theorem). > > Thanks > Peter > > > On Sun, 4 Apr 2021 at 17:57, Philippe Hatstadt > <phi...@ex...> wrote: > > > > Hi Peter. > > I am going back to this semi-dated thread. My question is what > measure/numeraire is the drift adjustment in the HW engine compatible with, > if any? In other words, if I price say a swaption via Monte-Carlo > simulation, and say I evaluation my cash flows with the discount factor as > numeraire, i.e. I use swap.NPV() to value the forward swap on each path, I > overprice the option versus closed-form Jamshidian. I think swap.NPV() is > consistent with a money market account as numeraire, so my question is > whether I am still supposed to "deflate" the swap.NPV() to satisfy no > arbitrage? I thought such deflation typically takes place as an additional > drift adjustment that needs to be calibrated, but my question is whether > this is already done or not in the HW engine for DF as numeraire, or if > there is none and it needs to be done? > > > > Philippe Hatstadt > > > > > > On Sun, Oct 25, 2020 at 1:47 PM Peter Caspers <pca...@gm...> > wrote: > >> > >> I think this is expected, according to Brigo Mercurio Formula (3.37) > >> for the mean of the short rate at t (conditional on F_s with s = 0, > >> i.e. the unconditional mean) is > >> > >> r(0) exp(-at) + alpha(t) - alpha(0) exp(-at) = alpha(t) = f(0,t) + > >> sigma^2 / (2 a^2) ( 1 - exp(- at) ) ^2 > >> > >> because alpha(0) = r(0) and so the first and last summand cancel out. > >> Plugging in sigma = 0.1 and a = 0.1 that means that E( r( 30 ) ) = > >> 0.05 + 0.4514... = 0.5014.... This is all including the term > >> responsible for the fit to the initial flat curve at 5%. And by the > >> way, I don't think you can disable this part of the drift in > >> HullWhiteProcess. > >> > >> Also, I think sigma = 0.1 is an extremely high value, maybe on purpose > >> for the sake of the example? > >> > >> > >> On Sun, 25 Oct 2020 at 17:44, Philippe Hatstadt > >> <phi...@ex...> wrote: > >> > > >> > Actually, I have a follow-up question on the drift issue. > >> > I was experimenting with the Hull-White implementation from the > QuantLib Cookbook, and interestingly, in Chapter 15, they build a flat > curve with a forward rate of 5%, via: > >> > spot_curve = ql.FlatForward(todays_date, > ql.QuoteHandle(ql.SimpleQuote(forward_rate)), day_count) > >> > > >> > The HW parameters are sigma=10% and a=10%, and the HW engine is built > via: > >> > > >> > hw_process = ql.HullWhiteProcess(spot_curve_handle, a, sigma) > >> > > >> > They then proceed to generate paths of the short term rate, and they > demonstrate that the simulated rate converges to the theoretical expected > forward rate f(0,t<T) but the graph of such expected forward is not flat at > 5%, instead it is monotonously increasing from 5% to as high as 50% after > 30 years. So it very much looks like the paths of rates that they show are > not drift adjusted otherwise the expected path should be flat at 5%. > >> > So I'm unsure what is going on? Is there an optional argument in the > hw_process call to do the drift adjustment or not? > >> > > >> > Philippe Hatstadt > >> > > >> > > >> > On Sun, Oct 25, 2020 at 9:09 AM Peter Caspers <pca...@gm...> > wrote: > >> >> > >> >> Hi Philippe, > >> >> > >> >> the Jamshidian engine uses a) discount bond prices conditional on the > >> >> state of the model (i.e. the short rate in the case of the Hull-White > >> >> model) and b) zero bond option prices in the model to come up with a > >> >> model swaption price. It retrieves this information via the > >> >> discountBond() and discountBondOption() methods in the > >> >> OneFactorAffineModel interface. The methods account for the > adjustment > >> >> term theta(t) in the Hull-White model SDE already, there is nothing > >> >> that the engine needs to do in addition to that. I don't know if that > >> >> answers your question? > >> >> > >> >> The HullWhiteProcess also takes into account the adjustment to the > >> >> initial curve already. To see that you can look into the > >> >> implementation of HullWhiteProcess::drift() > >> >> > >> >> > https://github.com/lballabio/QuantLib/blob/master/ql/processes/hullwhiteprocess.cpp#L38 > >> >> > >> >> which coincides with e.g. Brigo Mercurio, Interest Rate Models, > Theory > >> >> and Practice, Formulas (3.33) and (3.34) observing that in this > >> >> context > >> >> > >> >> > https://github.com/lballabio/QuantLib/blob/master/ql/processes/ornsteinuhlenbeckprocess.hpp#L90 > >> >> > >> >> level_ is zero, speed_ is the Hull-White mean reversion parameter and > >> >> x stands for the short rate at time t. > >> >> > >> >> Does that make sense? > >> >> > >> >> Thanks, > >> >> Peter > >> >> > >> >> > >> >> On Sun, 25 Oct 2020 at 12:47, philippe hatstadt via QuantLib-users > >> >> <qua...@li...> wrote: > >> >> > > >> >> > Is there any information about how the Jamshidian engine does the > drift adjustment to match the initial curve for the Hull White model? > >> >> > If I want to use the QL HW Process in a MC model, I assume II have > to do the drift adjustment myself, or is there existing QL functionality to > do that? > >> >> > > >> >> > Regards > >> >> > > >> >> > Philippe Hatstadt > >> >> > +1-203-252-0408 > >> >> > https://www.linkedin.com/in/philippe-hatstadt > >> >> > > >> >> > > >> >> > > >> >> > _______________________________________________ > >> >> > 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 > >> > > >> > > >> > > >> > > >> > Brokerage services offered through Exos Securities LLC, member of > SIPC / FINRA. For important disclosures, click here. > > > > > > > > > > Broker-Dealer services offered through Exos Securities LLC, member of > SIPC / FINRA / BrokerCheck / 2021 Exos, inc. For important disclosures, > click here. > > > > > -- 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>. |
|
From: jian Xu <jia...@gm...> - 2021-04-09 16:59:43
|
I see. Thanks! On Fri, Apr 9, 2021 at 4:31 AM Luigi Ballabio <lui...@gm...> wrote: > > As David said — or you can avoid the map by selecting the first coupon before conversion: > > c = ql.as_floating_rate_coupon(bnd.cashflows()[0]) > myindex = c.index() > > > On Fri, Apr 9, 2021 at 10:25 AM David Duarte <nh...@gm...> wrote: >> >> Hi, >> >> I'm not sure the index is exposed for the bond object, but you can extract it from the cashflows. >> Maybe not the easiest way to go about it, but hopefully you'll get the idea: >> >> bnd = ql.FloatingRateBond(...) >> c = [*map(ql.as_floating_rate_coupon, bnd.cashflows())][0] >> myindex = c.index() >> >> Regards, >> David >> >> On Fri, 9 Apr 2021 at 03:03, jian Xu <jia...@gm...> wrote: >>> >>> Hi, >>> >>> An index is passed in duration the construction of a FloatingRateBond, >>> But after that, given the FloatingRateBond object, how do I get the >>> index back (in Python)? Thanks. >>> >>> Jian >>> >>> >>> _______________________________________________ >>> 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 |
|
From: Christofer B. <bog...@gm...> - 2021-04-09 10:42:41
|
Great, thanks! Just wondering if there is any example on this implementation either in C++ or Python. The payoff of such instruments is based on Arithmetic/Geometric average of OI rate over the tenor. Thanks and regards, On Fri, Apr 9, 2021 at 1:16 PM Peter Caspers <pca...@gm...> wrote: > > Hi Christofer, this is released code, so you can do it today. > Thanks, Peter > > On Sun, 21 Mar 2021 at 19:46, Christofer Bogaso > <bog...@gm...> wrote: > > > > Thanks. > > > > Do we have any timeline when cap / floor pricing for ON coupons will > > be available? > > > > Also, some workout examples will be super helpful. > > > > On Sat, Mar 20, 2021 at 12:55 AM Peter Caspers <pca...@gm...> wrote: > > > > > > Hi Christofer, > > > > > > we have added a pricer here > > > > > > https://github.com/OpenSourceRisk/Engine/blob/master/QuantExt/qle/cashflows/blackovernightindexedcouponpricer.hpp > > > > > > inspired by Lyanshenko / Mercurio, Looking forward to backward looking > > > rates, section 6.3. Currently there are only the old Libor > > > volatilities available as far as I know. I'd expect that there will be > > > new volatility quotes in the future and some sort of market formula > > > that translates those into standard cap prices. Therefore the > > > implementation should be seen as preliminary and proprietary, there > > > are other possible approaches. We'll update the method as soon as the > > > market develops. I should also mention that there is a bug in the > > > github code, line 70 in the cpp should be > > > > > > Real stdDev = sigma * std::sqrt(std::max(fixingStartTime, 0.0) + > > > std::pow(fixingEndTime - > > > std::max(fixingStartTime, 0.0), 3.0) / > > > std::pow(fixingEndTime - > > > fixingStartTime, 2.0) / 3.0); > > > > > > which will be in the next ORE release. We also added daily (or > > > "local") cap / floor pricing for ON coupons, which will be available > > > in that release as well. Hope that helps in one way or the other. Any > > > feedback or discussions around this topic are welcome! > > > > > > Thanks > > > Peter > > > > > > On Wed, 17 Mar 2021 at 18:39, Christofer Bogaso > > > <bog...@gm...> wrote: > > > > > > > > Hi, > > > > > > > > I am just wondering if there is any implementation to price some > > > > Interest Rate Caps and Swaptions where payoff is based on Overnight > > > > rate contrary to present Libor references. > > > > > > > > So far I can only see QL implementation based on Libor. > > > > > > > > Any reference to OI based pricing would be appreciated. > > > > > > > > Thanks and regards, > > > > > > > > > > > > _______________________________________________ > > > > QuantLib-users mailing list > > > > Qua...@li... > > > > https://lists.sourceforge.net/lists/listinfo/quantlib-users |
|
From: David S. <da...@el...> - 2021-04-09 10:41:53
|
Thanks Peter, I’ll take a look! I am in the fortunate position of being in control of all parts of the system, so I should be able to maintain consistency. I think I will probably go for an object repository indexed by a string. The QuantLibXL Excel interface has handy enumeration functions, so I can probably generate a lot of the code from that. Best David > On 9 Apr 2021, at 08:55, Peter Caspers <pca...@gm...> wrote: > > Yes, we have functions to convert strings into QuantLib / QuantExt > objects and back, see > > https://github.com/OpenSourceRisk/Engine/blob/master/OREData/ored/utilities/parsers.cpp > > However, we don't aim at a complete coverage of all existing C++ > classes nor do we strive to support aliases from all possible systems > in the world. Also, for certain objects like calendars, currencies, > also some index types, we move more and more to dynamically created > objects, i.e. we set up the objects from the contents of an xml file. > That is of course not possible in cases where the objects involve > complicated computations like ActAct ICMA day counter, but for the > Chinese Calendar it's easier than to update C++ and depend on the > release cycle. > > Thanks, Peter > >> On Thu, 8 Apr 2021 at 15:59, Francois Botha <ig...@gm...> wrote: >> >> I'm guessing here, but does OpenRiskEngine not do something like that? Maybe Peter can confirm. If so, maybe David can leverage off the work that has been done there. >> >> regards >> Francois Botha >> >> >>> On Thu, 8 Apr 2021 at 15:40, Luigi Ballabio <lui...@gm...> wrote: >>> >>> Hello David, >>> I'd prefer not to do that in the library. It would mean not only maintaining the factory, but also the whole set of different day-counter names that people might have in their existing DB because they're getting data from Reuters or Bloomberg or whatever provider they're using. >>> >>> Luigi >>> >>> >>> On Wed, Apr 7, 2021 at 7:40 PM <da...@el...> wrote: >>>> >>>> Hi, >>>> >>>> This may be something that has been asked before, but I am trying to rebuild various DayCounters (and indeed other Enums/classes) from a string-based name in C++. My goal is to store the configurations needed to build a QL bond in an SQL database (eg if I want to build a Belgian spline curve, from a defined list of bond ISINs). >>>> >>>> In Python, with its run-time type discovery, I can save the string representation of the class or enum into the database, and get the object back using eval(). However that isn’t much help for when/if I migrate the code to C++. I’d much prefer to use the string-based name, as in QuantLibXL (see QuantLibXL: Enumerations ) which has the added benefit that I can use the same definitions in Excel. >>>> >>>> >>>> >>>> It is simple enough to write a DayCounterFactory class in C++, build a map of {name,instance of QL class), and get back a DayCounter object of the correct type. However, I run the risk of being out of sync with any changes made in QuantLib (eg new enums). >>>> >>>> Is there any chance of putting this factory into QuantLib itself, and hence maintaining it along with the rest of the project? This may have been asked before, and rejected for sound conceptual reasons of which I am unaware! >>>> >>>> >>>> >>>> Best wishes, >>>> >>>> >>>> >>>> David Sansom >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> 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 >> >> _______________________________________________ >> 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 |
|
From: Luigi B. <lui...@gm...> - 2021-04-09 09:43:03
|
As David said — or you can avoid the map by selecting the first coupon before conversion: c = ql.as_floating_rate_coupon(bnd.cashflows()[0]) myindex = c.index() On Fri, Apr 9, 2021 at 10:25 AM David Duarte <nh...@gm...> wrote: > Hi, > > I'm not sure the index is exposed for the bond object, but you can extract > it from the cashflows. > Maybe not the easiest way to go about it, but hopefully you'll get the > idea: > > bnd = ql.FloatingRateBond(...) > c = [*map(ql.as_floating_rate_coupon, bnd.cashflows())][0] > myindex = c.index() > > Regards, > David > > On Fri, 9 Apr 2021 at 03:03, jian Xu <jia...@gm...> wrote: > >> Hi, >> >> An index is passed in duration the construction of a FloatingRateBond, >> But after that, given the FloatingRateBond object, how do I get the >> index back (in Python)? Thanks. >> >> Jian >> >> >> _______________________________________________ >> 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 > |
|
From: David D. <nh...@gm...> - 2021-04-09 08:23:46
|
Hi, I'm not sure the index is exposed for the bond object, but you can extract it from the cashflows. Maybe not the easiest way to go about it, but hopefully you'll get the idea: bnd = ql.FloatingRateBond(...) c = [*map(ql.as_floating_rate_coupon, bnd.cashflows())][0] myindex = c.index() Regards, David On Fri, 9 Apr 2021 at 03:03, jian Xu <jia...@gm...> wrote: > Hi, > > An index is passed in duration the construction of a FloatingRateBond, > But after that, given the FloatingRateBond object, how do I get the > index back (in Python)? Thanks. > > Jian > > > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Peter C. <pca...@gm...> - 2021-04-09 08:03:15
|
Hey Philippe, so you simulate HW paths under a specific measure (standard HullWhite = Bank Account, there is a class for T-Forward and the GSR which is basically = Hull White under T-Forward as well) and compute swap.NPV() on a simulation node (t, x) where t = simulation time, x = HW state. You'll want to compute the NPV w.r.t. t as the valuation time, i.e. discount the cashflows with pay date > t back to t using the conditional curve at (t,x). Similarly you project floating coupons with the conditional projection curve at (t,x). Then you'll have to divide the result by the numeraire, i.e. the bank account B(t) or the zero bond P(t,T) for the T-forward measure. The average over such deflated NPVs will give you the NPV at t=0 over the Numeraire at t=0, i.e. you have to multiply by B(0)=1 (no effect in this case of course) resp. P(0,T) for T-forward measure. In formulas NPV(t=0) = N(0) E ( NPV(t,x) / N(t) ) where N = Bank Account or zero bond with maturity T. And yes, a change in measure corresponds to a change in the drift of the simulated process (Girsanov Theorem). Thanks Peter On Sun, 4 Apr 2021 at 17:57, Philippe Hatstadt <phi...@ex...> wrote: > > Hi Peter. > I am going back to this semi-dated thread. My question is what measure/numeraire is the drift adjustment in the HW engine compatible with, if any? In other words, if I price say a swaption via Monte-Carlo simulation, and say I evaluation my cash flows with the discount factor as numeraire, i.e. I use swap.NPV() to value the forward swap on each path, I overprice the option versus closed-form Jamshidian. I think swap.NPV() is consistent with a money market account as numeraire, so my question is whether I am still supposed to "deflate" the swap.NPV() to satisfy no arbitrage? I thought such deflation typically takes place as an additional drift adjustment that needs to be calibrated, but my question is whether this is already done or not in the HW engine for DF as numeraire, or if there is none and it needs to be done? > > Philippe Hatstadt > > > On Sun, Oct 25, 2020 at 1:47 PM Peter Caspers <pca...@gm...> wrote: >> >> I think this is expected, according to Brigo Mercurio Formula (3.37) >> for the mean of the short rate at t (conditional on F_s with s = 0, >> i.e. the unconditional mean) is >> >> r(0) exp(-at) + alpha(t) - alpha(0) exp(-at) = alpha(t) = f(0,t) + >> sigma^2 / (2 a^2) ( 1 - exp(- at) ) ^2 >> >> because alpha(0) = r(0) and so the first and last summand cancel out. >> Plugging in sigma = 0.1 and a = 0.1 that means that E( r( 30 ) ) = >> 0.05 + 0.4514... = 0.5014.... This is all including the term >> responsible for the fit to the initial flat curve at 5%. And by the >> way, I don't think you can disable this part of the drift in >> HullWhiteProcess. >> >> Also, I think sigma = 0.1 is an extremely high value, maybe on purpose >> for the sake of the example? >> >> >> On Sun, 25 Oct 2020 at 17:44, Philippe Hatstadt >> <phi...@ex...> wrote: >> > >> > Actually, I have a follow-up question on the drift issue. >> > I was experimenting with the Hull-White implementation from the QuantLib Cookbook, and interestingly, in Chapter 15, they build a flat curve with a forward rate of 5%, via: >> > spot_curve = ql.FlatForward(todays_date, ql.QuoteHandle(ql.SimpleQuote(forward_rate)), day_count) >> > >> > The HW parameters are sigma=10% and a=10%, and the HW engine is built via: >> > >> > hw_process = ql.HullWhiteProcess(spot_curve_handle, a, sigma) >> > >> > They then proceed to generate paths of the short term rate, and they demonstrate that the simulated rate converges to the theoretical expected forward rate f(0,t<T) but the graph of such expected forward is not flat at 5%, instead it is monotonously increasing from 5% to as high as 50% after 30 years. So it very much looks like the paths of rates that they show are not drift adjusted otherwise the expected path should be flat at 5%. >> > So I'm unsure what is going on? Is there an optional argument in the hw_process call to do the drift adjustment or not? >> > >> > Philippe Hatstadt >> > >> > >> > On Sun, Oct 25, 2020 at 9:09 AM Peter Caspers <pca...@gm...> wrote: >> >> >> >> Hi Philippe, >> >> >> >> the Jamshidian engine uses a) discount bond prices conditional on the >> >> state of the model (i.e. the short rate in the case of the Hull-White >> >> model) and b) zero bond option prices in the model to come up with a >> >> model swaption price. It retrieves this information via the >> >> discountBond() and discountBondOption() methods in the >> >> OneFactorAffineModel interface. The methods account for the adjustment >> >> term theta(t) in the Hull-White model SDE already, there is nothing >> >> that the engine needs to do in addition to that. I don't know if that >> >> answers your question? >> >> >> >> The HullWhiteProcess also takes into account the adjustment to the >> >> initial curve already. To see that you can look into the >> >> implementation of HullWhiteProcess::drift() >> >> >> >> https://github.com/lballabio/QuantLib/blob/master/ql/processes/hullwhiteprocess.cpp#L38 >> >> >> >> which coincides with e.g. Brigo Mercurio, Interest Rate Models, Theory >> >> and Practice, Formulas (3.33) and (3.34) observing that in this >> >> context >> >> >> >> https://github.com/lballabio/QuantLib/blob/master/ql/processes/ornsteinuhlenbeckprocess.hpp#L90 >> >> >> >> level_ is zero, speed_ is the Hull-White mean reversion parameter and >> >> x stands for the short rate at time t. >> >> >> >> Does that make sense? >> >> >> >> Thanks, >> >> Peter >> >> >> >> >> >> On Sun, 25 Oct 2020 at 12:47, philippe hatstadt via QuantLib-users >> >> <qua...@li...> wrote: >> >> > >> >> > Is there any information about how the Jamshidian engine does the drift adjustment to match the initial curve for the Hull White model? >> >> > If I want to use the QL HW Process in a MC model, I assume II have to do the drift adjustment myself, or is there existing QL functionality to do that? >> >> > >> >> > Regards >> >> > >> >> > Philippe Hatstadt >> >> > +1-203-252-0408 >> >> > https://www.linkedin.com/in/philippe-hatstadt >> >> > >> >> > >> >> > >> >> > _______________________________________________ >> >> > 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 >> > >> > >> > >> > >> > Brokerage services offered through Exos Securities LLC, member of SIPC / FINRA. For important disclosures, click here. > > > > > Broker-Dealer services offered through Exos Securities LLC, member of SIPC / FINRA / BrokerCheck / 2021 Exos, inc. For important disclosures, click here. > > |
|
From: Peter C. <pca...@gm...> - 2021-04-09 08:03:12
|
Hi Christofer, this is released code, so you can do it today. Thanks, Peter On Sun, 21 Mar 2021 at 19:46, Christofer Bogaso <bog...@gm...> wrote: > > Thanks. > > Do we have any timeline when cap / floor pricing for ON coupons will > be available? > > Also, some workout examples will be super helpful. > > On Sat, Mar 20, 2021 at 12:55 AM Peter Caspers <pca...@gm...> wrote: > > > > Hi Christofer, > > > > we have added a pricer here > > > > https://github.com/OpenSourceRisk/Engine/blob/master/QuantExt/qle/cashflows/blackovernightindexedcouponpricer.hpp > > > > inspired by Lyanshenko / Mercurio, Looking forward to backward looking > > rates, section 6.3. Currently there are only the old Libor > > volatilities available as far as I know. I'd expect that there will be > > new volatility quotes in the future and some sort of market formula > > that translates those into standard cap prices. Therefore the > > implementation should be seen as preliminary and proprietary, there > > are other possible approaches. We'll update the method as soon as the > > market develops. I should also mention that there is a bug in the > > github code, line 70 in the cpp should be > > > > Real stdDev = sigma * std::sqrt(std::max(fixingStartTime, 0.0) + > > std::pow(fixingEndTime - > > std::max(fixingStartTime, 0.0), 3.0) / > > std::pow(fixingEndTime - > > fixingStartTime, 2.0) / 3.0); > > > > which will be in the next ORE release. We also added daily (or > > "local") cap / floor pricing for ON coupons, which will be available > > in that release as well. Hope that helps in one way or the other. Any > > feedback or discussions around this topic are welcome! > > > > Thanks > > Peter > > > > On Wed, 17 Mar 2021 at 18:39, Christofer Bogaso > > <bog...@gm...> wrote: > > > > > > Hi, > > > > > > I am just wondering if there is any implementation to price some > > > Interest Rate Caps and Swaptions where payoff is based on Overnight > > > rate contrary to present Libor references. > > > > > > So far I can only see QL implementation based on Libor. > > > > > > Any reference to OI based pricing would be appreciated. > > > > > > Thanks and regards, > > > > > > > > > _______________________________________________ > > > QuantLib-users mailing list > > > Qua...@li... > > > https://lists.sourceforge.net/lists/listinfo/quantlib-users |
|
From: Peter C. <pca...@gm...> - 2021-04-09 07:53:53
|
Yes, we have functions to convert strings into QuantLib / QuantExt objects and back, see https://github.com/OpenSourceRisk/Engine/blob/master/OREData/ored/utilities/parsers.cpp However, we don't aim at a complete coverage of all existing C++ classes nor do we strive to support aliases from all possible systems in the world. Also, for certain objects like calendars, currencies, also some index types, we move more and more to dynamically created objects, i.e. we set up the objects from the contents of an xml file. That is of course not possible in cases where the objects involve complicated computations like ActAct ICMA day counter, but for the Chinese Calendar it's easier than to update C++ and depend on the release cycle. Thanks, Peter On Thu, 8 Apr 2021 at 15:59, Francois Botha <ig...@gm...> wrote: > > I'm guessing here, but does OpenRiskEngine not do something like that? Maybe Peter can confirm. If so, maybe David can leverage off the work that has been done there. > > regards > Francois Botha > > > On Thu, 8 Apr 2021 at 15:40, Luigi Ballabio <lui...@gm...> wrote: >> >> Hello David, >> I'd prefer not to do that in the library. It would mean not only maintaining the factory, but also the whole set of different day-counter names that people might have in their existing DB because they're getting data from Reuters or Bloomberg or whatever provider they're using. >> >> Luigi >> >> >> On Wed, Apr 7, 2021 at 7:40 PM <da...@el...> wrote: >>> >>> Hi, >>> >>> This may be something that has been asked before, but I am trying to rebuild various DayCounters (and indeed other Enums/classes) from a string-based name in C++. My goal is to store the configurations needed to build a QL bond in an SQL database (eg if I want to build a Belgian spline curve, from a defined list of bond ISINs). >>> >>> In Python, with its run-time type discovery, I can save the string representation of the class or enum into the database, and get the object back using eval(). However that isn’t much help for when/if I migrate the code to C++. I’d much prefer to use the string-based name, as in QuantLibXL (see QuantLibXL: Enumerations ) which has the added benefit that I can use the same definitions in Excel. >>> >>> >>> >>> It is simple enough to write a DayCounterFactory class in C++, build a map of {name,instance of QL class), and get back a DayCounter object of the correct type. However, I run the risk of being out of sync with any changes made in QuantLib (eg new enums). >>> >>> Is there any chance of putting this factory into QuantLib itself, and hence maintaining it along with the rest of the project? This may have been asked before, and rejected for sound conceptual reasons of which I am unaware! >>> >>> >>> >>> Best wishes, >>> >>> >>> >>> David Sansom >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> >>> _______________________________________________ >>> 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 > > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users |
|
From: jian Xu <jia...@gm...> - 2021-04-09 02:03:09
|
Hi, An index is passed in duration the construction of a FloatingRateBond, But after that, given the FloatingRateBond object, how do I get the index back (in Python)? Thanks. Jian |
|
From: Francois B. <ig...@gm...> - 2021-04-08 13:58:51
|
I'm guessing here, but does OpenRiskEngine not do something like that? Maybe Peter can confirm. If so, maybe David can leverage off the work that has been done there. regards Francois Botha On Thu, 8 Apr 2021 at 15:40, Luigi Ballabio <lui...@gm...> wrote: > Hello David, > I'd prefer not to do that in the library. It would mean not only > maintaining the factory, but also the whole set of different > day-counter names that people might have in their existing DB because > they're getting data from Reuters or Bloomberg or whatever provider they're > using. > > Luigi > > > On Wed, Apr 7, 2021 at 7:40 PM <da...@el...> wrote: > >> Hi, >> >> This may be something that has been asked before, but I am trying to >> rebuild various DayCounters (and indeed other Enums/classes) from a >> string-based name in C++. My goal is to store the configurations needed to >> build a QL bond in an SQL database (eg if I want to build a Belgian spline >> curve, from a defined list of bond ISINs). >> >> In Python, with its run-time type discovery, I can save the string >> representation of the class or enum into the database, and get the object >> back using eval(). However that isn’t much help for when/if I migrate the >> code to C++. I’d much prefer to use the string-based name, as in QuantLibXL >> (see QuantLibXL: Enumerations >> <https://www.quantlib.org/quantlibxl/enums.html#enum_type_11> ) which >> has the added benefit that I can use the same definitions in Excel. >> >> >> >> It is simple enough to write a DayCounterFactory class in C++, build a >> map of {name,instance of QL class), and get back a DayCounter object of the >> correct type. However, I run the risk of being out of sync with any changes >> made in QuantLib (eg new enums). >> >> Is there any chance of putting this factory into QuantLib itself, and >> hence maintaining it along with the rest of the project? This may have been >> asked before, and rejected for sound conceptual reasons of which I am >> unaware! >> >> >> >> Best wishes, >> >> >> >> David Sansom >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> _______________________________________________ >> 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 > |
|
From: Luigi B. <lui...@gm...> - 2021-04-08 13:53:02
|
Hello,
I don't think we have example code for the treasury curve, but the idea
is that if you have the par yields of a set of bonds (i.e., the coupons
that cause those bonds to have price 100) you can use the
PiecewiseYieldCurve class for bootstrap and pass it a series of BondHelpers
corresponding to that set of bonds — that is, each will have one of the
given maturities, the corresponding coupon rate, and a quoted price of 100.
Once you have the curve, you can use it as any other curve. For vanilla
options, you can look at the EquityOption example distributed with QuantLib
and replace the flat curve in the example with your curve.
Hope this helps,
Luigi
On Tue, Mar 16, 2021 at 9:17 PM Prasanna Katta <pk...@ku...>
wrote:
> Hello.
> Are there any examples which show how to bootstrap the US Treasury yield
> curve, and then use them to price vanilla options? The following is an
> example of the US Treasury yield curve.
>
> Date1 Mo2 Mo3 Mo6 Mo1 Yr2 Yr3 Yr5 Yr7 Yr10 Yr20 Yr30 Yr
> 01/02/13 0.07 N/A 0.08 0.12 0.15 0.27 0.37 0.76 1.25 1.86 2.63 3.04
>
> Any guidance would be appreciated.
>
> Thanks.
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: Luigi B. <lui...@gm...> - 2021-04-08 13:37:41
|
Hello David,
I'd prefer not to do that in the library. It would mean not only
maintaining the factory, but also the whole set of different
day-counter names that people might have in their existing DB because
they're getting data from Reuters or Bloomberg or whatever provider they're
using.
Luigi
On Wed, Apr 7, 2021 at 7:40 PM <da...@el...> wrote:
> Hi,
>
> This may be something that has been asked before, but I am trying to
> rebuild various DayCounters (and indeed other Enums/classes) from a
> string-based name in C++. My goal is to store the configurations needed to
> build a QL bond in an SQL database (eg if I want to build a Belgian spline
> curve, from a defined list of bond ISINs).
>
> In Python, with its run-time type discovery, I can save the string
> representation of the class or enum into the database, and get the object
> back using eval(). However that isn’t much help for when/if I migrate the
> code to C++. I’d much prefer to use the string-based name, as in QuantLibXL
> (see QuantLibXL: Enumerations
> <https://www.quantlib.org/quantlibxl/enums.html#enum_type_11> ) which has
> the added benefit that I can use the same definitions in Excel.
>
>
>
> It is simple enough to write a DayCounterFactory class in C++, build a map
> of {name,instance of QL class), and get back a DayCounter object of the
> correct type. However, I run the risk of being out of sync with any changes
> made in QuantLib (eg new enums).
>
> Is there any chance of putting this factory into QuantLib itself, and
> hence maintaining it along with the rest of the project? This may have been
> asked before, and rejected for sound conceptual reasons of which I am
> unaware!
>
>
>
> Best wishes,
>
>
>
> David Sansom
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: <da...@el...> - 2021-04-07 17:37:45
|
Hi, This may be something that has been asked before, but I am trying to rebuild various DayCounters (and indeed other Enums/classes) from a string-based name in C++. My goal is to store the configurations needed to build a QL bond in an SQL database (eg if I want to build a Belgian spline curve, from a defined list of bond ISINs). In Python, with its run-time type discovery, I can save the string representation of the class or enum into the database, and get the object back using eval(). However that isn't much help for when/if I migrate the code to C++. I'd much prefer to use the string-based name, as in QuantLibXL (see QuantLibXL: Enumerations <https://www.quantlib.org/quantlibxl/enums.html#enum_type_11> ) which has the added benefit that I can use the same definitions in Excel. It is simple enough to write a DayCounterFactory class in C++, build a map of {name,instance of QL class), and get back a DayCounter object of the correct type. However, I run the risk of being out of sync with any changes made in QuantLib (eg new enums). Is there any chance of putting this factory into QuantLib itself, and hence maintaining it along with the rest of the project? This may have been asked before, and rejected for sound conceptual reasons of which I am unaware! Best wishes, David Sansom |
|
From: David D. <nh...@gm...> - 2021-04-07 08:05:47
|
Because you gave the input for the 29 fixing and not the 31...
If you give it a fixing for the 31 will get that rate.
myindex.addFixing(Date(31, 1, 2018), 0.05, True)
print(myindex.fixing(spots[0]))
# 0.05
On Wed, 7 Apr 2021 at 09:00, Brian Smith <bri...@gm...> wrote:
> Yes. That I get. But my question is why on Date(31,1,2018) I get rate
> 0.051194139707830454?
>
> Should not I get 5%, because thats what I fixed manually for Date(29, 1,
> 2018)?
>
> On Wed, 7 Apr 2021 at 13:26, David Duarte <nh...@gm...> wrote:
> >
> > Because spot[0] will not give you the fixing date, as the fixing date is
> 2 business days before the start of the accrual period.
> >
> > I believe Date(29, 1, 2018) is the fixing date for your first period and
> spot[0] would be Date(31,1,2018)
> >
> > On Wed, 7 Apr 2021 at 08:23, Brian Smith <bri...@gm...>
> wrote:
> >>
> >> Many thanks!
> >>
> >> However when I try to extract the Fixing rate for 31-01-2018, I get a
> >> different value from 5% which I defined manually.
> >>
> >> >>> myindex.fixing(spots[0])
> >> 0.051194139707830454
> >>
> >> However I already defined :
> >>
> >> myindex.addFixing(Date(29, 1, 2018), spotsdate[1], True)
> >>
> >> Given that next fixing will happen only on July-2018, should I expect
> >> myindex.fixing(spots[0]) = 5%?
> >>
> >> Why am I seeing 0.051194139707830454?
> >>
> >> Thanks for your time.
> >>
> >> On Wed, 7 Apr 2021 at 11:42, Ponram Gopal <po...@gm...> wrote:
> >> >
> >> > The coupon payment amounts are based on the projected Euribor6M reset
> rates.
> >> > 5% was added as the fixing for 29-Jan-2018. The next reset rate was
> projected based on the zero curve.
> >> >
> >> > myindex.fixing(Date(27,7,2018))
> >> > Out[69]: 0.050644366225002097
> >> >
> >> > myindex.fixing(Date(27,7,2018))*Actual360().yearFraction(spots[1],
> spots[2]) * 100
> >> > Out[72]: 2.5884898292778846
> >> >
> >> > The coupon amount of 2.5884898292778846 is based on the projected
> rate fixing on 27-Jul-2018.
> >> >
> >> > df1 = curveHandle.discount(Date(31,7,2018))
> >> > df2 = curveHandle.discount(Date(31,1,2019))
> >> > accrual_factor =
> Actual360().yearFraction(Date(31,7,2018),Date(31,1,2019))
> >> > fwd_rate = ((df1/df2)-1)/accrual_factor
> >> >
> >> > fwd_rate
> >> > Out[104]: 0.050644366225002097
> >> >
> >> > On Tue, Apr 6, 2021 at 2:17 PM Brian Smith <
> bri...@gm...> wrote:
> >> >>
> >> >> Hi all - I would really appreciate if someone points me why I see
> this
> >> >> difference, although small, just to make sure I am not making any
> >> >> trivial mistake.
> >> >>
> >> >> Thanks for your time.
> >> >>
> >> >> On Mon, 5 Apr 2021 at 15:48, Brian Smith <bri...@gm...>
> wrote:
> >> >> >
> >> >> > I see. Thanks for pointing this out.
> >> >> >
> >> >> > Coming back to the calculation of 2nd coupon, I did manual
> calculation
> >> >> > given that in the yield curve construction, I choose continuous
> >> >> > compounding -
> >> >> >
> >> >> > (math.sqrt(math.exp(0.05)) - 1)*2 *
> Actual360().yearFraction(spots[1],
> >> >> > spots[2]) * 100
> >> >> >
> >> >> > This gives answer 2.5877678758305054
> >> >> >
> >> >> > Whereas, QL gives coupon payment as 2.5884898292778846
> >> >> >
> >> >> > So, I dont see any exact match. Is there any definitive reason for
> >> >> > this? Or just due to floating point error?
> >> >> >
> >> >> > On Mon, 5 Apr 2021 at 15:32, David Duarte <nh...@gm...>
> wrote:
> >> >> > >
> >> >> > > Because the fixing date for that coupon is 29.01.2018 and you
> specified 0 for that fixing...
> >> >> > >
> >> >> > > Try changing this line, and the first coupon will have the rate
> you input:;
> >> >> > >
> >> >> > > myindex.addFixing(Date(29, 1, 2018), 0.0, True)
> >> >> > >
> >> >> > > On Mon, 5 Apr 2021 at 10:58, Brian Smith <
> bri...@gm...> wrote:
> >> >> > >>
> >> >> > >> Thanks.
> >> >> > >>
> >> >> > >> But still I dont have any clue what was wrong in below code?
> >> >> > >>
> >> >> > >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> >> >> > >> Actual360()).cashflows()]
> >> >> > >>
> >> >> > >> Why am I getting 0 here as first coupon?
> >> >> > >>
> >> >> > >> On Mon, 5 Apr 2021 at 15:11, David Duarte <nh...@gm...>
> wrote:
> >> >> > >> >
> >> >> > >> > The curve you are building takes continuous rates as inputs
> and uses linear interpolation of zero yields for non node points.
> >> >> > >> > You could alternatively specify annually compounded rates as
> inputs.
> >> >> > >> >
> >> >> > >> >
> >> >> > >> > In any case, you can inspect the cashflow details with
> ql.as_floating_coupon.
> >> >> > >> >
> >> >> > >> > Here is an example:
> >> >> > >> >
> >> >> > >> > bond = FloatingRateBond(0, 100, bond_schedule , myindex,
> Actual360())
> >> >> > >> > interest_cashflows = [*map(as_floating_rate_coupon,
> bond.cashflows())][:-1]
> >> >> > >> > rate = interest_cashflows[1].rate()
> >> >> > >> > accrualDays = interest_cashflows[1].accrualDays()
> >> >> > >> >
> >> >> > >> > print("Floating rate:", rate)
> >> >> > >> > print("Cashflow", 100 * rate * accrualDays/360)
> >> >> > >> >
> >> >> > >> >
> >> >> > >> > # Floating rate: 0.050644366225002097
> >> >> > >> > # Cashflow 2.588489829277885
> >> >> > >> >
> >> >> > >> >
> >> >> > >> > On Mon, 5 Apr 2021 at 07:02, Brian Smith <
> bri...@gm...> wrote:
> >> >> > >> >>
> >> >> > >> >> Thanks again.
> >> >> > >> >>
> >> >> > >> >> Below is my modified code with 0 replaced by a dummy 0.05.
> But still I
> >> >> > >> >> see 0 for first coupon payment.
> >> >> > >> >>
> >> >> > >> >> from QuantLib import *
> >> >> > >> >>
> >> >> > >> >> mydate = Date(31, 1, 2018)
> >> >> > >> >>
> >> >> > >> >> Settings.instance().evaluationDate = mydate
> >> >> > >> >>
> >> >> > >> >> spots = [mydate, mydate + Period("6m"), mydate +
> Period("1y"), mydate
> >> >> > >> >> + Period("2y"), mydate + Period("3y")]
> >> >> > >> >> spotsdate = [0.05, 0.05, 0.05, 0.05, 0.05]
> >> >> > >> >>
> >> >> > >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots,
> spotsdate,
> >> >> > >> >> Actual360(), Canada(), Linear(), Continuous))
> >> >> > >> >>
> >> >> > >> >> myindex = Euribor6M(curveHandle)
> >> >> > >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> >> >> > >> >>
> >> >> > >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"),
> Period(6,
> >> >> > >> >> Months), Canada(), Unadjusted, Unadjusted,
> DateGeneration.Forward,
> >> >> > >> >> False)
> >> >> > >> >>
> >> >> > >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule
> , myindex,
> >> >> > >> >> Actual360()).cashflows()]
> >> >> > >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule
> , myindex,
> >> >> > >> >> Actual360()).cashflows()]
> >> >> > >> >>
> >> >> > >> >> ### [0.0, 2.5884898292778846, 100.0]
> >> >> > >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> >> >> > >> >>
> >> >> > >> >> To match the second coupon payment, I used below manual
> formula to
> >> >> > >> >> convert continuous compounding to semi-annual :
> >> >> > >> >>
> >> >> > >> >> (math.sqrt(math.exp(0.05)) - 1)*2 *
> Actual360().yearFraction(spots[1],
> >> >> > >> >> spots[2]) * 100
> >> >> > >> >> ### 2.5877678758305054
> >> >> > >> >>
> >> >> > >> >> With this, I got a better match, but still not exact. Should
> I make
> >> >> > >> >> any other adjustment?
> >> >> > >> >>
> >> >> > >> >> Appreciate your pointer.
> >> >> > >> >>
> >> >> > >> >> Thanks and regards,
> >> >> > >> >>
> >> >> > >> >> On Mon, 5 Apr 2021 at 04:08, Arkadiy Naumov <
> ark...@gm...> wrote:
> >> >> > >> >> >
> >> >> > >> >> > As far as the first zero - that's your extra fixing
> contributing. Either set it to 0.05 or create a custom index that does not
> have 2-days settlement, so you don't even have to worry about it.
> >> >> > >> >> > For the interest being slightly off - 0.05 is continuously
> compounded (you set your zero curve this way), but the bond resets to
> "simple" rate (which is higher, so the numbers make sense at least
> directionally)
> >> >> > >> >> >
> >> >> > >> >> > On Sun, Apr 4, 2021 at 4:09 AM Brian Smith <
> bri...@gm...> wrote:
> >> >> > >> >> >>
> >> >> > >> >> >> Thanks for your comments.
> >> >> > >> >> >>
> >> >> > >> >> >> But I still failed to understand the coupon payments at
> various coupon
> >> >> > >> >> >> dates. Below is my full example -
> >> >> > >> >> >>
> >> >> > >> >> >> from QuantLib import *
> >> >> > >> >> >>
> >> >> > >> >> >> mydate = Date(31, 1, 2018)
> >> >> > >> >> >>
> >> >> > >> >> >> Settings.instance().evaluationDate = mydate
> >> >> > >> >> >>
> >> >> > >> >> >> spots = [mydate, mydate + Period("6m"), mydate +
> Period("1y"), mydate
> >> >> > >> >> >> + Period("2y"), mydate + Period("3y")]
> >> >> > >> >> >> spotsdate = [0, 0.05, 0.05, 0.05, 0.05]
> >> >> > >> >> >>
> >> >> > >> >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots,
> spotsdate,
> >> >> > >> >> >> Actual360(), Canada(), Linear(), Continuous))
> >> >> > >> >> >>
> >> >> > >> >> >> myindex = Euribor6M(curveHandle)
> >> >> > >> >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> >> >> > >> >> >>
> >> >> > >> >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"),
> Period(6,
> >> >> > >> >> >> Months), Canada(), Unadjusted, Unadjusted,
> DateGeneration.Forward,
> >> >> > >> >> >> False)
> >> >> > >> >> >>
> >> >> > >> >> >> [c.amount() for c in FloatingRateBond(0, 100,
> bond_schedule , myindex,
> >> >> > >> >> >> Actual360()).cashflows()]
> >> >> > >> >> >> [c.date() for c in FloatingRateBond(0, 100,
> bond_schedule , myindex,
> >> >> > >> >> >> Actual360()).cashflows()]
> >> >> > >> >> >>
> >> >> > >> >> >> ### [0.0, 2.5884898292778846, 100.0]
> >> >> > >> >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> >> >> > >> >> >>
> >> >> > >> >> >> So I see on the 1st coupon date, QL is showing coupon
> payment as 0. Why?
> >> >> > >> >> >> And, on the last coupon date, coupon payment is
> 2.5884898292778846.
> >> >> > >> >> >> How this number is calculated? If I manually calculate
> this, I get
> >> >> > >> >> >> just a close match -
> >> >> > >> >> >>
> >> >> > >> >> >> 5 * Actual360().yearFraction(spots[1], spots[2])
> >> >> > >> >> >>
> >> >> > >> >> >> ### 2.5555555555555554
> >> >> > >> >> >>
> >> >> > >> >> >> Am I missing something?
> >> >> > >> >> >>
> >> >> > >> >> >> On Sun, 4 Apr 2021 at 03:27, Arkadiy Naumov <
> ark...@gm...> wrote:
> >> >> > >> >> >> >
> >> >> > >> >> >> > And as to the zeros - I may be wrong, but try
> explicitly setting the evaluationDate to whatever date you want to be your
> spot.
> >> >> > >> >> >> >
> >> >> > >> >> >> > On Sat, Apr 3, 2021 at 5:50 PM Arkadiy Naumov <
> ark...@gm...> wrote:
> >> >> > >> >> >> >>
> >> >> > >> >> >> >> Hi Brian,
> >> >> > >> >> >> >>
> >> >> > >> >> >> >> Without running your code - the reason Jan29th comes
> into play is because Euribor6M has a two days settlement built in:
> https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/eurlibor.cpp#L63
> >> >> > >> >> >> >>
> >> >> > >> >> >> >>
> >> >> > >> >> >> >> On Sat, Apr 3, 2021 at 10:22 AM Brian Smith <
> bri...@gm...> wrote:
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> Hi,
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> I found out that I have to add a dummy quote to get
> this work. So I added -
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> myindex = Euribor6M(curveHandle)
> >> >> > >> >> >> >>> myindex.addFixing(Date(27, 7, 2018), 0.00)
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> bond_schedule = Schedule(mydate,
> >> >> > >> >> >> >>> mydate + Period("1y"), Period(6, Months), Canada(),
> Unadjusted,
> >> >> > >> >> >> >>> Unadjusted, DateGeneration.Forward, False)
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> [c.amount() for c in FloatingRateBond(0, 10000,
> bond_schedule ,
> >> >> > >> >> >> >>> myindex, Actual360()).cashflows()]
> >> >> > >> >> >> >>> [c.date() for c in FloatingRateBond(0, 10000,
> bond_schedule , myindex,
> >> >> > >> >> >> >>> Actual360()).cashflows()]
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> However with this, I am getting strange result as all
> the coupon
> >> >> > >> >> >> >>> payments are coming as zero.
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> Can you please help me to understand what went wrong
> in my code?
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> On Sat, 3 Apr 2021 at 14:39, Brian Smith <
> bri...@gm...> wrote:
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > Hi,
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > I want to extract all the cash flow amounts from a
> bond as defined below -
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > from QuantLib import *
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > mydate = Date(31, 1, 2018)
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > spots = [mydate, mydate + Period("6m"), mydate +
> Period("1y"), mydate
> >> >> > >> >> >> >>> > + Period("2y"), mydate + Period("3y")]
> >> >> > >> >> >> >>> > spotsdate = [0, 0.25, 0.45, 0.65, 0.85]
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > curveHandle =
> YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
> >> >> > >> >> >> >>> > Actual360(), Canada(), Linear(), Continuous))
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > [c.amount() for c in FloatingRateBond(0, 10000,
> Schedule(mydate,
> >> >> > >> >> >> >>> > mydate + Period("1y"), Period(6, Months), Canada(),
> Unadjusted,
> >> >> > >> >> >> >>> > Unadjusted, DateGeneration.Forward, False) ,
> Euribor6M(curveHandle),
> >> >> > >> >> >> >>> > Actual360()).cashflows()]
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > However above code failed to achieve any result,
> but giving out below error -
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > Traceback (most recent call last):File "<stdin>",
> line 1, in
> >> >> > >> >> >> >>> > <module>File "<stdin>", line 1, in <listcomp>File
> >> >> > >> >> >> >>> >
> "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line
> >> >> > >> >> >> >>> > 9967, in amountreturn
> _QuantLib.CashFlow_amount(self)RuntimeError:
> >> >> > >> >> >> >>> > Missing Euribor6M Actual/360 fixing for January
> 29th, 2018
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > I wonder where the date January 29th, 2018 comes
> from and how to resolve this?
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > Any pointer will be highly appreciated.
> >> >> > >> >> >> >>> >
> >> >> > >> >> >> >>> > Thanks for your time.
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>>
> >> >> > >> >> >> >>> _______________________________________________
> >> >> > >> >> >> >>> 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
> >> >>
> >> >>
> >> >> _______________________________________________
> >> >> QuantLib-users mailing list
> >> >> Qua...@li...
> >> >> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: Brian S. <bri...@gm...> - 2021-04-07 08:01:18
|
Yes. That I get. But my question is why on Date(31,1,2018) I get rate
0.051194139707830454?
Should not I get 5%, because thats what I fixed manually for Date(29, 1, 2018)?
On Wed, 7 Apr 2021 at 13:26, David Duarte <nh...@gm...> wrote:
>
> Because spot[0] will not give you the fixing date, as the fixing date is 2 business days before the start of the accrual period.
>
> I believe Date(29, 1, 2018) is the fixing date for your first period and spot[0] would be Date(31,1,2018)
>
> On Wed, 7 Apr 2021 at 08:23, Brian Smith <bri...@gm...> wrote:
>>
>> Many thanks!
>>
>> However when I try to extract the Fixing rate for 31-01-2018, I get a
>> different value from 5% which I defined manually.
>>
>> >>> myindex.fixing(spots[0])
>> 0.051194139707830454
>>
>> However I already defined :
>>
>> myindex.addFixing(Date(29, 1, 2018), spotsdate[1], True)
>>
>> Given that next fixing will happen only on July-2018, should I expect
>> myindex.fixing(spots[0]) = 5%?
>>
>> Why am I seeing 0.051194139707830454?
>>
>> Thanks for your time.
>>
>> On Wed, 7 Apr 2021 at 11:42, Ponram Gopal <po...@gm...> wrote:
>> >
>> > The coupon payment amounts are based on the projected Euribor6M reset rates.
>> > 5% was added as the fixing for 29-Jan-2018. The next reset rate was projected based on the zero curve.
>> >
>> > myindex.fixing(Date(27,7,2018))
>> > Out[69]: 0.050644366225002097
>> >
>> > myindex.fixing(Date(27,7,2018))*Actual360().yearFraction(spots[1], spots[2]) * 100
>> > Out[72]: 2.5884898292778846
>> >
>> > The coupon amount of 2.5884898292778846 is based on the projected rate fixing on 27-Jul-2018.
>> >
>> > df1 = curveHandle.discount(Date(31,7,2018))
>> > df2 = curveHandle.discount(Date(31,1,2019))
>> > accrual_factor = Actual360().yearFraction(Date(31,7,2018),Date(31,1,2019))
>> > fwd_rate = ((df1/df2)-1)/accrual_factor
>> >
>> > fwd_rate
>> > Out[104]: 0.050644366225002097
>> >
>> > On Tue, Apr 6, 2021 at 2:17 PM Brian Smith <bri...@gm...> wrote:
>> >>
>> >> Hi all - I would really appreciate if someone points me why I see this
>> >> difference, although small, just to make sure I am not making any
>> >> trivial mistake.
>> >>
>> >> Thanks for your time.
>> >>
>> >> On Mon, 5 Apr 2021 at 15:48, Brian Smith <bri...@gm...> wrote:
>> >> >
>> >> > I see. Thanks for pointing this out.
>> >> >
>> >> > Coming back to the calculation of 2nd coupon, I did manual calculation
>> >> > given that in the yield curve construction, I choose continuous
>> >> > compounding -
>> >> >
>> >> > (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
>> >> > spots[2]) * 100
>> >> >
>> >> > This gives answer 2.5877678758305054
>> >> >
>> >> > Whereas, QL gives coupon payment as 2.5884898292778846
>> >> >
>> >> > So, I dont see any exact match. Is there any definitive reason for
>> >> > this? Or just due to floating point error?
>> >> >
>> >> > On Mon, 5 Apr 2021 at 15:32, David Duarte <nh...@gm...> wrote:
>> >> > >
>> >> > > Because the fixing date for that coupon is 29.01.2018 and you specified 0 for that fixing...
>> >> > >
>> >> > > Try changing this line, and the first coupon will have the rate you input:;
>> >> > >
>> >> > > myindex.addFixing(Date(29, 1, 2018), 0.0, True)
>> >> > >
>> >> > > On Mon, 5 Apr 2021 at 10:58, Brian Smith <bri...@gm...> wrote:
>> >> > >>
>> >> > >> Thanks.
>> >> > >>
>> >> > >> But still I dont have any clue what was wrong in below code?
>> >> > >>
>> >> > >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> >> > >> Actual360()).cashflows()]
>> >> > >>
>> >> > >> Why am I getting 0 here as first coupon?
>> >> > >>
>> >> > >> On Mon, 5 Apr 2021 at 15:11, David Duarte <nh...@gm...> wrote:
>> >> > >> >
>> >> > >> > The curve you are building takes continuous rates as inputs and uses linear interpolation of zero yields for non node points.
>> >> > >> > You could alternatively specify annually compounded rates as inputs.
>> >> > >> >
>> >> > >> >
>> >> > >> > In any case, you can inspect the cashflow details with ql.as_floating_coupon.
>> >> > >> >
>> >> > >> > Here is an example:
>> >> > >> >
>> >> > >> > bond = FloatingRateBond(0, 100, bond_schedule , myindex, Actual360())
>> >> > >> > interest_cashflows = [*map(as_floating_rate_coupon, bond.cashflows())][:-1]
>> >> > >> > rate = interest_cashflows[1].rate()
>> >> > >> > accrualDays = interest_cashflows[1].accrualDays()
>> >> > >> >
>> >> > >> > print("Floating rate:", rate)
>> >> > >> > print("Cashflow", 100 * rate * accrualDays/360)
>> >> > >> >
>> >> > >> >
>> >> > >> > # Floating rate: 0.050644366225002097
>> >> > >> > # Cashflow 2.588489829277885
>> >> > >> >
>> >> > >> >
>> >> > >> > On Mon, 5 Apr 2021 at 07:02, Brian Smith <bri...@gm...> wrote:
>> >> > >> >>
>> >> > >> >> Thanks again.
>> >> > >> >>
>> >> > >> >> Below is my modified code with 0 replaced by a dummy 0.05. But still I
>> >> > >> >> see 0 for first coupon payment.
>> >> > >> >>
>> >> > >> >> from QuantLib import *
>> >> > >> >>
>> >> > >> >> mydate = Date(31, 1, 2018)
>> >> > >> >>
>> >> > >> >> Settings.instance().evaluationDate = mydate
>> >> > >> >>
>> >> > >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
>> >> > >> >> + Period("2y"), mydate + Period("3y")]
>> >> > >> >> spotsdate = [0.05, 0.05, 0.05, 0.05, 0.05]
>> >> > >> >>
>> >> > >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
>> >> > >> >> Actual360(), Canada(), Linear(), Continuous))
>> >> > >> >>
>> >> > >> >> myindex = Euribor6M(curveHandle)
>> >> > >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
>> >> > >> >>
>> >> > >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"), Period(6,
>> >> > >> >> Months), Canada(), Unadjusted, Unadjusted, DateGeneration.Forward,
>> >> > >> >> False)
>> >> > >> >>
>> >> > >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> >> > >> >> Actual360()).cashflows()]
>> >> > >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> >> > >> >> Actual360()).cashflows()]
>> >> > >> >>
>> >> > >> >> ### [0.0, 2.5884898292778846, 100.0]
>> >> > >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
>> >> > >> >>
>> >> > >> >> To match the second coupon payment, I used below manual formula to
>> >> > >> >> convert continuous compounding to semi-annual :
>> >> > >> >>
>> >> > >> >> (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
>> >> > >> >> spots[2]) * 100
>> >> > >> >> ### 2.5877678758305054
>> >> > >> >>
>> >> > >> >> With this, I got a better match, but still not exact. Should I make
>> >> > >> >> any other adjustment?
>> >> > >> >>
>> >> > >> >> Appreciate your pointer.
>> >> > >> >>
>> >> > >> >> Thanks and regards,
>> >> > >> >>
>> >> > >> >> On Mon, 5 Apr 2021 at 04:08, Arkadiy Naumov <ark...@gm...> wrote:
>> >> > >> >> >
>> >> > >> >> > As far as the first zero - that's your extra fixing contributing. Either set it to 0.05 or create a custom index that does not have 2-days settlement, so you don't even have to worry about it.
>> >> > >> >> > For the interest being slightly off - 0.05 is continuously compounded (you set your zero curve this way), but the bond resets to "simple" rate (which is higher, so the numbers make sense at least directionally)
>> >> > >> >> >
>> >> > >> >> > On Sun, Apr 4, 2021 at 4:09 AM Brian Smith <bri...@gm...> wrote:
>> >> > >> >> >>
>> >> > >> >> >> Thanks for your comments.
>> >> > >> >> >>
>> >> > >> >> >> But I still failed to understand the coupon payments at various coupon
>> >> > >> >> >> dates. Below is my full example -
>> >> > >> >> >>
>> >> > >> >> >> from QuantLib import *
>> >> > >> >> >>
>> >> > >> >> >> mydate = Date(31, 1, 2018)
>> >> > >> >> >>
>> >> > >> >> >> Settings.instance().evaluationDate = mydate
>> >> > >> >> >>
>> >> > >> >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
>> >> > >> >> >> + Period("2y"), mydate + Period("3y")]
>> >> > >> >> >> spotsdate = [0, 0.05, 0.05, 0.05, 0.05]
>> >> > >> >> >>
>> >> > >> >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
>> >> > >> >> >> Actual360(), Canada(), Linear(), Continuous))
>> >> > >> >> >>
>> >> > >> >> >> myindex = Euribor6M(curveHandle)
>> >> > >> >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
>> >> > >> >> >>
>> >> > >> >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"), Period(6,
>> >> > >> >> >> Months), Canada(), Unadjusted, Unadjusted, DateGeneration.Forward,
>> >> > >> >> >> False)
>> >> > >> >> >>
>> >> > >> >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> >> > >> >> >> Actual360()).cashflows()]
>> >> > >> >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> >> > >> >> >> Actual360()).cashflows()]
>> >> > >> >> >>
>> >> > >> >> >> ### [0.0, 2.5884898292778846, 100.0]
>> >> > >> >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
>> >> > >> >> >>
>> >> > >> >> >> So I see on the 1st coupon date, QL is showing coupon payment as 0. Why?
>> >> > >> >> >> And, on the last coupon date, coupon payment is 2.5884898292778846.
>> >> > >> >> >> How this number is calculated? If I manually calculate this, I get
>> >> > >> >> >> just a close match -
>> >> > >> >> >>
>> >> > >> >> >> 5 * Actual360().yearFraction(spots[1], spots[2])
>> >> > >> >> >>
>> >> > >> >> >> ### 2.5555555555555554
>> >> > >> >> >>
>> >> > >> >> >> Am I missing something?
>> >> > >> >> >>
>> >> > >> >> >> On Sun, 4 Apr 2021 at 03:27, Arkadiy Naumov <ark...@gm...> wrote:
>> >> > >> >> >> >
>> >> > >> >> >> > And as to the zeros - I may be wrong, but try explicitly setting the evaluationDate to whatever date you want to be your spot.
>> >> > >> >> >> >
>> >> > >> >> >> > On Sat, Apr 3, 2021 at 5:50 PM Arkadiy Naumov <ark...@gm...> wrote:
>> >> > >> >> >> >>
>> >> > >> >> >> >> Hi Brian,
>> >> > >> >> >> >>
>> >> > >> >> >> >> Without running your code - the reason Jan29th comes into play is because Euribor6M has a two days settlement built in: https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/eurlibor.cpp#L63
>> >> > >> >> >> >>
>> >> > >> >> >> >>
>> >> > >> >> >> >> On Sat, Apr 3, 2021 at 10:22 AM Brian Smith <bri...@gm...> wrote:
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> Hi,
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> I found out that I have to add a dummy quote to get this work. So I added -
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> myindex = Euribor6M(curveHandle)
>> >> > >> >> >> >>> myindex.addFixing(Date(27, 7, 2018), 0.00)
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> bond_schedule = Schedule(mydate,
>> >> > >> >> >> >>> mydate + Period("1y"), Period(6, Months), Canada(), Unadjusted,
>> >> > >> >> >> >>> Unadjusted, DateGeneration.Forward, False)
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> [c.amount() for c in FloatingRateBond(0, 10000, bond_schedule ,
>> >> > >> >> >> >>> myindex, Actual360()).cashflows()]
>> >> > >> >> >> >>> [c.date() for c in FloatingRateBond(0, 10000, bond_schedule , myindex,
>> >> > >> >> >> >>> Actual360()).cashflows()]
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> However with this, I am getting strange result as all the coupon
>> >> > >> >> >> >>> payments are coming as zero.
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> Can you please help me to understand what went wrong in my code?
>> >> > >> >> >> >>>
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> On Sat, 3 Apr 2021 at 14:39, Brian Smith <bri...@gm...> wrote:
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > Hi,
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > I want to extract all the cash flow amounts from a bond as defined below -
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > from QuantLib import *
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > mydate = Date(31, 1, 2018)
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
>> >> > >> >> >> >>> > + Period("2y"), mydate + Period("3y")]
>> >> > >> >> >> >>> > spotsdate = [0, 0.25, 0.45, 0.65, 0.85]
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
>> >> > >> >> >> >>> > Actual360(), Canada(), Linear(), Continuous))
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > [c.amount() for c in FloatingRateBond(0, 10000, Schedule(mydate,
>> >> > >> >> >> >>> > mydate + Period("1y"), Period(6, Months), Canada(), Unadjusted,
>> >> > >> >> >> >>> > Unadjusted, DateGeneration.Forward, False) , Euribor6M(curveHandle),
>> >> > >> >> >> >>> > Actual360()).cashflows()]
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > However above code failed to achieve any result, but giving out below error -
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > Traceback (most recent call last):File "<stdin>", line 1, in
>> >> > >> >> >> >>> > <module>File "<stdin>", line 1, in <listcomp>File
>> >> > >> >> >> >>> > "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line
>> >> > >> >> >> >>> > 9967, in amountreturn _QuantLib.CashFlow_amount(self)RuntimeError:
>> >> > >> >> >> >>> > Missing Euribor6M Actual/360 fixing for January 29th, 2018
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > I wonder where the date January 29th, 2018 comes from and how to resolve this?
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > Any pointer will be highly appreciated.
>> >> > >> >> >> >>> >
>> >> > >> >> >> >>> > Thanks for your time.
>> >> > >> >> >> >>>
>> >> > >> >> >> >>>
>> >> > >> >> >> >>> _______________________________________________
>> >> > >> >> >> >>> 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
>> >>
>> >>
>> >> _______________________________________________
>> >> QuantLib-users mailing list
>> >> Qua...@li...
>> >> https://lists.sourceforge.net/lists/listinfo/quantlib-users
|
|
From: David D. <nh...@gm...> - 2021-04-07 07:56:41
|
Because spot[0] will not give you the fixing date, as the fixing date is 2
business days before the start of the accrual period.
I believe Date(29, 1, 2018) is the fixing date for your first period and
spot[0] would be Date(31,1,2018)
On Wed, 7 Apr 2021 at 08:23, Brian Smith <bri...@gm...> wrote:
> Many thanks!
>
> However when I try to extract the Fixing rate for 31-01-2018, I get a
> different value from 5% which I defined manually.
>
> >>> myindex.fixing(spots[0])
> 0.051194139707830454
>
> However I already defined :
>
> myindex.addFixing(Date(29, 1, 2018), spotsdate[1], True)
>
> Given that next fixing will happen only on July-2018, should I expect
> myindex.fixing(spots[0]) = 5%?
>
> Why am I seeing 0.051194139707830454?
>
> Thanks for your time.
>
> On Wed, 7 Apr 2021 at 11:42, Ponram Gopal <po...@gm...> wrote:
> >
> > The coupon payment amounts are based on the projected Euribor6M reset
> rates.
> > 5% was added as the fixing for 29-Jan-2018. The next reset rate was
> projected based on the zero curve.
> >
> > myindex.fixing(Date(27,7,2018))
> > Out[69]: 0.050644366225002097
> >
> > myindex.fixing(Date(27,7,2018))*Actual360().yearFraction(spots[1],
> spots[2]) * 100
> > Out[72]: 2.5884898292778846
> >
> > The coupon amount of 2.5884898292778846 is based on the projected rate
> fixing on 27-Jul-2018.
> >
> > df1 = curveHandle.discount(Date(31,7,2018))
> > df2 = curveHandle.discount(Date(31,1,2019))
> > accrual_factor =
> Actual360().yearFraction(Date(31,7,2018),Date(31,1,2019))
> > fwd_rate = ((df1/df2)-1)/accrual_factor
> >
> > fwd_rate
> > Out[104]: 0.050644366225002097
> >
> > On Tue, Apr 6, 2021 at 2:17 PM Brian Smith <bri...@gm...>
> wrote:
> >>
> >> Hi all - I would really appreciate if someone points me why I see this
> >> difference, although small, just to make sure I am not making any
> >> trivial mistake.
> >>
> >> Thanks for your time.
> >>
> >> On Mon, 5 Apr 2021 at 15:48, Brian Smith <bri...@gm...>
> wrote:
> >> >
> >> > I see. Thanks for pointing this out.
> >> >
> >> > Coming back to the calculation of 2nd coupon, I did manual calculation
> >> > given that in the yield curve construction, I choose continuous
> >> > compounding -
> >> >
> >> > (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
> >> > spots[2]) * 100
> >> >
> >> > This gives answer 2.5877678758305054
> >> >
> >> > Whereas, QL gives coupon payment as 2.5884898292778846
> >> >
> >> > So, I dont see any exact match. Is there any definitive reason for
> >> > this? Or just due to floating point error?
> >> >
> >> > On Mon, 5 Apr 2021 at 15:32, David Duarte <nh...@gm...> wrote:
> >> > >
> >> > > Because the fixing date for that coupon is 29.01.2018 and you
> specified 0 for that fixing...
> >> > >
> >> > > Try changing this line, and the first coupon will have the rate you
> input:;
> >> > >
> >> > > myindex.addFixing(Date(29, 1, 2018), 0.0, True)
> >> > >
> >> > > On Mon, 5 Apr 2021 at 10:58, Brian Smith <
> bri...@gm...> wrote:
> >> > >>
> >> > >> Thanks.
> >> > >>
> >> > >> But still I dont have any clue what was wrong in below code?
> >> > >>
> >> > >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> >> > >> Actual360()).cashflows()]
> >> > >>
> >> > >> Why am I getting 0 here as first coupon?
> >> > >>
> >> > >> On Mon, 5 Apr 2021 at 15:11, David Duarte <nh...@gm...>
> wrote:
> >> > >> >
> >> > >> > The curve you are building takes continuous rates as inputs and
> uses linear interpolation of zero yields for non node points.
> >> > >> > You could alternatively specify annually compounded rates as
> inputs.
> >> > >> >
> >> > >> >
> >> > >> > In any case, you can inspect the cashflow details with
> ql.as_floating_coupon.
> >> > >> >
> >> > >> > Here is an example:
> >> > >> >
> >> > >> > bond = FloatingRateBond(0, 100, bond_schedule , myindex,
> Actual360())
> >> > >> > interest_cashflows = [*map(as_floating_rate_coupon,
> bond.cashflows())][:-1]
> >> > >> > rate = interest_cashflows[1].rate()
> >> > >> > accrualDays = interest_cashflows[1].accrualDays()
> >> > >> >
> >> > >> > print("Floating rate:", rate)
> >> > >> > print("Cashflow", 100 * rate * accrualDays/360)
> >> > >> >
> >> > >> >
> >> > >> > # Floating rate: 0.050644366225002097
> >> > >> > # Cashflow 2.588489829277885
> >> > >> >
> >> > >> >
> >> > >> > On Mon, 5 Apr 2021 at 07:02, Brian Smith <
> bri...@gm...> wrote:
> >> > >> >>
> >> > >> >> Thanks again.
> >> > >> >>
> >> > >> >> Below is my modified code with 0 replaced by a dummy 0.05. But
> still I
> >> > >> >> see 0 for first coupon payment.
> >> > >> >>
> >> > >> >> from QuantLib import *
> >> > >> >>
> >> > >> >> mydate = Date(31, 1, 2018)
> >> > >> >>
> >> > >> >> Settings.instance().evaluationDate = mydate
> >> > >> >>
> >> > >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"),
> mydate
> >> > >> >> + Period("2y"), mydate + Period("3y")]
> >> > >> >> spotsdate = [0.05, 0.05, 0.05, 0.05, 0.05]
> >> > >> >>
> >> > >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots,
> spotsdate,
> >> > >> >> Actual360(), Canada(), Linear(), Continuous))
> >> > >> >>
> >> > >> >> myindex = Euribor6M(curveHandle)
> >> > >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> >> > >> >>
> >> > >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"),
> Period(6,
> >> > >> >> Months), Canada(), Unadjusted, Unadjusted,
> DateGeneration.Forward,
> >> > >> >> False)
> >> > >> >>
> >> > >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> >> > >> >> Actual360()).cashflows()]
> >> > >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> >> > >> >> Actual360()).cashflows()]
> >> > >> >>
> >> > >> >> ### [0.0, 2.5884898292778846, 100.0]
> >> > >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> >> > >> >>
> >> > >> >> To match the second coupon payment, I used below manual formula
> to
> >> > >> >> convert continuous compounding to semi-annual :
> >> > >> >>
> >> > >> >> (math.sqrt(math.exp(0.05)) - 1)*2 *
> Actual360().yearFraction(spots[1],
> >> > >> >> spots[2]) * 100
> >> > >> >> ### 2.5877678758305054
> >> > >> >>
> >> > >> >> With this, I got a better match, but still not exact. Should I
> make
> >> > >> >> any other adjustment?
> >> > >> >>
> >> > >> >> Appreciate your pointer.
> >> > >> >>
> >> > >> >> Thanks and regards,
> >> > >> >>
> >> > >> >> On Mon, 5 Apr 2021 at 04:08, Arkadiy Naumov <
> ark...@gm...> wrote:
> >> > >> >> >
> >> > >> >> > As far as the first zero - that's your extra fixing
> contributing. Either set it to 0.05 or create a custom index that does not
> have 2-days settlement, so you don't even have to worry about it.
> >> > >> >> > For the interest being slightly off - 0.05 is continuously
> compounded (you set your zero curve this way), but the bond resets to
> "simple" rate (which is higher, so the numbers make sense at least
> directionally)
> >> > >> >> >
> >> > >> >> > On Sun, Apr 4, 2021 at 4:09 AM Brian Smith <
> bri...@gm...> wrote:
> >> > >> >> >>
> >> > >> >> >> Thanks for your comments.
> >> > >> >> >>
> >> > >> >> >> But I still failed to understand the coupon payments at
> various coupon
> >> > >> >> >> dates. Below is my full example -
> >> > >> >> >>
> >> > >> >> >> from QuantLib import *
> >> > >> >> >>
> >> > >> >> >> mydate = Date(31, 1, 2018)
> >> > >> >> >>
> >> > >> >> >> Settings.instance().evaluationDate = mydate
> >> > >> >> >>
> >> > >> >> >> spots = [mydate, mydate + Period("6m"), mydate +
> Period("1y"), mydate
> >> > >> >> >> + Period("2y"), mydate + Period("3y")]
> >> > >> >> >> spotsdate = [0, 0.05, 0.05, 0.05, 0.05]
> >> > >> >> >>
> >> > >> >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots,
> spotsdate,
> >> > >> >> >> Actual360(), Canada(), Linear(), Continuous))
> >> > >> >> >>
> >> > >> >> >> myindex = Euribor6M(curveHandle)
> >> > >> >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> >> > >> >> >>
> >> > >> >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"),
> Period(6,
> >> > >> >> >> Months), Canada(), Unadjusted, Unadjusted,
> DateGeneration.Forward,
> >> > >> >> >> False)
> >> > >> >> >>
> >> > >> >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule
> , myindex,
> >> > >> >> >> Actual360()).cashflows()]
> >> > >> >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule
> , myindex,
> >> > >> >> >> Actual360()).cashflows()]
> >> > >> >> >>
> >> > >> >> >> ### [0.0, 2.5884898292778846, 100.0]
> >> > >> >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> >> > >> >> >>
> >> > >> >> >> So I see on the 1st coupon date, QL is showing coupon
> payment as 0. Why?
> >> > >> >> >> And, on the last coupon date, coupon payment is
> 2.5884898292778846.
> >> > >> >> >> How this number is calculated? If I manually calculate this,
> I get
> >> > >> >> >> just a close match -
> >> > >> >> >>
> >> > >> >> >> 5 * Actual360().yearFraction(spots[1], spots[2])
> >> > >> >> >>
> >> > >> >> >> ### 2.5555555555555554
> >> > >> >> >>
> >> > >> >> >> Am I missing something?
> >> > >> >> >>
> >> > >> >> >> On Sun, 4 Apr 2021 at 03:27, Arkadiy Naumov <
> ark...@gm...> wrote:
> >> > >> >> >> >
> >> > >> >> >> > And as to the zeros - I may be wrong, but try explicitly
> setting the evaluationDate to whatever date you want to be your spot.
> >> > >> >> >> >
> >> > >> >> >> > On Sat, Apr 3, 2021 at 5:50 PM Arkadiy Naumov <
> ark...@gm...> wrote:
> >> > >> >> >> >>
> >> > >> >> >> >> Hi Brian,
> >> > >> >> >> >>
> >> > >> >> >> >> Without running your code - the reason Jan29th comes into
> play is because Euribor6M has a two days settlement built in:
> https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/eurlibor.cpp#L63
> >> > >> >> >> >>
> >> > >> >> >> >>
> >> > >> >> >> >> On Sat, Apr 3, 2021 at 10:22 AM Brian Smith <
> bri...@gm...> wrote:
> >> > >> >> >> >>>
> >> > >> >> >> >>> Hi,
> >> > >> >> >> >>>
> >> > >> >> >> >>> I found out that I have to add a dummy quote to get this
> work. So I added -
> >> > >> >> >> >>>
> >> > >> >> >> >>> myindex = Euribor6M(curveHandle)
> >> > >> >> >> >>> myindex.addFixing(Date(27, 7, 2018), 0.00)
> >> > >> >> >> >>>
> >> > >> >> >> >>> bond_schedule = Schedule(mydate,
> >> > >> >> >> >>> mydate + Period("1y"), Period(6, Months), Canada(),
> Unadjusted,
> >> > >> >> >> >>> Unadjusted, DateGeneration.Forward, False)
> >> > >> >> >> >>>
> >> > >> >> >> >>> [c.amount() for c in FloatingRateBond(0, 10000,
> bond_schedule ,
> >> > >> >> >> >>> myindex, Actual360()).cashflows()]
> >> > >> >> >> >>> [c.date() for c in FloatingRateBond(0, 10000,
> bond_schedule , myindex,
> >> > >> >> >> >>> Actual360()).cashflows()]
> >> > >> >> >> >>>
> >> > >> >> >> >>> However with this, I am getting strange result as all
> the coupon
> >> > >> >> >> >>> payments are coming as zero.
> >> > >> >> >> >>>
> >> > >> >> >> >>> Can you please help me to understand what went wrong in
> my code?
> >> > >> >> >> >>>
> >> > >> >> >> >>>
> >> > >> >> >> >>> On Sat, 3 Apr 2021 at 14:39, Brian Smith <
> bri...@gm...> wrote:
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > Hi,
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > I want to extract all the cash flow amounts from a
> bond as defined below -
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > from QuantLib import *
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > mydate = Date(31, 1, 2018)
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > spots = [mydate, mydate + Period("6m"), mydate +
> Period("1y"), mydate
> >> > >> >> >> >>> > + Period("2y"), mydate + Period("3y")]
> >> > >> >> >> >>> > spotsdate = [0, 0.25, 0.45, 0.65, 0.85]
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > curveHandle =
> YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
> >> > >> >> >> >>> > Actual360(), Canada(), Linear(), Continuous))
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > [c.amount() for c in FloatingRateBond(0, 10000,
> Schedule(mydate,
> >> > >> >> >> >>> > mydate + Period("1y"), Period(6, Months), Canada(),
> Unadjusted,
> >> > >> >> >> >>> > Unadjusted, DateGeneration.Forward, False) ,
> Euribor6M(curveHandle),
> >> > >> >> >> >>> > Actual360()).cashflows()]
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > However above code failed to achieve any result, but
> giving out below error -
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > Traceback (most recent call last):File "<stdin>", line
> 1, in
> >> > >> >> >> >>> > <module>File "<stdin>", line 1, in <listcomp>File
> >> > >> >> >> >>> >
> "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line
> >> > >> >> >> >>> > 9967, in amountreturn
> _QuantLib.CashFlow_amount(self)RuntimeError:
> >> > >> >> >> >>> > Missing Euribor6M Actual/360 fixing for January 29th,
> 2018
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > I wonder where the date January 29th, 2018 comes from
> and how to resolve this?
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > Any pointer will be highly appreciated.
> >> > >> >> >> >>> >
> >> > >> >> >> >>> > Thanks for your time.
> >> > >> >> >> >>>
> >> > >> >> >> >>>
> >> > >> >> >> >>> _______________________________________________
> >> > >> >> >> >>> 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
> >>
> >>
> >> _______________________________________________
> >> QuantLib-users mailing list
> >> Qua...@li...
> >> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: Brian S. <bri...@gm...> - 2021-04-07 07:23:32
|
Many thanks!
However when I try to extract the Fixing rate for 31-01-2018, I get a
different value from 5% which I defined manually.
>>> myindex.fixing(spots[0])
0.051194139707830454
However I already defined :
myindex.addFixing(Date(29, 1, 2018), spotsdate[1], True)
Given that next fixing will happen only on July-2018, should I expect
myindex.fixing(spots[0]) = 5%?
Why am I seeing 0.051194139707830454?
Thanks for your time.
On Wed, 7 Apr 2021 at 11:42, Ponram Gopal <po...@gm...> wrote:
>
> The coupon payment amounts are based on the projected Euribor6M reset rates.
> 5% was added as the fixing for 29-Jan-2018. The next reset rate was projected based on the zero curve.
>
> myindex.fixing(Date(27,7,2018))
> Out[69]: 0.050644366225002097
>
> myindex.fixing(Date(27,7,2018))*Actual360().yearFraction(spots[1], spots[2]) * 100
> Out[72]: 2.5884898292778846
>
> The coupon amount of 2.5884898292778846 is based on the projected rate fixing on 27-Jul-2018.
>
> df1 = curveHandle.discount(Date(31,7,2018))
> df2 = curveHandle.discount(Date(31,1,2019))
> accrual_factor = Actual360().yearFraction(Date(31,7,2018),Date(31,1,2019))
> fwd_rate = ((df1/df2)-1)/accrual_factor
>
> fwd_rate
> Out[104]: 0.050644366225002097
>
> On Tue, Apr 6, 2021 at 2:17 PM Brian Smith <bri...@gm...> wrote:
>>
>> Hi all - I would really appreciate if someone points me why I see this
>> difference, although small, just to make sure I am not making any
>> trivial mistake.
>>
>> Thanks for your time.
>>
>> On Mon, 5 Apr 2021 at 15:48, Brian Smith <bri...@gm...> wrote:
>> >
>> > I see. Thanks for pointing this out.
>> >
>> > Coming back to the calculation of 2nd coupon, I did manual calculation
>> > given that in the yield curve construction, I choose continuous
>> > compounding -
>> >
>> > (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
>> > spots[2]) * 100
>> >
>> > This gives answer 2.5877678758305054
>> >
>> > Whereas, QL gives coupon payment as 2.5884898292778846
>> >
>> > So, I dont see any exact match. Is there any definitive reason for
>> > this? Or just due to floating point error?
>> >
>> > On Mon, 5 Apr 2021 at 15:32, David Duarte <nh...@gm...> wrote:
>> > >
>> > > Because the fixing date for that coupon is 29.01.2018 and you specified 0 for that fixing...
>> > >
>> > > Try changing this line, and the first coupon will have the rate you input:;
>> > >
>> > > myindex.addFixing(Date(29, 1, 2018), 0.0, True)
>> > >
>> > > On Mon, 5 Apr 2021 at 10:58, Brian Smith <bri...@gm...> wrote:
>> > >>
>> > >> Thanks.
>> > >>
>> > >> But still I dont have any clue what was wrong in below code?
>> > >>
>> > >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> > >> Actual360()).cashflows()]
>> > >>
>> > >> Why am I getting 0 here as first coupon?
>> > >>
>> > >> On Mon, 5 Apr 2021 at 15:11, David Duarte <nh...@gm...> wrote:
>> > >> >
>> > >> > The curve you are building takes continuous rates as inputs and uses linear interpolation of zero yields for non node points.
>> > >> > You could alternatively specify annually compounded rates as inputs.
>> > >> >
>> > >> >
>> > >> > In any case, you can inspect the cashflow details with ql.as_floating_coupon.
>> > >> >
>> > >> > Here is an example:
>> > >> >
>> > >> > bond = FloatingRateBond(0, 100, bond_schedule , myindex, Actual360())
>> > >> > interest_cashflows = [*map(as_floating_rate_coupon, bond.cashflows())][:-1]
>> > >> > rate = interest_cashflows[1].rate()
>> > >> > accrualDays = interest_cashflows[1].accrualDays()
>> > >> >
>> > >> > print("Floating rate:", rate)
>> > >> > print("Cashflow", 100 * rate * accrualDays/360)
>> > >> >
>> > >> >
>> > >> > # Floating rate: 0.050644366225002097
>> > >> > # Cashflow 2.588489829277885
>> > >> >
>> > >> >
>> > >> > On Mon, 5 Apr 2021 at 07:02, Brian Smith <bri...@gm...> wrote:
>> > >> >>
>> > >> >> Thanks again.
>> > >> >>
>> > >> >> Below is my modified code with 0 replaced by a dummy 0.05. But still I
>> > >> >> see 0 for first coupon payment.
>> > >> >>
>> > >> >> from QuantLib import *
>> > >> >>
>> > >> >> mydate = Date(31, 1, 2018)
>> > >> >>
>> > >> >> Settings.instance().evaluationDate = mydate
>> > >> >>
>> > >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
>> > >> >> + Period("2y"), mydate + Period("3y")]
>> > >> >> spotsdate = [0.05, 0.05, 0.05, 0.05, 0.05]
>> > >> >>
>> > >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
>> > >> >> Actual360(), Canada(), Linear(), Continuous))
>> > >> >>
>> > >> >> myindex = Euribor6M(curveHandle)
>> > >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
>> > >> >>
>> > >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"), Period(6,
>> > >> >> Months), Canada(), Unadjusted, Unadjusted, DateGeneration.Forward,
>> > >> >> False)
>> > >> >>
>> > >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> > >> >> Actual360()).cashflows()]
>> > >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> > >> >> Actual360()).cashflows()]
>> > >> >>
>> > >> >> ### [0.0, 2.5884898292778846, 100.0]
>> > >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
>> > >> >>
>> > >> >> To match the second coupon payment, I used below manual formula to
>> > >> >> convert continuous compounding to semi-annual :
>> > >> >>
>> > >> >> (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
>> > >> >> spots[2]) * 100
>> > >> >> ### 2.5877678758305054
>> > >> >>
>> > >> >> With this, I got a better match, but still not exact. Should I make
>> > >> >> any other adjustment?
>> > >> >>
>> > >> >> Appreciate your pointer.
>> > >> >>
>> > >> >> Thanks and regards,
>> > >> >>
>> > >> >> On Mon, 5 Apr 2021 at 04:08, Arkadiy Naumov <ark...@gm...> wrote:
>> > >> >> >
>> > >> >> > As far as the first zero - that's your extra fixing contributing. Either set it to 0.05 or create a custom index that does not have 2-days settlement, so you don't even have to worry about it.
>> > >> >> > For the interest being slightly off - 0.05 is continuously compounded (you set your zero curve this way), but the bond resets to "simple" rate (which is higher, so the numbers make sense at least directionally)
>> > >> >> >
>> > >> >> > On Sun, Apr 4, 2021 at 4:09 AM Brian Smith <bri...@gm...> wrote:
>> > >> >> >>
>> > >> >> >> Thanks for your comments.
>> > >> >> >>
>> > >> >> >> But I still failed to understand the coupon payments at various coupon
>> > >> >> >> dates. Below is my full example -
>> > >> >> >>
>> > >> >> >> from QuantLib import *
>> > >> >> >>
>> > >> >> >> mydate = Date(31, 1, 2018)
>> > >> >> >>
>> > >> >> >> Settings.instance().evaluationDate = mydate
>> > >> >> >>
>> > >> >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
>> > >> >> >> + Period("2y"), mydate + Period("3y")]
>> > >> >> >> spotsdate = [0, 0.05, 0.05, 0.05, 0.05]
>> > >> >> >>
>> > >> >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
>> > >> >> >> Actual360(), Canada(), Linear(), Continuous))
>> > >> >> >>
>> > >> >> >> myindex = Euribor6M(curveHandle)
>> > >> >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
>> > >> >> >>
>> > >> >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"), Period(6,
>> > >> >> >> Months), Canada(), Unadjusted, Unadjusted, DateGeneration.Forward,
>> > >> >> >> False)
>> > >> >> >>
>> > >> >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> > >> >> >> Actual360()).cashflows()]
>> > >> >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
>> > >> >> >> Actual360()).cashflows()]
>> > >> >> >>
>> > >> >> >> ### [0.0, 2.5884898292778846, 100.0]
>> > >> >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
>> > >> >> >>
>> > >> >> >> So I see on the 1st coupon date, QL is showing coupon payment as 0. Why?
>> > >> >> >> And, on the last coupon date, coupon payment is 2.5884898292778846.
>> > >> >> >> How this number is calculated? If I manually calculate this, I get
>> > >> >> >> just a close match -
>> > >> >> >>
>> > >> >> >> 5 * Actual360().yearFraction(spots[1], spots[2])
>> > >> >> >>
>> > >> >> >> ### 2.5555555555555554
>> > >> >> >>
>> > >> >> >> Am I missing something?
>> > >> >> >>
>> > >> >> >> On Sun, 4 Apr 2021 at 03:27, Arkadiy Naumov <ark...@gm...> wrote:
>> > >> >> >> >
>> > >> >> >> > And as to the zeros - I may be wrong, but try explicitly setting the evaluationDate to whatever date you want to be your spot.
>> > >> >> >> >
>> > >> >> >> > On Sat, Apr 3, 2021 at 5:50 PM Arkadiy Naumov <ark...@gm...> wrote:
>> > >> >> >> >>
>> > >> >> >> >> Hi Brian,
>> > >> >> >> >>
>> > >> >> >> >> Without running your code - the reason Jan29th comes into play is because Euribor6M has a two days settlement built in: https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/eurlibor.cpp#L63
>> > >> >> >> >>
>> > >> >> >> >>
>> > >> >> >> >> On Sat, Apr 3, 2021 at 10:22 AM Brian Smith <bri...@gm...> wrote:
>> > >> >> >> >>>
>> > >> >> >> >>> Hi,
>> > >> >> >> >>>
>> > >> >> >> >>> I found out that I have to add a dummy quote to get this work. So I added -
>> > >> >> >> >>>
>> > >> >> >> >>> myindex = Euribor6M(curveHandle)
>> > >> >> >> >>> myindex.addFixing(Date(27, 7, 2018), 0.00)
>> > >> >> >> >>>
>> > >> >> >> >>> bond_schedule = Schedule(mydate,
>> > >> >> >> >>> mydate + Period("1y"), Period(6, Months), Canada(), Unadjusted,
>> > >> >> >> >>> Unadjusted, DateGeneration.Forward, False)
>> > >> >> >> >>>
>> > >> >> >> >>> [c.amount() for c in FloatingRateBond(0, 10000, bond_schedule ,
>> > >> >> >> >>> myindex, Actual360()).cashflows()]
>> > >> >> >> >>> [c.date() for c in FloatingRateBond(0, 10000, bond_schedule , myindex,
>> > >> >> >> >>> Actual360()).cashflows()]
>> > >> >> >> >>>
>> > >> >> >> >>> However with this, I am getting strange result as all the coupon
>> > >> >> >> >>> payments are coming as zero.
>> > >> >> >> >>>
>> > >> >> >> >>> Can you please help me to understand what went wrong in my code?
>> > >> >> >> >>>
>> > >> >> >> >>>
>> > >> >> >> >>> On Sat, 3 Apr 2021 at 14:39, Brian Smith <bri...@gm...> wrote:
>> > >> >> >> >>> >
>> > >> >> >> >>> > Hi,
>> > >> >> >> >>> >
>> > >> >> >> >>> > I want to extract all the cash flow amounts from a bond as defined below -
>> > >> >> >> >>> >
>> > >> >> >> >>> > from QuantLib import *
>> > >> >> >> >>> >
>> > >> >> >> >>> > mydate = Date(31, 1, 2018)
>> > >> >> >> >>> >
>> > >> >> >> >>> > spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
>> > >> >> >> >>> > + Period("2y"), mydate + Period("3y")]
>> > >> >> >> >>> > spotsdate = [0, 0.25, 0.45, 0.65, 0.85]
>> > >> >> >> >>> >
>> > >> >> >> >>> > curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
>> > >> >> >> >>> > Actual360(), Canada(), Linear(), Continuous))
>> > >> >> >> >>> >
>> > >> >> >> >>> > [c.amount() for c in FloatingRateBond(0, 10000, Schedule(mydate,
>> > >> >> >> >>> > mydate + Period("1y"), Period(6, Months), Canada(), Unadjusted,
>> > >> >> >> >>> > Unadjusted, DateGeneration.Forward, False) , Euribor6M(curveHandle),
>> > >> >> >> >>> > Actual360()).cashflows()]
>> > >> >> >> >>> >
>> > >> >> >> >>> > However above code failed to achieve any result, but giving out below error -
>> > >> >> >> >>> >
>> > >> >> >> >>> > Traceback (most recent call last):File "<stdin>", line 1, in
>> > >> >> >> >>> > <module>File "<stdin>", line 1, in <listcomp>File
>> > >> >> >> >>> > "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line
>> > >> >> >> >>> > 9967, in amountreturn _QuantLib.CashFlow_amount(self)RuntimeError:
>> > >> >> >> >>> > Missing Euribor6M Actual/360 fixing for January 29th, 2018
>> > >> >> >> >>> >
>> > >> >> >> >>> > I wonder where the date January 29th, 2018 comes from and how to resolve this?
>> > >> >> >> >>> >
>> > >> >> >> >>> > Any pointer will be highly appreciated.
>> > >> >> >> >>> >
>> > >> >> >> >>> > Thanks for your time.
>> > >> >> >> >>>
>> > >> >> >> >>>
>> > >> >> >> >>> _______________________________________________
>> > >> >> >> >>> 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
>>
>>
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li...
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
|
|
From: Ponram G. <po...@gm...> - 2021-04-07 06:12:50
|
The coupon payment amounts are based on the projected Euribor6M reset
rates.
5% was added as the fixing for 29-Jan-2018. The next reset rate was
projected based on the zero curve.
myindex.fixing(Date(27,7,2018))
Out[69]: 0.050644366225002097
myindex.fixing(Date(27,7,2018))*Actual360().yearFraction(spots[1],
spots[2]) * 100
Out[72]: 2.5884898292778846
The coupon amount of 2.5884898292778846 is based on the projected rate
fixing on 27-Jul-2018.
df1 = curveHandle.discount(Date(31,7,2018))
df2 = curveHandle.discount(Date(31,1,2019))
accrual_factor = Actual360().yearFraction(Date(31,7,2018),Date(31,1,2019))
fwd_rate = ((df1/df2)-1)/accrual_factor
fwd_rate
Out[104]: 0.050644366225002097
On Tue, Apr 6, 2021 at 2:17 PM Brian Smith <bri...@gm...>
wrote:
> Hi all - I would really appreciate if someone points me why I see this
> difference, although small, just to make sure I am not making any
> trivial mistake.
>
> Thanks for your time.
>
> On Mon, 5 Apr 2021 at 15:48, Brian Smith <bri...@gm...>
> wrote:
> >
> > I see. Thanks for pointing this out.
> >
> > Coming back to the calculation of 2nd coupon, I did manual calculation
> > given that in the yield curve construction, I choose continuous
> > compounding -
> >
> > (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
> > spots[2]) * 100
> >
> > This gives answer 2.5877678758305054
> >
> > Whereas, QL gives coupon payment as 2.5884898292778846
> >
> > So, I dont see any exact match. Is there any definitive reason for
> > this? Or just due to floating point error?
> >
> > On Mon, 5 Apr 2021 at 15:32, David Duarte <nh...@gm...> wrote:
> > >
> > > Because the fixing date for that coupon is 29.01.2018 and you
> specified 0 for that fixing...
> > >
> > > Try changing this line, and the first coupon will have the rate you
> input:;
> > >
> > > myindex.addFixing(Date(29, 1, 2018), 0.0, True)
> > >
> > > On Mon, 5 Apr 2021 at 10:58, Brian Smith <bri...@gm...>
> wrote:
> > >>
> > >> Thanks.
> > >>
> > >> But still I dont have any clue what was wrong in below code?
> > >>
> > >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
> > >> Actual360()).cashflows()]
> > >>
> > >> Why am I getting 0 here as first coupon?
> > >>
> > >> On Mon, 5 Apr 2021 at 15:11, David Duarte <nh...@gm...> wrote:
> > >> >
> > >> > The curve you are building takes continuous rates as inputs and
> uses linear interpolation of zero yields for non node points.
> > >> > You could alternatively specify annually compounded rates as inputs.
> > >> >
> > >> >
> > >> > In any case, you can inspect the cashflow details with
> ql.as_floating_coupon.
> > >> >
> > >> > Here is an example:
> > >> >
> > >> > bond = FloatingRateBond(0, 100, bond_schedule , myindex,
> Actual360())
> > >> > interest_cashflows = [*map(as_floating_rate_coupon,
> bond.cashflows())][:-1]
> > >> > rate = interest_cashflows[1].rate()
> > >> > accrualDays = interest_cashflows[1].accrualDays()
> > >> >
> > >> > print("Floating rate:", rate)
> > >> > print("Cashflow", 100 * rate * accrualDays/360)
> > >> >
> > >> >
> > >> > # Floating rate: 0.050644366225002097
> > >> > # Cashflow 2.588489829277885
> > >> >
> > >> >
> > >> > On Mon, 5 Apr 2021 at 07:02, Brian Smith <
> bri...@gm...> wrote:
> > >> >>
> > >> >> Thanks again.
> > >> >>
> > >> >> Below is my modified code with 0 replaced by a dummy 0.05. But
> still I
> > >> >> see 0 for first coupon payment.
> > >> >>
> > >> >> from QuantLib import *
> > >> >>
> > >> >> mydate = Date(31, 1, 2018)
> > >> >>
> > >> >> Settings.instance().evaluationDate = mydate
> > >> >>
> > >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"),
> mydate
> > >> >> + Period("2y"), mydate + Period("3y")]
> > >> >> spotsdate = [0.05, 0.05, 0.05, 0.05, 0.05]
> > >> >>
> > >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
> > >> >> Actual360(), Canada(), Linear(), Continuous))
> > >> >>
> > >> >> myindex = Euribor6M(curveHandle)
> > >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> > >> >>
> > >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"), Period(6,
> > >> >> Months), Canada(), Unadjusted, Unadjusted, DateGeneration.Forward,
> > >> >> False)
> > >> >>
> > >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> > >> >> Actual360()).cashflows()]
> > >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> > >> >> Actual360()).cashflows()]
> > >> >>
> > >> >> ### [0.0, 2.5884898292778846, 100.0]
> > >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> > >> >>
> > >> >> To match the second coupon payment, I used below manual formula to
> > >> >> convert continuous compounding to semi-annual :
> > >> >>
> > >> >> (math.sqrt(math.exp(0.05)) - 1)*2 *
> Actual360().yearFraction(spots[1],
> > >> >> spots[2]) * 100
> > >> >> ### 2.5877678758305054
> > >> >>
> > >> >> With this, I got a better match, but still not exact. Should I make
> > >> >> any other adjustment?
> > >> >>
> > >> >> Appreciate your pointer.
> > >> >>
> > >> >> Thanks and regards,
> > >> >>
> > >> >> On Mon, 5 Apr 2021 at 04:08, Arkadiy Naumov <
> ark...@gm...> wrote:
> > >> >> >
> > >> >> > As far as the first zero - that's your extra fixing
> contributing. Either set it to 0.05 or create a custom index that does not
> have 2-days settlement, so you don't even have to worry about it.
> > >> >> > For the interest being slightly off - 0.05 is continuously
> compounded (you set your zero curve this way), but the bond resets to
> "simple" rate (which is higher, so the numbers make sense at least
> directionally)
> > >> >> >
> > >> >> > On Sun, Apr 4, 2021 at 4:09 AM Brian Smith <
> bri...@gm...> wrote:
> > >> >> >>
> > >> >> >> Thanks for your comments.
> > >> >> >>
> > >> >> >> But I still failed to understand the coupon payments at various
> coupon
> > >> >> >> dates. Below is my full example -
> > >> >> >>
> > >> >> >> from QuantLib import *
> > >> >> >>
> > >> >> >> mydate = Date(31, 1, 2018)
> > >> >> >>
> > >> >> >> Settings.instance().evaluationDate = mydate
> > >> >> >>
> > >> >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"),
> mydate
> > >> >> >> + Period("2y"), mydate + Period("3y")]
> > >> >> >> spotsdate = [0, 0.05, 0.05, 0.05, 0.05]
> > >> >> >>
> > >> >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots,
> spotsdate,
> > >> >> >> Actual360(), Canada(), Linear(), Continuous))
> > >> >> >>
> > >> >> >> myindex = Euribor6M(curveHandle)
> > >> >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> > >> >> >>
> > >> >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"),
> Period(6,
> > >> >> >> Months), Canada(), Unadjusted, Unadjusted,
> DateGeneration.Forward,
> > >> >> >> False)
> > >> >> >>
> > >> >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> > >> >> >> Actual360()).cashflows()]
> > >> >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule ,
> myindex,
> > >> >> >> Actual360()).cashflows()]
> > >> >> >>
> > >> >> >> ### [0.0, 2.5884898292778846, 100.0]
> > >> >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> > >> >> >>
> > >> >> >> So I see on the 1st coupon date, QL is showing coupon payment
> as 0. Why?
> > >> >> >> And, on the last coupon date, coupon payment is
> 2.5884898292778846.
> > >> >> >> How this number is calculated? If I manually calculate this, I
> get
> > >> >> >> just a close match -
> > >> >> >>
> > >> >> >> 5 * Actual360().yearFraction(spots[1], spots[2])
> > >> >> >>
> > >> >> >> ### 2.5555555555555554
> > >> >> >>
> > >> >> >> Am I missing something?
> > >> >> >>
> > >> >> >> On Sun, 4 Apr 2021 at 03:27, Arkadiy Naumov <
> ark...@gm...> wrote:
> > >> >> >> >
> > >> >> >> > And as to the zeros - I may be wrong, but try explicitly
> setting the evaluationDate to whatever date you want to be your spot.
> > >> >> >> >
> > >> >> >> > On Sat, Apr 3, 2021 at 5:50 PM Arkadiy Naumov <
> ark...@gm...> wrote:
> > >> >> >> >>
> > >> >> >> >> Hi Brian,
> > >> >> >> >>
> > >> >> >> >> Without running your code - the reason Jan29th comes into
> play is because Euribor6M has a two days settlement built in:
> https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/eurlibor.cpp#L63
> > >> >> >> >>
> > >> >> >> >>
> > >> >> >> >> On Sat, Apr 3, 2021 at 10:22 AM Brian Smith <
> bri...@gm...> wrote:
> > >> >> >> >>>
> > >> >> >> >>> Hi,
> > >> >> >> >>>
> > >> >> >> >>> I found out that I have to add a dummy quote to get this
> work. So I added -
> > >> >> >> >>>
> > >> >> >> >>> myindex = Euribor6M(curveHandle)
> > >> >> >> >>> myindex.addFixing(Date(27, 7, 2018), 0.00)
> > >> >> >> >>>
> > >> >> >> >>> bond_schedule = Schedule(mydate,
> > >> >> >> >>> mydate + Period("1y"), Period(6, Months), Canada(),
> Unadjusted,
> > >> >> >> >>> Unadjusted, DateGeneration.Forward, False)
> > >> >> >> >>>
> > >> >> >> >>> [c.amount() for c in FloatingRateBond(0, 10000,
> bond_schedule ,
> > >> >> >> >>> myindex, Actual360()).cashflows()]
> > >> >> >> >>> [c.date() for c in FloatingRateBond(0, 10000, bond_schedule
> , myindex,
> > >> >> >> >>> Actual360()).cashflows()]
> > >> >> >> >>>
> > >> >> >> >>> However with this, I am getting strange result as all the
> coupon
> > >> >> >> >>> payments are coming as zero.
> > >> >> >> >>>
> > >> >> >> >>> Can you please help me to understand what went wrong in my
> code?
> > >> >> >> >>>
> > >> >> >> >>>
> > >> >> >> >>> On Sat, 3 Apr 2021 at 14:39, Brian Smith <
> bri...@gm...> wrote:
> > >> >> >> >>> >
> > >> >> >> >>> > Hi,
> > >> >> >> >>> >
> > >> >> >> >>> > I want to extract all the cash flow amounts from a bond
> as defined below -
> > >> >> >> >>> >
> > >> >> >> >>> > from QuantLib import *
> > >> >> >> >>> >
> > >> >> >> >>> > mydate = Date(31, 1, 2018)
> > >> >> >> >>> >
> > >> >> >> >>> > spots = [mydate, mydate + Period("6m"), mydate +
> Period("1y"), mydate
> > >> >> >> >>> > + Period("2y"), mydate + Period("3y")]
> > >> >> >> >>> > spotsdate = [0, 0.25, 0.45, 0.65, 0.85]
> > >> >> >> >>> >
> > >> >> >> >>> > curveHandle = YieldTermStructureHandle(ZeroCurve(spots,
> spotsdate,
> > >> >> >> >>> > Actual360(), Canada(), Linear(), Continuous))
> > >> >> >> >>> >
> > >> >> >> >>> > [c.amount() for c in FloatingRateBond(0, 10000,
> Schedule(mydate,
> > >> >> >> >>> > mydate + Period("1y"), Period(6, Months), Canada(),
> Unadjusted,
> > >> >> >> >>> > Unadjusted, DateGeneration.Forward, False) ,
> Euribor6M(curveHandle),
> > >> >> >> >>> > Actual360()).cashflows()]
> > >> >> >> >>> >
> > >> >> >> >>> > However above code failed to achieve any result, but
> giving out below error -
> > >> >> >> >>> >
> > >> >> >> >>> > Traceback (most recent call last):File "<stdin>", line 1,
> in
> > >> >> >> >>> > <module>File "<stdin>", line 1, in <listcomp>File
> > >> >> >> >>> >
> "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line
> > >> >> >> >>> > 9967, in amountreturn
> _QuantLib.CashFlow_amount(self)RuntimeError:
> > >> >> >> >>> > Missing Euribor6M Actual/360 fixing for January 29th, 2018
> > >> >> >> >>> >
> > >> >> >> >>> > I wonder where the date January 29th, 2018 comes from and
> how to resolve this?
> > >> >> >> >>> >
> > >> >> >> >>> > Any pointer will be highly appreciated.
> > >> >> >> >>> >
> > >> >> >> >>> > Thanks for your time.
> > >> >> >> >>>
> > >> >> >> >>>
> > >> >> >> >>> _______________________________________________
> > >> >> >> >>> 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
>
>
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: Brian S. <bri...@gm...> - 2021-04-06 18:15:12
|
Hi all - I would really appreciate if someone points me why I see this
difference, although small, just to make sure I am not making any
trivial mistake.
Thanks for your time.
On Mon, 5 Apr 2021 at 15:48, Brian Smith <bri...@gm...> wrote:
>
> I see. Thanks for pointing this out.
>
> Coming back to the calculation of 2nd coupon, I did manual calculation
> given that in the yield curve construction, I choose continuous
> compounding -
>
> (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
> spots[2]) * 100
>
> This gives answer 2.5877678758305054
>
> Whereas, QL gives coupon payment as 2.5884898292778846
>
> So, I dont see any exact match. Is there any definitive reason for
> this? Or just due to floating point error?
>
> On Mon, 5 Apr 2021 at 15:32, David Duarte <nh...@gm...> wrote:
> >
> > Because the fixing date for that coupon is 29.01.2018 and you specified 0 for that fixing...
> >
> > Try changing this line, and the first coupon will have the rate you input:;
> >
> > myindex.addFixing(Date(29, 1, 2018), 0.0, True)
> >
> > On Mon, 5 Apr 2021 at 10:58, Brian Smith <bri...@gm...> wrote:
> >>
> >> Thanks.
> >>
> >> But still I dont have any clue what was wrong in below code?
> >>
> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
> >> Actual360()).cashflows()]
> >>
> >> Why am I getting 0 here as first coupon?
> >>
> >> On Mon, 5 Apr 2021 at 15:11, David Duarte <nh...@gm...> wrote:
> >> >
> >> > The curve you are building takes continuous rates as inputs and uses linear interpolation of zero yields for non node points.
> >> > You could alternatively specify annually compounded rates as inputs.
> >> >
> >> >
> >> > In any case, you can inspect the cashflow details with ql.as_floating_coupon.
> >> >
> >> > Here is an example:
> >> >
> >> > bond = FloatingRateBond(0, 100, bond_schedule , myindex, Actual360())
> >> > interest_cashflows = [*map(as_floating_rate_coupon, bond.cashflows())][:-1]
> >> > rate = interest_cashflows[1].rate()
> >> > accrualDays = interest_cashflows[1].accrualDays()
> >> >
> >> > print("Floating rate:", rate)
> >> > print("Cashflow", 100 * rate * accrualDays/360)
> >> >
> >> >
> >> > # Floating rate: 0.050644366225002097
> >> > # Cashflow 2.588489829277885
> >> >
> >> >
> >> > On Mon, 5 Apr 2021 at 07:02, Brian Smith <bri...@gm...> wrote:
> >> >>
> >> >> Thanks again.
> >> >>
> >> >> Below is my modified code with 0 replaced by a dummy 0.05. But still I
> >> >> see 0 for first coupon payment.
> >> >>
> >> >> from QuantLib import *
> >> >>
> >> >> mydate = Date(31, 1, 2018)
> >> >>
> >> >> Settings.instance().evaluationDate = mydate
> >> >>
> >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
> >> >> + Period("2y"), mydate + Period("3y")]
> >> >> spotsdate = [0.05, 0.05, 0.05, 0.05, 0.05]
> >> >>
> >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
> >> >> Actual360(), Canada(), Linear(), Continuous))
> >> >>
> >> >> myindex = Euribor6M(curveHandle)
> >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> >> >>
> >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"), Period(6,
> >> >> Months), Canada(), Unadjusted, Unadjusted, DateGeneration.Forward,
> >> >> False)
> >> >>
> >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
> >> >> Actual360()).cashflows()]
> >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
> >> >> Actual360()).cashflows()]
> >> >>
> >> >> ### [0.0, 2.5884898292778846, 100.0]
> >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> >> >>
> >> >> To match the second coupon payment, I used below manual formula to
> >> >> convert continuous compounding to semi-annual :
> >> >>
> >> >> (math.sqrt(math.exp(0.05)) - 1)*2 * Actual360().yearFraction(spots[1],
> >> >> spots[2]) * 100
> >> >> ### 2.5877678758305054
> >> >>
> >> >> With this, I got a better match, but still not exact. Should I make
> >> >> any other adjustment?
> >> >>
> >> >> Appreciate your pointer.
> >> >>
> >> >> Thanks and regards,
> >> >>
> >> >> On Mon, 5 Apr 2021 at 04:08, Arkadiy Naumov <ark...@gm...> wrote:
> >> >> >
> >> >> > As far as the first zero - that's your extra fixing contributing. Either set it to 0.05 or create a custom index that does not have 2-days settlement, so you don't even have to worry about it.
> >> >> > For the interest being slightly off - 0.05 is continuously compounded (you set your zero curve this way), but the bond resets to "simple" rate (which is higher, so the numbers make sense at least directionally)
> >> >> >
> >> >> > On Sun, Apr 4, 2021 at 4:09 AM Brian Smith <bri...@gm...> wrote:
> >> >> >>
> >> >> >> Thanks for your comments.
> >> >> >>
> >> >> >> But I still failed to understand the coupon payments at various coupon
> >> >> >> dates. Below is my full example -
> >> >> >>
> >> >> >> from QuantLib import *
> >> >> >>
> >> >> >> mydate = Date(31, 1, 2018)
> >> >> >>
> >> >> >> Settings.instance().evaluationDate = mydate
> >> >> >>
> >> >> >> spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
> >> >> >> + Period("2y"), mydate + Period("3y")]
> >> >> >> spotsdate = [0, 0.05, 0.05, 0.05, 0.05]
> >> >> >>
> >> >> >> curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
> >> >> >> Actual360(), Canada(), Linear(), Continuous))
> >> >> >>
> >> >> >> myindex = Euribor6M(curveHandle)
> >> >> >> myindex.addFixing(Date(29, 1, 2018), 0.00)
> >> >> >>
> >> >> >> bond_schedule = Schedule(mydate, mydate + Period("1y"), Period(6,
> >> >> >> Months), Canada(), Unadjusted, Unadjusted, DateGeneration.Forward,
> >> >> >> False)
> >> >> >>
> >> >> >> [c.amount() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
> >> >> >> Actual360()).cashflows()]
> >> >> >> [c.date() for c in FloatingRateBond(0, 100, bond_schedule , myindex,
> >> >> >> Actual360()).cashflows()]
> >> >> >>
> >> >> >> ### [0.0, 2.5884898292778846, 100.0]
> >> >> >> ### [Date(31,7,2018), Date(31,1,2019), Date(31,1,2019)]
> >> >> >>
> >> >> >> So I see on the 1st coupon date, QL is showing coupon payment as 0. Why?
> >> >> >> And, on the last coupon date, coupon payment is 2.5884898292778846.
> >> >> >> How this number is calculated? If I manually calculate this, I get
> >> >> >> just a close match -
> >> >> >>
> >> >> >> 5 * Actual360().yearFraction(spots[1], spots[2])
> >> >> >>
> >> >> >> ### 2.5555555555555554
> >> >> >>
> >> >> >> Am I missing something?
> >> >> >>
> >> >> >> On Sun, 4 Apr 2021 at 03:27, Arkadiy Naumov <ark...@gm...> wrote:
> >> >> >> >
> >> >> >> > And as to the zeros - I may be wrong, but try explicitly setting the evaluationDate to whatever date you want to be your spot.
> >> >> >> >
> >> >> >> > On Sat, Apr 3, 2021 at 5:50 PM Arkadiy Naumov <ark...@gm...> wrote:
> >> >> >> >>
> >> >> >> >> Hi Brian,
> >> >> >> >>
> >> >> >> >> Without running your code - the reason Jan29th comes into play is because Euribor6M has a two days settlement built in: https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/eurlibor.cpp#L63
> >> >> >> >>
> >> >> >> >>
> >> >> >> >> On Sat, Apr 3, 2021 at 10:22 AM Brian Smith <bri...@gm...> wrote:
> >> >> >> >>>
> >> >> >> >>> Hi,
> >> >> >> >>>
> >> >> >> >>> I found out that I have to add a dummy quote to get this work. So I added -
> >> >> >> >>>
> >> >> >> >>> myindex = Euribor6M(curveHandle)
> >> >> >> >>> myindex.addFixing(Date(27, 7, 2018), 0.00)
> >> >> >> >>>
> >> >> >> >>> bond_schedule = Schedule(mydate,
> >> >> >> >>> mydate + Period("1y"), Period(6, Months), Canada(), Unadjusted,
> >> >> >> >>> Unadjusted, DateGeneration.Forward, False)
> >> >> >> >>>
> >> >> >> >>> [c.amount() for c in FloatingRateBond(0, 10000, bond_schedule ,
> >> >> >> >>> myindex, Actual360()).cashflows()]
> >> >> >> >>> [c.date() for c in FloatingRateBond(0, 10000, bond_schedule , myindex,
> >> >> >> >>> Actual360()).cashflows()]
> >> >> >> >>>
> >> >> >> >>> However with this, I am getting strange result as all the coupon
> >> >> >> >>> payments are coming as zero.
> >> >> >> >>>
> >> >> >> >>> Can you please help me to understand what went wrong in my code?
> >> >> >> >>>
> >> >> >> >>>
> >> >> >> >>> On Sat, 3 Apr 2021 at 14:39, Brian Smith <bri...@gm...> wrote:
> >> >> >> >>> >
> >> >> >> >>> > Hi,
> >> >> >> >>> >
> >> >> >> >>> > I want to extract all the cash flow amounts from a bond as defined below -
> >> >> >> >>> >
> >> >> >> >>> > from QuantLib import *
> >> >> >> >>> >
> >> >> >> >>> > mydate = Date(31, 1, 2018)
> >> >> >> >>> >
> >> >> >> >>> > spots = [mydate, mydate + Period("6m"), mydate + Period("1y"), mydate
> >> >> >> >>> > + Period("2y"), mydate + Period("3y")]
> >> >> >> >>> > spotsdate = [0, 0.25, 0.45, 0.65, 0.85]
> >> >> >> >>> >
> >> >> >> >>> > curveHandle = YieldTermStructureHandle(ZeroCurve(spots, spotsdate,
> >> >> >> >>> > Actual360(), Canada(), Linear(), Continuous))
> >> >> >> >>> >
> >> >> >> >>> > [c.amount() for c in FloatingRateBond(0, 10000, Schedule(mydate,
> >> >> >> >>> > mydate + Period("1y"), Period(6, Months), Canada(), Unadjusted,
> >> >> >> >>> > Unadjusted, DateGeneration.Forward, False) , Euribor6M(curveHandle),
> >> >> >> >>> > Actual360()).cashflows()]
> >> >> >> >>> >
> >> >> >> >>> > However above code failed to achieve any result, but giving out below error -
> >> >> >> >>> >
> >> >> >> >>> > Traceback (most recent call last):File "<stdin>", line 1, in
> >> >> >> >>> > <module>File "<stdin>", line 1, in <listcomp>File
> >> >> >> >>> > "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line
> >> >> >> >>> > 9967, in amountreturn _QuantLib.CashFlow_amount(self)RuntimeError:
> >> >> >> >>> > Missing Euribor6M Actual/360 fixing for January 29th, 2018
> >> >> >> >>> >
> >> >> >> >>> > I wonder where the date January 29th, 2018 comes from and how to resolve this?
> >> >> >> >>> >
> >> >> >> >>> > Any pointer will be highly appreciated.
> >> >> >> >>> >
> >> >> >> >>> > Thanks for your time.
> >> >> >> >>>
> >> >> >> >>>
> >> >> >> >>> _______________________________________________
> >> >> >> >>> 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
|