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
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Philippe H. <phi...@ex...> - 2023-12-17 21:08:00
|
You could try ql.CashFlows(cashflows, curve_handle, valaution_date) I think. Where valuation date can be the curve evaluation date or anything you want but beware about ex-coupon dates
Regards
Philippe Hatstadt
+1-203-252-0408
> On Dec 17, 2023, at 3:22 PM, Quant <qua...@gm...> wrote:
>
>
> Hi Quantlib Users,
>
> I have bootstrapped the yield curve and I have managed to extract discount factors from this yield curve but the discount factors are referencing from the Evaluation Date. These discount factors are used to calculate the PV of the bond but they can not be used to calculate the Dirty Price of the bond if the Evaluation Date is different from the Bond Settlement Date. How do I extract the Discount Factors from the Bond Settlement Date instead of the Evaluation Date. Hoping that my question is clear.
>
> Find below a part of the code that I have tried to use to extract the discount factors;
> fields = ['accrualStartDate', 'accrualEndDate', 'date', 'nominal', 'rate',
> 'amount', 'accrualDays', 'accrualPeriod']
> BondCashflows = []
> for cf in list(map(ql.as_fixed_rate_coupon, bond.cashflows()))[:-1]:
> row = {fld: eval(f"cf.{fld}()") for fld in fields}
> row['AccrualPeriod'] = round((row['accrualEndDate'] - row['accrualStartDate']) / 365, 4)
> if row['date'] >= today:
> row['ZeroRate (NPV)'] = round(curve.zeroRate(row['date'], day_count, ql.Compounded, ql.Annual).rate(), 9)
> row['ZeroRate (Dirty Price)'] = round(curve.forwardRate(bond.settlementDate(), row['date'], day_count, ql.Compounded, ql.Annual).rate(), 9)
> row['DiscFactor (NPV)'] = round(curve.discount(row['date']), 9)
> row['DiscFactor (Dirty Price)'] = round(curve.discount(bond.settlementDate(), row['date']), 9)
> else:
> row['ZeroRate (NPV)'] = 0
> row['ZeroRate (Dirty Price)'] = 0
> row['DiscFactor (NPV)'] = 0 # or any other appropriate handling for dates before today
> row['DiscFactor (Dirty Price)'] = 0 # or any other appropriate handling for dates before today
> row['NPV'] = round(row['DiscFactor (NPV)'] * row['amount'], 9)
> BondCashflows.append(row)
>
> BondCashflows = pd.DataFrame(BondCashflows)
>
> print(BondCashflows)
>
> Thanks & regards
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
--
1370 Broadway, Suite 1450 | New York, NY | 10018
<https://www.exosfinancial.com/>
<https://www.linkedin.com/company/meetexos/about/>
Broker-Dealer
services offered through Exos Securities LLC, Member SIPC, FINRA. For
important disclosures including Form CRS and Regulation BI click here
<https://www.exosfinancial.com/general-disclosures>.
Confidentiality
Notice: The information contained in this email (including attachments) is
only for the personal and confidential use of the sender and recipient
named above. If the reader is not the intended recipient, you are notified
that you have received this message in error and that any review,
dissemination, copying or distribution is prohibited. If you have received
this communication in error, please notify the sender immediately by e-mail
and delete or destroy the original message and all copies.
|
|
From: Quant <qua...@gm...> - 2023-12-17 20:21:26
|
Hi Quantlib Users,
I have bootstrapped the yield curve and I have managed to extract discount
factors from this yield curve but the discount factors are referencing from
the Evaluation Date. These discount factors are used to calculate the PV of
the bond but they can not be used to calculate the Dirty Price of the bond
if the Evaluation Date is different from the Bond Settlement Date. How do I
extract the Discount Factors from the Bond Settlement Date instead of the
Evaluation Date. Hoping that my question is clear.
Find below a part of the code that I have tried to use to extract the
discount factors;
fields = ['accrualStartDate', 'accrualEndDate', 'date', 'nominal', 'rate',
'amount', 'accrualDays', 'accrualPeriod']
BondCashflows = []
for cf in list(map(ql.as_fixed_rate_coupon, bond.cashflows()))[:-1]:
row = {fld: eval(f"cf.{fld}()") for fld in fields}
row['AccrualPeriod'] = round((row['accrualEndDate'] -
row['accrualStartDate']) / 365, 4)
if row['date'] >= today:
row['ZeroRate (NPV)'] = round(curve.zeroRate(row['date'],
day_count, ql.Compounded, ql.Annual).rate(), 9)
row['ZeroRate (Dirty Price)'] =
round(curve.forwardRate(bond.settlementDate(), row['date'], day_count,
ql.Compounded, ql.Annual).rate(), 9)
row['DiscFactor (NPV)'] = round(curve.discount(row['date']), 9)
row['DiscFactor (Dirty Price)'] =
round(curve.discount(bond.settlementDate(), row['date']), 9)
else:
row['ZeroRate (NPV)'] = 0
row['ZeroRate (Dirty Price)'] = 0
row['DiscFactor (NPV)'] = 0 # or any other appropriate
handling for dates before today
row['DiscFactor (Dirty Price)'] = 0 # or any other
appropriate handling for dates before today
row['NPV'] = round(row['DiscFactor (NPV)'] * row['amount'], 9)
BondCashflows.append(row)
BondCashflows = pd.DataFrame(BondCashflows)
print(BondCashflows)
Thanks & regards
|
|
From: Philippe H. <pha...@ma...> - 2023-12-11 16:31:53
|
Thank you. Which cookbook are you referring to Mike? Where can I find it? Regards Philippe Hatstadt 203-252-0408 pha...@ma... On Dec 11, 2023, at 11:14 AM, Mike DelMedico <mik...@gm...> wrote: Yes, it’s documented pretty well in the cookbook available online. You use several classes (deposit/future/swap rate helpers) to complete the bootstrapping. If you want the fancy stair-stepped front end then you may need to use additional deposit rate helpers to override/control those points explicitly. Regards, Mike On Mon, Dec 11, 2023 at 10:09 philippe hatstadt via QuantLib-users < qua...@li... > wrote: Does QuantLib have a class to build and bootstrap a SOFR forecasting and discounting curve, using as inputs either term fixed-floating OIS swap rates or better yet a blend of SOFR futures and OIS for longer tenors? Regards Philippe Hatstadt +1-203-252-0408 _______________________________________________ QuantLib-users mailing list Qua...@li... https://lists.sourceforge.net/lists/listinfo/quantlib-users |
|
From: Luigi B. <lui...@gm...> - 2023-12-11 16:24:50
|
Hi Philippe,
you can use the PiecewiseYieldCurve class by passing it helpers that
model SOFR-based instruments. As of the latest release,
both SofrFutureRateHelper and OISRateHelper are available.
Luigi
On Mon, Dec 11, 2023 at 5:09 PM philippe hatstadt via QuantLib-users <
qua...@li...> wrote:
> Does QuantLib have a class to build and bootstrap a SOFR forecasting and
> discounting curve, using as inputs either term fixed-floating OIS swap
> rates or better yet a blend of SOFR futures and OIS for longer tenors?
>
> Regards
>
> Philippe Hatstadt
> +1-203-252-0408
>
>
>
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: Mike D. <mik...@gm...> - 2023-12-11 16:14:23
|
Yes, it’s documented pretty well in the cookbook available online. You use several classes (deposit/future/swap rate helpers) to complete the bootstrapping. If you want the fancy stair-stepped front end then you may need to use additional deposit rate helpers to override/control those points explicitly. Regards, Mike On Mon, Dec 11, 2023 at 10:09 philippe hatstadt via QuantLib-users < qua...@li...> wrote: > Does QuantLib have a class to build and bootstrap a SOFR forecasting and > discounting curve, using as inputs either term fixed-floating OIS swap > rates or better yet a blend of SOFR futures and OIS for longer tenors? > > Regards > > Philippe Hatstadt > +1-203-252-0408 > > > > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: philippe h. <pha...@ma...> - 2023-12-11 16:06:18
|
Does QuantLib have a class to build and bootstrap a SOFR forecasting and discounting curve, using as inputs either term fixed-floating OIS swap rates or better yet a blend of SOFR futures and OIS for longer tenors? Regards Philippe Hatstadt +1-203-252-0408 |
|
From: philippe h. <pha...@ma...> - 2023-12-11 16:04:20
|
Is there any QL 2 factor rate model implementation that has been exposed to Python? I am working on a CMBS Pool OAS model and need the ability to de-correlate short rates and long rates. But I would also need a calibration module to swaption vols and some way to calibrate the correlation parameters to match correlation matrices or rate changes by tenors. Please let me know. Regards Philippe Hatstadt +1-203-252-0408 |
|
From: Luigi B. <lui...@gm...> - 2023-12-11 15:10:36
|
Hello, apologies for the delay. Not all the C++ classes are exposed to Python; there's some manual work involved. To check if a given class is available in Python, I'm afraid the easiest way is to search for it in the SWIG interface files ( https://github.com/lballabio/QuantLib-SWIG/tree/master/SWIG). The experimental folder is where we store classes when the interface is not yet finalized. Once a class is in the main part of the library, changing the interface in a backward-compatible way (i.e. without breaking code that someone might have written based on that class) becomes difficult. When we're not yet sure of the interface of a class, we store it into experimental, which isn't supposed to be as stable as the main code. Hope this helps, Luigi On Mon, Nov 13, 2023 at 1:44 PM kmylonakis via QuantLib-users < qua...@li...> wrote: > Hi all, > > I would like to have a look at the 1F Gaussian Copula model that i see is > implemented in the experimental directory and would like to ask if this > class is readily exposed via SWIG to Python. I could not find it myself and > wondering if there is something that I am missing. > > And one more question since I am new to QL. Generaly what is the meaning > of the classes under experimental, does it mean not validated? > > Thank you very much in advance. > Kostas > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Luigi B. <lui...@gm...> - 2023-12-01 16:21:55
|
Yes, CashFlows.npv uses the settle date as you would expect; you can check its implementation at < https://github.com/lballabio/QuantLib/blob/v1.32/ql/cashflows/cashflows.cpp#L425 >. I'm not sure that it's the only way to do it (you might try something by passing the cash flows to the Bond constructors) but it's probably the least complicated. Hope this helps, Luigi On Fri, Dec 1, 2023 at 3:29 PM Philippe Hatstadt < phi...@ex...> wrote: > Thanks Luigi. > Let me provide more color. The exercise above is part of a python unit > test and in fact, what I am testing is that .NPV(settle_date) matches > .dirtyPrice(settle_date). I found an old post on this forum that explains > that .NPV() can only price to ql.Settings.instance().evaluationDate. This > is why I tried setting the latter to settle_date and call .NPV() again but > maybe it also rebuilds my curve and changes things, so that doesn't seem > like a good idea. What I did that made it work was simply to return > .NPV(evaluationDate) / curve.discount(settle_date). Then the values match > perfectly. So far so good. > Now let's go back to why I was writing such a unit test to begin with, > because to your point, use dirtyPrice(settle_date) and be happy. Well not > quite. The instrument I am pricing is a funky GNMA fixed rate amortizing > bond via OAS. As a result, I do not use YieldToMaturity, but instead, for > each OAS path, I must value the cash flows on a curve shifted by a > z-spread, bond_engine = ql.DiscountingBondEngine(curve_handle) and > exos_bond.setPricingEngine(bond_engine) > The amortization It is *not* a standard amortization table like a > conventional mortgage, so we wrote the cash flow model including > involuntary prepay curve but the structure has a 14d payment lag on monthly > cash flows, and the ex-coupon date is the last day of the month. Settle lag > is T+2. In other words, if I buy a bond and it settles on 11/30, I am > buying the entire 11/01-11/30 coupon. On the other hand, if it settles, on > 12/01, I am not, but I have to pay one day of accrued. I am unaware of any > QL bond instrument that can correctly accept arbitrary cash flows and also > accept a 14d settle lag. If one existed, I would instantiate it and attempt > to use .dirtyPrice() although I don't even think that would work since I > need to price on a curve and not use a flat yield to maturity. > > So, my plan is to instead do something like this: > cfs = [ql.SimpleCashFlow(cashflow, d) for d, cashflow in zip(dates, leg) ] > pv = ql.CashFlows.npv(cfs, discountTermStructure, False, settle_date) > and I would need to make sure to generate the ex-coupon date myself when > generating the cash flow vector. > > So I wanted to confirm that the approach above is the only valid one for > this funky instrument to be priced via prepay/OAS on a curve. So can you > confirm that ql.CashFlows.npv) does correctly PV to the settle_date (> > reference date) so that I don't have to do the roll forward manually? I > suppose I can write a unit test for that as well but wanted to know for > sure. > > Philippe Hatstadt > > > On Fri, Dec 1, 2023 at 5:34 AM Luigi Ballabio <lui...@gm...> > wrote: > >> Hello Philippe, >> instead of NPV, use bond.cleanPrice() or bond.dirtyPrice() instead. >> Those two methods take the settlement days into account. >> >> Luigi >> >> >> On Thu, Nov 30, 2023 at 1:24 AM Philippe Hatstadt via QuantLib-users < >> qua...@li...> wrote: >> >>> I am building a ql.YieldTermStructureHandle with US treasury bonds that >>> settle T+1. Since the method is bootystrapping, I expect each bond sued to >>> build the curve to repcie itself 100% accurateIy when pricing any of the >>> bonds used to build the curve on such curve. >>> To test that, I compute the bonds dirty price by first assigning a >>> pricing engine via my_bond.set_pricing_engine_from_curve(curve_handle) and >>> then calling my_bond.NPV(). While the above returns a value, it does not >>> return a value exactly equal to the dirty price of the bond using the >>> closed-form my_bond.dirtyPrice(*args, settle_date) method. the values >>> differ by about 0.013, whihc is about euqal to 100 *(1-1/(1+.05/365)), >>> meaning that the difference is about one day of discounting at a 5% rate, >>> close to market rates. >>> This strongly indicates that thre NPV() method discounts the cash flows >>> to T+0 = trade_date, and not to the T+1 settle date. >>> So how can I instruct my_bond.NPV() to use a given settle date? I looked >>> in the documentation of both python and C++ and it doesn't seem like there >>> is any way to do that? >>> One thing I tried to do is ql.Settings.instance().evaluationDate = >>> settle_date just before I call .NPV() but it does exactly the opposite and >>> appears to add one more day of discounting instead of reducing it. >>> >>> Any advice is appreciated. >>> >>> >>> Regards Philippe Hatstadt 203-252-0408 pha...@ma... >>> >>> >>> _______________________________________________ >>> 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 >> > > 1370 Broadway, Suite 1450 | New York, NY | 10018 > > [image: https://www.exosfinancial.com/] <https://www.exosfinancial.com/> [image: > https://www.linkedin.com/company/meetexos/about/] > <https://www.linkedin.com/company/meetexos/about/> > > Broker-Dealer services offered through Exos Securities LLC, Member SIPC, > FINRA. For important disclosures including Form CRS and Regulation BI click > here <https://www.exosfinancial.com/general-disclosures>. > > > Confidentiality Notice: The information contained in this email > (including attachments) is only for the personal and confidential use of > the sender and recipient named above. If the reader is not the intended > recipient, you are notified that you have received this message in error > and that any review, dissemination, copying or distribution is prohibited. > If you have received this communication in error, please notify the sender > immediately by e-mail and delete or destroy the original message and all > copies. > |
|
From: Philippe H. <phi...@ex...> - 2023-12-01 15:35:04
|
Thanks Luigi. Let me provide more color. The exercise above is part of a python unit test and in fact, what I am testing is that .NPV(settle_date) matches .dirtyPrice(settle_date). I found an old post on this forum that explains that .NPV() can only price to ql.Settings.instance().evaluationDate. This is why I tried setting the latter to settle_date and call .NPV() again but maybe it also rebuilds my curve and changes things, so that doesn't seem like a good idea. What I did that made it work was simply to return .NPV(evaluationDate) / curve.discount(settle_date). Then the values match perfectly. So far so good. Now let's go back to why I was writing such a unit test to begin with, because to your point, use dirtyPrice(settle_date) and be happy. Well not quite. The instrument I am pricing is a funky GNMA fixed rate amortizing bond via OAS. As a result, I do not use YieldToMaturity, but instead, for each OAS path, I must value the cash flows on a curve shifted by a z-spread, bond_engine = ql.DiscountingBondEngine(curve_handle) and exos_bond.setPricingEngine(bond_engine) The amortization It is *not* a standard amortization table like a conventional mortgage, so we wrote the cash flow model including involuntary prepay curve but the structure has a 14d payment lag on monthly cash flows, and the ex-coupon date is the last day of the month. Settle lag is T+2. In other words, if I buy a bond and it settles on 11/30, I am buying the entire 11/01-11/30 coupon. On the other hand, if it settles, on 12/01, I am not, but I have to pay one day of accrued. I am unaware of any QL bond instrument that can correctly accept arbitrary cash flows and also accept a 14d settle lag. If one existed, I would instantiate it and attempt to use .dirtyPrice() although I don't even think that would work since I need to price on a curve and not use a flat yield to maturity. So, my plan is to instead do something like this: cfs = [ql.SimpleCashFlow(cashflow, d) for d, cashflow in zip(dates, leg) ] pv = ql.CashFlows.npv(cfs, discountTermStructure, False, settle_date) and I would need to make sure to generate the ex-coupon date myself when generating the cash flow vector. So I wanted to confirm that the approach above is the only valid one for this funky instrument to be priced via prepay/OAS on a curve. So can you confirm that ql.CashFlows.npv) does correctly PV to the settle_date (> reference date) so that I don't have to do the roll forward manually? I suppose I can write a unit test for that as well but wanted to know for sure. Philippe Hatstadt On Fri, Dec 1, 2023 at 5:34 AM Luigi Ballabio <lui...@gm...> wrote: > Hello Philippe, > instead of NPV, use bond.cleanPrice() or bond.dirtyPrice() instead. > Those two methods take the settlement days into account. > > Luigi > > > On Thu, Nov 30, 2023 at 1:24 AM Philippe Hatstadt via QuantLib-users < > qua...@li...> wrote: > >> I am building a ql.YieldTermStructureHandle with US treasury bonds that >> settle T+1. Since the method is bootystrapping, I expect each bond sued to >> build the curve to repcie itself 100% accurateIy when pricing any of the >> bonds used to build the curve on such curve. >> To test that, I compute the bonds dirty price by first assigning a >> pricing engine via my_bond.set_pricing_engine_from_curve(curve_handle) and >> then calling my_bond.NPV(). While the above returns a value, it does not >> return a value exactly equal to the dirty price of the bond using the >> closed-form my_bond.dirtyPrice(*args, settle_date) method. the values >> differ by about 0.013, whihc is about euqal to 100 *(1-1/(1+.05/365)), >> meaning that the difference is about one day of discounting at a 5% rate, >> close to market rates. >> This strongly indicates that thre NPV() method discounts the cash flows >> to T+0 = trade_date, and not to the T+1 settle date. >> So how can I instruct my_bond.NPV() to use a given settle date? I looked >> in the documentation of both python and C++ and it doesn't seem like there >> is any way to do that? >> One thing I tried to do is ql.Settings.instance().evaluationDate = >> settle_date just before I call .NPV() but it does exactly the opposite and >> appears to add one more day of discounting instead of reducing it. >> >> Any advice is appreciated. >> >> >> Regards Philippe Hatstadt 203-252-0408 pha...@ma... >> >> >> _______________________________________________ >> 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 > -- 1370 Broadway, Suite 1450 | New York, NY | 10018 <https://www.exosfinancial.com/> <https://www.linkedin.com/company/meetexos/about/> Broker-Dealer services offered through Exos Securities LLC, Member SIPC, FINRA. For important disclosures including Form CRS and Regulation BI click here <https://www.exosfinancial.com/general-disclosures>. Confidentiality Notice: The information contained in this email (including attachments) is only for the personal and confidential use of the sender and recipient named above. If the reader is not the intended recipient, you are notified that you have received this message in error and that any review, dissemination, copying or distribution is prohibited. If you have received this communication in error, please notify the sender immediately by e-mail and delete or destroy the original message and all copies. |
|
From: Luigi B. <lui...@gm...> - 2023-12-01 10:33:52
|
Hello Philippe,
instead of NPV, use bond.cleanPrice() or bond.dirtyPrice() instead.
Those two methods take the settlement days into account.
Luigi
On Thu, Nov 30, 2023 at 1:24 AM Philippe Hatstadt via QuantLib-users <
qua...@li...> wrote:
> I am building a ql.YieldTermStructureHandle with US treasury bonds that
> settle T+1. Since the method is bootystrapping, I expect each bond sued to
> build the curve to repcie itself 100% accurateIy when pricing any of the
> bonds used to build the curve on such curve.
> To test that, I compute the bonds dirty price by first assigning a pricing
> engine via my_bond.set_pricing_engine_from_curve(curve_handle) and then
> calling my_bond.NPV(). While the above returns a value, it does not return
> a value exactly equal to the dirty price of the bond using the closed-form
> my_bond.dirtyPrice(*args, settle_date) method. the values differ by about
> 0.013, whihc is about euqal to 100 *(1-1/(1+.05/365)), meaning that the
> difference is about one day of discounting at a 5% rate, close to market
> rates.
> This strongly indicates that thre NPV() method discounts the cash flows to
> T+0 = trade_date, and not to the T+1 settle date.
> So how can I instruct my_bond.NPV() to use a given settle date? I looked
> in the documentation of both python and C++ and it doesn't seem like there
> is any way to do that?
> One thing I tried to do is ql.Settings.instance().evaluationDate =
> settle_date just before I call .NPV() but it does exactly the opposite and
> appears to add one more day of discounting instead of reducing it.
>
> Any advice is appreciated.
>
>
> Regards Philippe Hatstadt 203-252-0408 pha...@ma...
>
>
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: Philippe H. <pha...@ma...> - 2023-11-30 00:20:52
|
I am building a ql.YieldTermStructureHandle with US treasury bonds that settle T+1. Since the method is bootystrapping, I expect each bond sued to build the curve to repcie itself 100% accurateIy when pricing any of the bonds used to build the curve on such curve. To test that, I compute the bonds dirty price by first assigning a pricing engine via my_bond.set_pricing_engine_from_curve(curve_handle) and then calling my_bond.NPV(). While the above returns a value, it does not return a value exactly equal to the dirty price of the bond using the closed-form my_bond.dirtyPrice(*args, settle_date) method. the values differ by about 0.013, whihc is about euqal to 100 *(1-1/(1+.05/365)), meaning that the difference is about one day of discounting at a 5% rate, close to market rates. This strongly indicates that thre NPV() method discounts the cash flows to T+0 = trade_date, and not to the T+1 settle date. So how can I instruct my_bond.NPV() to use a given settle date? I looked in the documentation of both python and C++ and it doesn't seem like there is any way to do that? One thing I tried to do is ql.Settings.instance().evaluationDate = settle_date just before I call .NPV() but it does exactly the opposite and appears to add one more day of discounting instead of reducing it. Any advice is appreciated. Regards Philippe Hatstadt 203-252-0408 pha...@ma... |
|
From: Philippe H. <pha...@ma...> - 2023-11-29 19:46:08
|
I use Python, but this obviouslyt appleis to C++. Most/all signatures require settlementDays like this one: ql. FixedRateBond ( settlementDays , faceAmount , schedule , coupon , paymentConvention ). I do not really understand why settlement days (or settlement date) needs to be an attribute of a Bond, as the latter should be immutable. Furthermore, methods such as ql.FixedrateBond.bondYield() requires a settlement date, which is quite normal. But then what is the point of having settle days/ date as a mandatory attribute of the Bond class constructor when it is correctly required to do any type of bond math calculations? Now, let's assume I build a US Govt bond with settlementDays=1. What happens if I want to compute a forward bond price with say T+5 settlement lag. I could directly pass such settlement date to bondYield() without rebuilding the bond object with settleDays=5 instead of 1. So can you confirm that doing the above effectively overrides the settleDays lag built in the bond class?Although passing settleDays=1 to build the bond seems redundant, I suppsoe it it required, which is fine. Regards Philippe Hatstadt 203-252-0408 pha...@ma... |
|
From: Quant <qua...@gm...> - 2023-11-27 09:48:54
|
Thanks Aleksis, changed the following parts and the Code worked without
errors:
(i) bondEngine =
ql.DiscountingBondEngine(ql.YieldTermStructureHandle(curve)) - added
ql.YieldTermStructureHandle()
(ii) bondYield = bond.bondYield(day_count, ql.Compounded, ql.Annual) -
added parameters day_count, ql.Compounded, ql.Annual
Regards,
On Mon, Nov 27, 2023 at 11:09 AM Aleksis Ali Raza <
ale...@go...> wrote:
> i think you’re just missing a ql.YieldTermStuctureHandle() call on ur
> constructed curve. you can add that but then u’ll need to alter the dt in
> dates call to refer to the unhandled curve, and also specify some
> parameters in the bondyield call. Then the error will go away.
>
> your code should run fine even without it.
>
> On Nov 27, 2023, at 8:38 AM, Quant <qua...@gm...> wrote:
>
> Hi QuantLib Users,
>
> I have data containing Bond information and I managed to use this
> information to bootstrap the zero curve. To check if my zero curve is
> correct, I would like to reprice the Bonds using the bootstrapped curve
> (using the zero curve) to get back to the quoted prices of the Bonds. I am
> getting the following errors on the repricing part and if anyone can help I
> would appreciate;
>
> Traceback (most recent call last):
> File "/Users/Library/CloudStorage/OneDrive-Personal/QuantLib Software/Valuations/IRS using Bond Bootstrapping/IRS using Bond Bootstrapping 2.py", line 369, in <module>
> bondEngine = ql.DiscountingBondEngine(curve)
> File "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line 25290, in __init__
> _QuantLib.DiscountingBondEngine_swiginit(self, _QuantLib.new_DiscountingBondEngine(discountCurve))
> TypeError: in method 'new_DiscountingBondEngine', argument 1 of type 'Handle< YieldTermStructure > const &'
>
>
> Find below the code that I am running;
>
> # Importing Libraries:# The code imports necessary libraries:# pandas for data manipulation, matplotlib.pyplot for plotting, and QuantLib (ql) for quantitative finance calculations.import pandas as pdimport matplotlib.pyplot as plt# Use the QuantLib or ORE Librariesimport QuantLib as ql
> # Setting Evaluation Date:# Sets the evaluation date
> today = ql.Date(21, ql.November, 2023)
> ql.Settings.instance().evaluationDate = today
> # Calendar and Day Count:# Creates a calendar object and specifies the day-count convention (Actual/365 Fixed)
> calendar = ql.NullCalendar()
> day_count = ql.Actual365Fixed()
> # Settlement Days:
> zero_coupon_settlement_days = 4
> coupon_bond_settlement_days = 3
> # Face Value
> faceAmount = 100
>
> data = [
> ('11-09-2023', '11-12-2023', 0, 99.524, zero_coupon_settlement_days),
> ('11-09-2023', '11-03-2024', 0, 96.539, zero_coupon_settlement_days),
> ('11-09-2023', '10-06-2024', 0, 93.552, zero_coupon_settlement_days),
> ('11-09-2023', '09-09-2024', 0, 89.510, zero_coupon_settlement_days),
> ('22-08-2022', '22-08-2024', 9.0, 96.406933, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2025', 10.0, 88.567570, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2027', 11.0, 71.363073, coupon_bond_settlement_days),
> ('22-08-2022', '22-08-2029', 12.0, 62.911623, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2032', 13.0, 55.976845, coupon_bond_settlement_days),
> ('22-08-2022', '22-08-2037', 14.0, 52.656596, coupon_bond_settlement_days)]
>
> helpers = []
> for issue_date, maturity, coupon, price, settlement_days in data:
> price = ql.QuoteHandle(ql.SimpleQuote(price))
> issue_date = ql.Date(issue_date, '%d-%m-%Y')
> maturity = ql.Date(maturity, '%d-%m-%Y')
> schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
> helper = ql.FixedRateBondHelper(price, settlement_days, faceAmount, schedule, [coupon / 100], day_count,
> False)
> helpers.append(helper)
>
> curve = ql.PiecewiseCubicZero(today, helpers, day_count)
> # Enable Extrapolation:# This line enables extrapolation for the yield curve.# Extrapolation allows the curve to provide interest rates or rates beyond the observed data points,# which can be useful for pricing or risk management purposes.
> curve.enableExtrapolation()
> # Zero Rate and Discount Rate Calculation:# Calculates and prints the zero rate and discount rate at a specific# future date (May 28, 2048) using the constructed yield curve.
> date = ql.Date(28, ql.May, 2024)
> zero_rate = curve.zeroRate(date, day_count, ql.Annual).rate()
> forward_rate = curve.forwardRate(date, date + ql.Period(1, ql.Years), day_count, ql.Annual).rate()
> discount_rate = curve.discount(date)print("Zero rate as at 28.05.2048: " + str(round(zero_rate*100, 4)) + str("%"))print("Forward rate as at 28.05.2048: " + str(round(forward_rate*100, 4)) + str("%"))print("Discount factor as at 28.05.2048: " + str(round(discount_rate, 4)))
> # Print the Zero Rates, Forward Rates and Discount Factors at node dates# print(pd.DataFrame(curve.nodes()))
> node_data = {'Date': [],
> 'Zero Rates': [],
> 'Forward Rates': [],
> 'Discount Factors': []}
> for dt in curve.dates():
> node_data['Date'].append(dt)
> node_data['Zero Rates'].append(curve.zeroRate(dt, day_count, ql.Annual).rate())
> node_data['Forward Rates'].append(curve.forwardRate(dt, dt + ql.Period(1, ql.Years), day_count, ql.Annual).rate())
> node_data['Discount Factors'].append(curve.discount(dt))
>
> node_dataframe = pd.DataFrame(node_data)
> print(node_dataframe)
>
> node_dataframe.to_excel('NodeRates.xlsx')
> # Printing Daily Zero Rates:# Prints the daily zero rates# It calculates and prints the zero rates for each year using the constructed yield curve.
> maturity_date = calendar.advance(today, ql.Period(1, ql.Years))
> current_date = todaywhile current_date <= maturity_date:
> zero_rate = curve.zeroRate(current_date, day_count, ql.Annual).rate()
> print(f"Date: {current_date}, Zero Rate: {zero_rate}")
> current_date = calendar.advance(current_date, ql.Period(1, ql.Years))
> # Creating Curve Data for Plotting:# Creates lists of curve dates, zero rates, and forward rates for plotting.# It calculates both zero rates and forward rates for each year up to 15 years from the current date.
> curve_dates = [today + ql.Period(i, ql.Years)
> for i in range(15)]
> curve_zero_rates = [curve.zeroRate(date, day_count, ql.Annual).rate()
> for date in curve_dates]
> # Converting ql.Date to Numerical Values: (years from today)# Converts the curve dates (ql.Date objects) to numerical values representing years from the current# date. This is done to prepare the data for plotting on the x-axis.
> numeric_dates = [(date - today) / 365 for date in curve_dates]
> # Plotting:# Creates a plot showing the zero rates and forward rates over time.# The x-axis represents the years from the current date, and the y-axis represents the interest rates.# The plot displays two lines: one for zero rates (blue) and another for forward rates (red).# The plot is labeled, grid lines are added, and the visualization is displayed using
> plt.figure(figsize=(10, 6))
> plt.plot(numeric_dates, curve_zero_rates, marker='', linestyle='-', color='b', label='Zero Rates')
> plt.title('Zero Rates')
> plt.xlabel('Years from Today')
> plt.ylabel('Rate')
> plt.legend()
> plt.grid(True)
> plt.xticks(rotation=0)
> plt.tight_layout()
>
> plt.show()
>
> tenors = ['3M', '6M', '9M', '1Y', '2Y', '3Y', '5Y', '7Y', '10Y', '15Y']
> # Print the Zero Rates, Forward Rates, and Discount Factors at Instrument maturity dates
> node_data = {'Maturity Date': [],
> 'Tenors': [],
> 'Zero Rates': [],
> 'Forward Rates': [],
> 'Discount Factors': []}
> for tenor in tenors:
> maturity_date = calendar.advance(today, ql.Period(tenor), ql.ModifiedFollowing) # Calculate the maturity date
> node_data['Maturity Date'].append(maturity_date)
> node_data['Tenors'].append(tenor)
> node_data['Zero Rates'].append(curve.zeroRate(maturity_date, day_count, ql.Annual).rate())
> node_data['Forward Rates'].append(curve.forwardRate(maturity_date, maturity_date + ql.Period(0, ql.Years), day_count, ql.Annual).rate())
> node_data['Discount Factors'].append(curve.discount(maturity_date))
>
> node_dataframe = pd.DataFrame(node_data)
> print(node_dataframe)
>
> node_dataframe.to_excel('NodeRates.xlsx')
> # Create a DataFrame to store bond results
> bond_results = {'Issue Date': [],
> 'Maturity Date': [],
> 'Coupon Rate': [],
> 'Price': [],
> 'Settlement Days': [],
> 'Yield': [],
> 'Clean Price': [],
> 'Dirty Price': []}
> # Calculate bond prices and yieldsfor issue_date, maturity, coupon, price, settlement_days in data:
> price = ql.QuoteHandle(ql.SimpleQuote(price))
> issue_date = ql.Date(issue_date, '%d-%m-%Y')
> maturity = ql.Date(maturity, '%d-%m-%Y')
> schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
> bondEngine = ql.DiscountingBondEngine(curve)
> bond = ql.FixedRateBond(settlement_days, faceAmount, schedule, [coupon / 100], day_count)
> bond.setPricingEngine(bondEngine)
>
> # Calculate bond yield, clean price, and dirty price
> bondYield = bond.bondYield()
> bondCleanPrice = bond.cleanPrice()
> bondDirtyPrice = bond.dirtyPrice()
>
> # Append the results to the DataFrame
> bond_results['Issue Date'].append(issue_date)
> bond_results['Maturity Date'].append(maturity)
> bond_results['Coupon Rate'].append(coupon)
> bond_results['Price'].append(price.value())
> bond_results['Settlement Days'].append(settlement_days)
> bond_results['Yield'].append(bondYield)
> bond_results['Clean Price'].append(bondCleanPrice)
> bond_results['Dirty Price'].append(bondDirtyPrice)
> # Create a DataFrame from the bond results
> bond_results_df = pd.DataFrame(bond_results)
> # Print the resultsprint(bond_results_df)
>
>
> Thanks & regards,
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
>
>
|
|
From: Aleksis A. R. <ale...@go...> - 2023-11-27 09:15:35
|
i think you’re just missing a ql.YieldTermStuctureHandle() call on ur constructed curve. you can add that but then u’ll need to alter the dt in dates call to refer to the unhandled curve, and also specify some parameters in the bondyield call. Then the error will go away.
your code should run fine even without it.
> On Nov 27, 2023, at 8:38 AM, Quant <qua...@gm...> wrote:
>
> Hi QuantLib Users,
>
> I have data containing Bond information and I managed to use this information to bootstrap the zero curve. To check if my zero curve is correct, I would like to reprice the Bonds using the bootstrapped curve (using the zero curve) to get back to the quoted prices of the Bonds. I am getting the following errors on the repricing part and if anyone can help I would appreciate;
>
> Traceback (most recent call last):
> File "/Users/Library/CloudStorage/OneDrive-Personal/QuantLib Software/Valuations/IRS using Bond Bootstrapping/IRS using Bond Bootstrapping 2.py", line 369, in <module>
> bondEngine = ql.DiscountingBondEngine(curve)
> File "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py", line 25290, in __init__
> _QuantLib.DiscountingBondEngine_swiginit(self, _QuantLib.new_DiscountingBondEngine(discountCurve))
> TypeError: in method 'new_DiscountingBondEngine', argument 1 of type 'Handle< YieldTermStructure > const &'
>
> Find below the code that I am running;
>
> # Importing Libraries:
> # The code imports necessary libraries:
> # pandas for data manipulation, matplotlib.pyplot for plotting, and QuantLib (ql) for quantitative finance calculations.
> import pandas as pd
> import matplotlib.pyplot as plt
> # Use the QuantLib or ORE Libraries
> import QuantLib as ql
>
> # Setting Evaluation Date:
> # Sets the evaluation date
> today = ql.Date(21, ql.November, 2023)
> ql.Settings.instance().evaluationDate = today
>
> # Calendar and Day Count:
> # Creates a calendar object and specifies the day-count convention (Actual/365 Fixed)
> calendar = ql.NullCalendar()
> day_count = ql.Actual365Fixed()
>
> # Settlement Days:
> zero_coupon_settlement_days = 4
> coupon_bond_settlement_days = 3
>
> # Face Value
> faceAmount = 100
>
> data = [
> ('11-09-2023', '11-12-2023', 0, 99.524, zero_coupon_settlement_days),
> ('11-09-2023', '11-03-2024', 0, 96.539, zero_coupon_settlement_days),
> ('11-09-2023', '10-06-2024', 0, 93.552, zero_coupon_settlement_days),
> ('11-09-2023', '09-09-2024', 0, 89.510, zero_coupon_settlement_days),
> ('22-08-2022', '22-08-2024', 9.0, 96.406933, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2025', 10.0, 88.567570, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2027', 11.0, 71.363073, coupon_bond_settlement_days),
> ('22-08-2022', '22-08-2029', 12.0, 62.911623, coupon_bond_settlement_days),
> ('27-06-2022', '27-06-2032', 13.0, 55.976845, coupon_bond_settlement_days),
> ('22-08-2022', '22-08-2037', 14.0, 52.656596, coupon_bond_settlement_days)]
>
> helpers = []
>
> for issue_date, maturity, coupon, price, settlement_days in data:
> price = ql.QuoteHandle(ql.SimpleQuote(price))
> issue_date = ql.Date(issue_date, '%d-%m-%Y')
> maturity = ql.Date(maturity, '%d-%m-%Y')
> schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
> helper = ql.FixedRateBondHelper(price, settlement_days, faceAmount, schedule, [coupon / 100], day_count,
> False)
> helpers.append(helper)
>
> curve = ql.PiecewiseCubicZero(today, helpers, day_count)
>
> # Enable Extrapolation:
> # This line enables extrapolation for the yield curve.
> # Extrapolation allows the curve to provide interest rates or rates beyond the observed data points,
> # which can be useful for pricing or risk management purposes.
> curve.enableExtrapolation()
>
> # Zero Rate and Discount Rate Calculation:
> # Calculates and prints the zero rate and discount rate at a specific
> # future date (May 28, 2048) using the constructed yield curve.
> date = ql.Date(28, ql.May, 2024)
> zero_rate = curve.zeroRate(date, day_count, ql.Annual).rate()
> forward_rate = curve.forwardRate(date, date + ql.Period(1, ql.Years), day_count, ql.Annual).rate()
> discount_rate = curve.discount(date)
> print("Zero rate as at 28.05.2048: " + str(round(zero_rate*100, 4)) + str("%"))
> print("Forward rate as at 28.05.2048: " + str(round(forward_rate*100, 4)) + str("%"))
> print("Discount factor as at 28.05.2048: " + str(round(discount_rate, 4)))
>
> # Print the Zero Rates, Forward Rates and Discount Factors at node dates
> # print(pd.DataFrame(curve.nodes()))
> node_data = {'Date': [],
> 'Zero Rates': [],
> 'Forward Rates': [],
> 'Discount Factors': []}
>
> for dt in curve.dates():
> node_data['Date'].append(dt)
> node_data['Zero Rates'].append(curve.zeroRate(dt, day_count, ql.Annual).rate())
> node_data['Forward Rates'].append(curve.forwardRate(dt, dt + ql.Period(1, ql.Years), day_count, ql.Annual).rate())
> node_data['Discount Factors'].append(curve.discount(dt))
>
> node_dataframe = pd.DataFrame(node_data)
>
> print(node_dataframe)
>
> node_dataframe.to_excel('NodeRates.xlsx')
>
> # Printing Daily Zero Rates:
> # Prints the daily zero rates
> # It calculates and prints the zero rates for each year using the constructed yield curve.
> maturity_date = calendar.advance(today, ql.Period(1, ql.Years))
> current_date = today
> while current_date <= maturity_date:
> zero_rate = curve.zeroRate(current_date, day_count, ql.Annual).rate()
> print(f"Date: {current_date}, Zero Rate: {zero_rate}")
> current_date = calendar.advance(current_date, ql.Period(1, ql.Years))
>
> # Creating Curve Data for Plotting:
> # Creates lists of curve dates, zero rates, and forward rates for plotting.
> # It calculates both zero rates and forward rates for each year up to 15 years from the current date.
> curve_dates = [today + ql.Period(i, ql.Years)
> for i in range(15)]
> curve_zero_rates = [curve.zeroRate(date, day_count, ql.Annual).rate()
> for date in curve_dates]
>
> # Converting ql.Date to Numerical Values: (years from today)
> # Converts the curve dates (ql.Date objects) to numerical values representing years from the current
> # date. This is done to prepare the data for plotting on the x-axis.
> numeric_dates = [(date - today) / 365 for date in curve_dates]
>
> # Plotting:
> # Creates a plot showing the zero rates and forward rates over time.
> # The x-axis represents the years from the current date, and the y-axis represents the interest rates.
> # The plot displays two lines: one for zero rates (blue) and another for forward rates (red).
> # The plot is labeled, grid lines are added, and the visualization is displayed using
> plt.figure(figsize=(10, 6))
> plt.plot(numeric_dates, curve_zero_rates, marker='', linestyle='-', color='b', label='Zero Rates')
> plt.title('Zero Rates')
> plt.xlabel('Years from Today')
> plt.ylabel('Rate')
> plt.legend()
> plt.grid(True)
> plt.xticks(rotation=0)
> plt.tight_layout()
>
> plt.show()
>
> tenors = ['3M', '6M', '9M', '1Y', '2Y', '3Y', '5Y', '7Y', '10Y', '15Y']
>
> # Print the Zero Rates, Forward Rates, and Discount Factors at Instrument maturity dates
> node_data = {'Maturity Date': [],
> 'Tenors': [],
> 'Zero Rates': [],
> 'Forward Rates': [],
> 'Discount Factors': []}
>
> for tenor in tenors:
> maturity_date = calendar.advance(today, ql.Period(tenor), ql.ModifiedFollowing) # Calculate the maturity date
> node_data['Maturity Date'].append(maturity_date)
> node_data['Tenors'].append(tenor)
> node_data['Zero Rates'].append(curve.zeroRate(maturity_date, day_count, ql.Annual).rate())
> node_data['Forward Rates'].append(curve.forwardRate(maturity_date, maturity_date + ql.Period(0, ql.Years), day_count, ql.Annual).rate())
> node_data['Discount Factors'].append(curve.discount(maturity_date))
>
> node_dataframe = pd.DataFrame(node_data)
>
> print(node_dataframe)
>
> node_dataframe.to_excel('NodeRates.xlsx')
>
> # Create a DataFrame to store bond results
> bond_results = {'Issue Date': [],
> 'Maturity Date': [],
> 'Coupon Rate': [],
> 'Price': [],
> 'Settlement Days': [],
> 'Yield': [],
> 'Clean Price': [],
> 'Dirty Price': []}
>
> # Calculate bond prices and yields
> for issue_date, maturity, coupon, price, settlement_days in data:
> price = ql.QuoteHandle(ql.SimpleQuote(price))
> issue_date = ql.Date(issue_date, '%d-%m-%Y')
> maturity = ql.Date(maturity, '%d-%m-%Y')
> schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
> bondEngine = ql.DiscountingBondEngine(curve)
> bond = ql.FixedRateBond(settlement_days, faceAmount, schedule, [coupon / 100], day_count)
> bond.setPricingEngine(bondEngine)
>
> # Calculate bond yield, clean price, and dirty price
> bondYield = bond.bondYield()
> bondCleanPrice = bond.cleanPrice()
> bondDirtyPrice = bond.dirtyPrice()
>
> # Append the results to the DataFrame
> bond_results['Issue Date'].append(issue_date)
> bond_results['Maturity Date'].append(maturity)
> bond_results['Coupon Rate'].append(coupon)
> bond_results['Price'].append(price.value())
> bond_results['Settlement Days'].append(settlement_days)
> bond_results['Yield'].append(bondYield)
> bond_results['Clean Price'].append(bondCleanPrice)
> bond_results['Dirty Price'].append(bondDirtyPrice)
>
> # Create a DataFrame from the bond results
> bond_results_df = pd.DataFrame(bond_results)
>
> # Print the results
> print(bond_results_df)
>
> Thanks & regards,
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
|
|
From: Quant <qua...@gm...> - 2023-11-27 08:38:27
|
Hi QuantLib Users,
I have data containing Bond information and I managed to use this
information to bootstrap the zero curve. To check if my zero curve is
correct, I would like to reprice the Bonds using the bootstrapped curve
(using the zero curve) to get back to the quoted prices of the Bonds. I am
getting the following errors on the repricing part and if anyone can help I
would appreciate;
Traceback (most recent call last):
File "/Users/Library/CloudStorage/OneDrive-Personal/QuantLib
Software/Valuations/IRS using Bond Bootstrapping/IRS using Bond
Bootstrapping 2.py", line 369, in <module>
bondEngine = ql.DiscountingBondEngine(curve)
File "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py",
line 25290, in __init__
_QuantLib.DiscountingBondEngine_swiginit(self,
_QuantLib.new_DiscountingBondEngine(discountCurve))
TypeError: in method 'new_DiscountingBondEngine', argument 1 of type
'Handle< YieldTermStructure > const &'
Find below the code that I am running;
# Importing Libraries:# The code imports necessary libraries:# pandas
for data manipulation, matplotlib.pyplot for plotting, and QuantLib
(ql) for quantitative finance calculations.import pandas as pdimport
matplotlib.pyplot as plt# Use the QuantLib or ORE Librariesimport
QuantLib as ql
# Setting Evaluation Date:# Sets the evaluation date
today = ql.Date(21, ql.November, 2023)
ql.Settings.instance().evaluationDate = today
# Calendar and Day Count:# Creates a calendar object and specifies the
day-count convention (Actual/365 Fixed)
calendar = ql.NullCalendar()
day_count = ql.Actual365Fixed()
# Settlement Days:
zero_coupon_settlement_days = 4
coupon_bond_settlement_days = 3
# Face Value
faceAmount = 100
data = [
('11-09-2023', '11-12-2023', 0, 99.524, zero_coupon_settlement_days),
('11-09-2023', '11-03-2024', 0, 96.539, zero_coupon_settlement_days),
('11-09-2023', '10-06-2024', 0, 93.552, zero_coupon_settlement_days),
('11-09-2023', '09-09-2024', 0, 89.510, zero_coupon_settlement_days),
('22-08-2022', '22-08-2024', 9.0, 96.406933, coupon_bond_settlement_days),
('27-06-2022', '27-06-2025', 10.0, 88.567570, coupon_bond_settlement_days),
('27-06-2022', '27-06-2027', 11.0, 71.363073, coupon_bond_settlement_days),
('22-08-2022', '22-08-2029', 12.0, 62.911623, coupon_bond_settlement_days),
('27-06-2022', '27-06-2032', 13.0, 55.976845, coupon_bond_settlement_days),
('22-08-2022', '22-08-2037', 14.0, 52.656596, coupon_bond_settlement_days)]
helpers = []
for issue_date, maturity, coupon, price, settlement_days in data:
price = ql.QuoteHandle(ql.SimpleQuote(price))
issue_date = ql.Date(issue_date, '%d-%m-%Y')
maturity = ql.Date(maturity, '%d-%m-%Y')
schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
helper = ql.FixedRateBondHelper(price, settlement_days,
faceAmount, schedule, [coupon / 100], day_count,
False)
helpers.append(helper)
curve = ql.PiecewiseCubicZero(today, helpers, day_count)
# Enable Extrapolation:# This line enables extrapolation for the yield
curve.# Extrapolation allows the curve to provide interest rates or
rates beyond the observed data points,# which can be useful for
pricing or risk management purposes.
curve.enableExtrapolation()
# Zero Rate and Discount Rate Calculation:# Calculates and prints the
zero rate and discount rate at a specific# future date (May 28, 2048)
using the constructed yield curve.
date = ql.Date(28, ql.May, 2024)
zero_rate = curve.zeroRate(date, day_count, ql.Annual).rate()
forward_rate = curve.forwardRate(date, date + ql.Period(1, ql.Years),
day_count, ql.Annual).rate()
discount_rate = curve.discount(date)print("Zero rate as at 28.05.2048:
" + str(round(zero_rate*100, 4)) + str("%"))print("Forward rate as at
28.05.2048: " + str(round(forward_rate*100, 4)) +
str("%"))print("Discount factor as at 28.05.2048: " +
str(round(discount_rate, 4)))
# Print the Zero Rates, Forward Rates and Discount Factors at node
dates# print(pd.DataFrame(curve.nodes()))
node_data = {'Date': [],
'Zero Rates': [],
'Forward Rates': [],
'Discount Factors': []}
for dt in curve.dates():
node_data['Date'].append(dt)
node_data['Zero Rates'].append(curve.zeroRate(dt, day_count,
ql.Annual).rate())
node_data['Forward Rates'].append(curve.forwardRate(dt, dt +
ql.Period(1, ql.Years), day_count, ql.Annual).rate())
node_data['Discount Factors'].append(curve.discount(dt))
node_dataframe = pd.DataFrame(node_data)
print(node_dataframe)
node_dataframe.to_excel('NodeRates.xlsx')
# Printing Daily Zero Rates:# Prints the daily zero rates# It
calculates and prints the zero rates for each year using the
constructed yield curve.
maturity_date = calendar.advance(today, ql.Period(1, ql.Years))
current_date = todaywhile current_date <= maturity_date:
zero_rate = curve.zeroRate(current_date, day_count, ql.Annual).rate()
print(f"Date: {current_date}, Zero Rate: {zero_rate}")
current_date = calendar.advance(current_date, ql.Period(1, ql.Years))
# Creating Curve Data for Plotting:# Creates lists of curve dates,
zero rates, and forward rates for plotting.# It calculates both zero
rates and forward rates for each year up to 15 years from the current
date.
curve_dates = [today + ql.Period(i, ql.Years)
for i in range(15)]
curve_zero_rates = [curve.zeroRate(date, day_count, ql.Annual).rate()
for date in curve_dates]
# Converting ql.Date to Numerical Values: (years from today)# Converts
the curve dates (ql.Date objects) to numerical values representing
years from the current# date. This is done to prepare the data for
plotting on the x-axis.
numeric_dates = [(date - today) / 365 for date in curve_dates]
# Plotting:# Creates a plot showing the zero rates and forward rates
over time.# The x-axis represents the years from the current date, and
the y-axis represents the interest rates.# The plot displays two
lines: one for zero rates (blue) and another for forward rates (red).#
The plot is labeled, grid lines are added, and the visualization is
displayed using
plt.figure(figsize=(10, 6))
plt.plot(numeric_dates, curve_zero_rates, marker='', linestyle='-',
color='b', label='Zero Rates')
plt.title('Zero Rates')
plt.xlabel('Years from Today')
plt.ylabel('Rate')
plt.legend()
plt.grid(True)
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()
tenors = ['3M', '6M', '9M', '1Y', '2Y', '3Y', '5Y', '7Y', '10Y', '15Y']
# Print the Zero Rates, Forward Rates, and Discount Factors at
Instrument maturity dates
node_data = {'Maturity Date': [],
'Tenors': [],
'Zero Rates': [],
'Forward Rates': [],
'Discount Factors': []}
for tenor in tenors:
maturity_date = calendar.advance(today, ql.Period(tenor),
ql.ModifiedFollowing) # Calculate the maturity date
node_data['Maturity Date'].append(maturity_date)
node_data['Tenors'].append(tenor)
node_data['Zero Rates'].append(curve.zeroRate(maturity_date,
day_count, ql.Annual).rate())
node_data['Forward Rates'].append(curve.forwardRate(maturity_date,
maturity_date + ql.Period(0, ql.Years), day_count, ql.Annual).rate())
node_data['Discount Factors'].append(curve.discount(maturity_date))
node_dataframe = pd.DataFrame(node_data)
print(node_dataframe)
node_dataframe.to_excel('NodeRates.xlsx')
# Create a DataFrame to store bond results
bond_results = {'Issue Date': [],
'Maturity Date': [],
'Coupon Rate': [],
'Price': [],
'Settlement Days': [],
'Yield': [],
'Clean Price': [],
'Dirty Price': []}
# Calculate bond prices and yieldsfor issue_date, maturity, coupon,
price, settlement_days in data:
price = ql.QuoteHandle(ql.SimpleQuote(price))
issue_date = ql.Date(issue_date, '%d-%m-%Y')
maturity = ql.Date(maturity, '%d-%m-%Y')
schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
bondEngine = ql.DiscountingBondEngine(curve)
bond = ql.FixedRateBond(settlement_days, faceAmount, schedule,
[coupon / 100], day_count)
bond.setPricingEngine(bondEngine)
# Calculate bond yield, clean price, and dirty price
bondYield = bond.bondYield()
bondCleanPrice = bond.cleanPrice()
bondDirtyPrice = bond.dirtyPrice()
# Append the results to the DataFrame
bond_results['Issue Date'].append(issue_date)
bond_results['Maturity Date'].append(maturity)
bond_results['Coupon Rate'].append(coupon)
bond_results['Price'].append(price.value())
bond_results['Settlement Days'].append(settlement_days)
bond_results['Yield'].append(bondYield)
bond_results['Clean Price'].append(bondCleanPrice)
bond_results['Dirty Price'].append(bondDirtyPrice)
# Create a DataFrame from the bond results
bond_results_df = pd.DataFrame(bond_results)
# Print the resultsprint(bond_results_df)
Thanks & regards,
|
|
From: Quant <qua...@gm...> - 2023-11-27 08:38:22
|
Hi QuantLib Users,
I have data containing Bond information and I managed to use this
information to bootstrap the zero curve. To check if my zero curve is
correct, I would like to reprice the Bonds using the bootstrapped curve
(using the zero curve) to get back to the quoted prices of the Bonds. I am
getting the following errors on the repricing part and if anyone can help I
would appreciate;
Traceback (most recent call last):
File "/Users/Library/CloudStorage/OneDrive-Personal/QuantLib
Software/Valuations/IRS using Bond Bootstrapping/IRS using Bond
Bootstrapping 2.py", line 369, in <module>
bondEngine = ql.DiscountingBondEngine(curve)
File "/usr/local/lib/python3.9/site-packages/QuantLib/QuantLib.py",
line 25290, in __init__
_QuantLib.DiscountingBondEngine_swiginit(self,
_QuantLib.new_DiscountingBondEngine(discountCurve))
TypeError: in method 'new_DiscountingBondEngine', argument 1 of type
'Handle< YieldTermStructure > const &'
Find below the code that I am running;
# Importing Libraries:# The code imports necessary libraries:# pandas
for data manipulation, matplotlib.pyplot for plotting, and QuantLib
(ql) for quantitative finance calculations.import pandas as pdimport
matplotlib.pyplot as plt# Use the QuantLib or ORE Librariesimport
QuantLib as ql
# Setting Evaluation Date:# Sets the evaluation date
today = ql.Date(21, ql.November, 2023)
ql.Settings.instance().evaluationDate = today
# Calendar and Day Count:# Creates a calendar object and specifies the
day-count convention (Actual/365 Fixed)
calendar = ql.NullCalendar()
day_count = ql.Actual365Fixed()
# Settlement Days:
zero_coupon_settlement_days = 4
coupon_bond_settlement_days = 3
# Face Value
faceAmount = 100
data = [
('11-09-2023', '11-12-2023', 0, 99.524, zero_coupon_settlement_days),
('11-09-2023', '11-03-2024', 0, 96.539, zero_coupon_settlement_days),
('11-09-2023', '10-06-2024', 0, 93.552, zero_coupon_settlement_days),
('11-09-2023', '09-09-2024', 0, 89.510, zero_coupon_settlement_days),
('22-08-2022', '22-08-2024', 9.0, 96.406933, coupon_bond_settlement_days),
('27-06-2022', '27-06-2025', 10.0, 88.567570, coupon_bond_settlement_days),
('27-06-2022', '27-06-2027', 11.0, 71.363073, coupon_bond_settlement_days),
('22-08-2022', '22-08-2029', 12.0, 62.911623, coupon_bond_settlement_days),
('27-06-2022', '27-06-2032', 13.0, 55.976845, coupon_bond_settlement_days),
('22-08-2022', '22-08-2037', 14.0, 52.656596, coupon_bond_settlement_days)]
helpers = []
for issue_date, maturity, coupon, price, settlement_days in data:
price = ql.QuoteHandle(ql.SimpleQuote(price))
issue_date = ql.Date(issue_date, '%d-%m-%Y')
maturity = ql.Date(maturity, '%d-%m-%Y')
schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
helper = ql.FixedRateBondHelper(price, settlement_days,
faceAmount, schedule, [coupon / 100], day_count,
False)
helpers.append(helper)
curve = ql.PiecewiseCubicZero(today, helpers, day_count)
# Enable Extrapolation:# This line enables extrapolation for the yield
curve.# Extrapolation allows the curve to provide interest rates or
rates beyond the observed data points,# which can be useful for
pricing or risk management purposes.
curve.enableExtrapolation()
# Zero Rate and Discount Rate Calculation:# Calculates and prints the
zero rate and discount rate at a specific# future date (May 28, 2048)
using the constructed yield curve.
date = ql.Date(28, ql.May, 2024)
zero_rate = curve.zeroRate(date, day_count, ql.Annual).rate()
forward_rate = curve.forwardRate(date, date + ql.Period(1, ql.Years),
day_count, ql.Annual).rate()
discount_rate = curve.discount(date)print("Zero rate as at 28.05.2048:
" + str(round(zero_rate*100, 4)) + str("%"))print("Forward rate as at
28.05.2048: " + str(round(forward_rate*100, 4)) +
str("%"))print("Discount factor as at 28.05.2048: " +
str(round(discount_rate, 4)))
# Print the Zero Rates, Forward Rates and Discount Factors at node
dates# print(pd.DataFrame(curve.nodes()))
node_data = {'Date': [],
'Zero Rates': [],
'Forward Rates': [],
'Discount Factors': []}
for dt in curve.dates():
node_data['Date'].append(dt)
node_data['Zero Rates'].append(curve.zeroRate(dt, day_count,
ql.Annual).rate())
node_data['Forward Rates'].append(curve.forwardRate(dt, dt +
ql.Period(1, ql.Years), day_count, ql.Annual).rate())
node_data['Discount Factors'].append(curve.discount(dt))
node_dataframe = pd.DataFrame(node_data)
print(node_dataframe)
node_dataframe.to_excel('NodeRates.xlsx')
# Printing Daily Zero Rates:# Prints the daily zero rates# It
calculates and prints the zero rates for each year using the
constructed yield curve.
maturity_date = calendar.advance(today, ql.Period(1, ql.Years))
current_date = todaywhile current_date <= maturity_date:
zero_rate = curve.zeroRate(current_date, day_count, ql.Annual).rate()
print(f"Date: {current_date}, Zero Rate: {zero_rate}")
current_date = calendar.advance(current_date, ql.Period(1, ql.Years))
# Creating Curve Data for Plotting:# Creates lists of curve dates,
zero rates, and forward rates for plotting.# It calculates both zero
rates and forward rates for each year up to 15 years from the current
date.
curve_dates = [today + ql.Period(i, ql.Years)
for i in range(15)]
curve_zero_rates = [curve.zeroRate(date, day_count, ql.Annual).rate()
for date in curve_dates]
# Converting ql.Date to Numerical Values: (years from today)# Converts
the curve dates (ql.Date objects) to numerical values representing
years from the current# date. This is done to prepare the data for
plotting on the x-axis.
numeric_dates = [(date - today) / 365 for date in curve_dates]
# Plotting:# Creates a plot showing the zero rates and forward rates
over time.# The x-axis represents the years from the current date, and
the y-axis represents the interest rates.# The plot displays two
lines: one for zero rates (blue) and another for forward rates (red).#
The plot is labeled, grid lines are added, and the visualization is
displayed using
plt.figure(figsize=(10, 6))
plt.plot(numeric_dates, curve_zero_rates, marker='', linestyle='-',
color='b', label='Zero Rates')
plt.title('Zero Rates')
plt.xlabel('Years from Today')
plt.ylabel('Rate')
plt.legend()
plt.grid(True)
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()
tenors = ['3M', '6M', '9M', '1Y', '2Y', '3Y', '5Y', '7Y', '10Y', '15Y']
# Print the Zero Rates, Forward Rates, and Discount Factors at
Instrument maturity dates
node_data = {'Maturity Date': [],
'Tenors': [],
'Zero Rates': [],
'Forward Rates': [],
'Discount Factors': []}
for tenor in tenors:
maturity_date = calendar.advance(today, ql.Period(tenor),
ql.ModifiedFollowing) # Calculate the maturity date
node_data['Maturity Date'].append(maturity_date)
node_data['Tenors'].append(tenor)
node_data['Zero Rates'].append(curve.zeroRate(maturity_date,
day_count, ql.Annual).rate())
node_data['Forward Rates'].append(curve.forwardRate(maturity_date,
maturity_date + ql.Period(0, ql.Years), day_count, ql.Annual).rate())
node_data['Discount Factors'].append(curve.discount(maturity_date))
node_dataframe = pd.DataFrame(node_data)
print(node_dataframe)
node_dataframe.to_excel('NodeRates.xlsx')
# Create a DataFrame to store bond results
bond_results = {'Issue Date': [],
'Maturity Date': [],
'Coupon Rate': [],
'Price': [],
'Settlement Days': [],
'Yield': [],
'Clean Price': [],
'Dirty Price': []}
# Calculate bond prices and yieldsfor issue_date, maturity, coupon,
price, settlement_days in data:
price = ql.QuoteHandle(ql.SimpleQuote(price))
issue_date = ql.Date(issue_date, '%d-%m-%Y')
maturity = ql.Date(maturity, '%d-%m-%Y')
schedule = ql.MakeSchedule(issue_date, maturity, ql.Period(ql.Semiannual))
bondEngine = ql.DiscountingBondEngine(curve)
bond = ql.FixedRateBond(settlement_days, faceAmount, schedule,
[coupon / 100], day_count)
bond.setPricingEngine(bondEngine)
# Calculate bond yield, clean price, and dirty price
bondYield = bond.bondYield()
bondCleanPrice = bond.cleanPrice()
bondDirtyPrice = bond.dirtyPrice()
# Append the results to the DataFrame
bond_results['Issue Date'].append(issue_date)
bond_results['Maturity Date'].append(maturity)
bond_results['Coupon Rate'].append(coupon)
bond_results['Price'].append(price.value())
bond_results['Settlement Days'].append(settlement_days)
bond_results['Yield'].append(bondYield)
bond_results['Clean Price'].append(bondCleanPrice)
bond_results['Dirty Price'].append(bondDirtyPrice)
# Create a DataFrame from the bond results
bond_results_df = pd.DataFrame(bond_results)
# Print the resultsprint(bond_results_df)
Thanks & regards,
|
|
From: Peter C. <pca...@gm...> - 2023-11-15 17:51:35
|
Hi Miguel and Ben, would you mind providing the modified example files and the error you get after the modification? Ideally open a PR adding your new example, then we can discuss and fix the issues on github? Thank you Peter On Wed, 15 Nov 2023 at 08:58, Ben Watson <ben...@ma...> wrote: > > I can't help but would also be interested in some workable examples using ORE.. > > > > On Wed, 15 Nov 2023, 4:04 pm Miguel Contreras, <con...@gm...> wrote: >> >> Hello everyone, >> >> >> >> I hope you are doing well. In our market risk team wish use ORE to model the XVA for our derivatives portfolio. We run some examples and try to customize the inputs for derivatives based on USD currency. We replace the currency, index curves, the models and market data by USD Currency, USD-SOFR, USD-SOFR-3M and so on. >> >> >> Unfortunately, when we run the examples again ( the example 1), we get some errors. We’d like to know if you can send us some examples based on USD currency, SOFR or SOFR Term 3m. We’ll really appreciate if you can share us some examples for an IRS USD Fixed – Float, a CCS USD float – EUR fixed for instance, and FX Forward EUR-USD. Thanks in advanced. >> >> >> >> All the best, >> >> >> >> Miguel A. Contreras >> _______________________________________________ >> 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: Ben W. <ben...@ma...> - 2023-11-15 07:57:47
|
I can't help but would also be interested in some workable examples using ORE.. On Wed, 15 Nov 2023, 4:04 pm Miguel Contreras, <con...@gm...> wrote: > Hello everyone, > > > > I hope you are doing well. In our market risk team wish use ORE to model > the XVA for our derivatives portfolio. We run some examples and try to > customize the inputs for derivatives based on USD currency. We replace the > currency, index curves, the models and market data by USD Currency, > USD-SOFR, USD-SOFR-3M and so on. > > > Unfortunately, when we run the examples again ( the example 1), we get > some errors. We’d like to know if you can send us some examples based on > USD currency, SOFR or SOFR Term 3m. We’ll really appreciate if you can > share us some examples for an IRS USD Fixed – Float, a CCS USD float – EUR > fixed for instance, and FX Forward EUR-USD. Thanks in advanced. > > > > All the best, > > > Miguel A. Contreras > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Miguel C. <con...@gm...> - 2023-11-15 05:03:33
|
Hello everyone, I hope you are doing well. In our market risk team wish use ORE to model the XVA for our derivatives portfolio. We run some examples and try to customize the inputs for derivatives based on USD currency. We replace the currency, index curves, the models and market data by USD Currency, USD-SOFR, USD-SOFR-3M and so on. Unfortunately, when we run the examples again ( the example 1), we get some errors. We’d like to know if you can send us some examples based on USD currency, SOFR or SOFR Term 3m. We’ll really appreciate if you can share us some examples for an IRS USD Fixed – Float, a CCS USD float – EUR fixed for instance, and FX Forward EUR-USD. Thanks in advanced. All the best, Miguel A. Contreras |
|
From: kmylonakis <kmy...@pr...> - 2023-11-13 12:40:25
|
Hi all, I would like to have a look at the 1F Gaussian Copula model that i see is implemented in the experimental directory and would like to ask if this class is readily exposed via SWIG to Python. I could not find it myself and wondering if there is something that I am missing. And one more question since I am new to QL. Generaly what is the meaning of the classes under experimental, does it mean not validated? Thank you very much in advance. Kostas |
|
From: Tom A. <tw...@ur...> - 2023-11-08 14:44:22
|
On Fri, 3 Nov 2023, ze73 man via QuantLib-users wrote: > I might be misunderstanding your last message, Trent. Take for example > the 3-Month EuriBor Nov '23, expiring on 13 Nov 2024 (as also confirmed > by ICE). What iborStartDate is ql.FuturesRateHelper expecting for this > contract? I thought this needed a "type" argument different than > Futures::IMM since none of these dates are IMM dates that are also not > matching the dates obtained with ql.IMM.nextDate()? iborStartDate should be the start date, aka value date, of the notional deposit underlying the future [1], which should be the third wednesday of the month, which we somewhat loosely call an IMM date. The expiry date is two business days before this. The name is a bit confusing, but reflects the fact that the future finally settles to the inter-bank offered rate for deposits starting on that date. The FuturesRateHelper checks that the iborStartDate is an IMM date, with the mainCycle parameter set to false, which means it accepts the third wednesday of any month. This is exactly what you want. You also mentioned calendars. The only use of the calendar in the FuturesRateHelper is to work out the maturity date of the notional deposit, based on the value date. That should be done using the calendar native to the market in which these notional deposits are made, which is the index's calendar (TARGET), not the exchange's calendar. You would only need the exchange calendar to work out the expiry date from the value date, but happily you already know the expiry date. Does this sound like it addresses your concerns? Or have i misunderstood? Incidentally, it seems like you are trying to build a curve using Euribor serials. Note that these are spaced at one month intervals, but are based on three month deposits, meaning that they sample heavily overlapping parts of the yield curve. Using a bootstrap process like QuantLib's, even the slightest inconsistency in their pricing will result in an extremely janky curve, which will give you implausible forecasts. I and others on this list have had a bad time with curve constructions like this. By all means try it, but i suggest you plot the daily instantaneous forward rates at your earliest opportunity - then when you see what a mess it is, try a different approach. tom [1] Futures like this are actually not formally defined in terms of notional deposits any more, but just in terms of the index and a formula which happens to match that for a deposit. This is to do with some silly risk rules which required derivatives on deposits to be treated as deposits in some situations, ie each contract counted as a million euros on your books. > Thank you! > > > On Thursday, November 2, 2023 at 05:08:19 PM EDT, Trent Maetzold <tr...@ma...> wrote: > > I’m looking at mine and they follow imm dates, monthly starts for the first six contracts then the standard imm dates for the next 6. Use ql.IMM.nextDate(date, False) to get the series of monthly IMM dates. > Then pass the start and end date to the futures rate helper constructor. > Sent from Proton Mail for iOS > > On Thu, Nov 2, 2023 at 15:55, ze73 man <ze7...@ya...> wrote: > Thanks, Trent. I followed your suggestion and created a new index. > However ql.FuturesRateHelper expects IMM futures and checks for IMM dates here so I get the error below. It seems the only way to use the rate helper with non-IMM futures is to add support for it in C++ and recompile quantlib? These futures are trading on ICE Futures Europe (Three Month Euribor Futures) and the expiration schedules are different. I don't see a way to use the underlying RateHelper class or /BootstrapHelper template in Python. > RuntimeError: November 13th, 2023 is not a valid IMM date > Any thoughts on this are welcome. Thanks, everyone! > On Wednesday, November 1, 2023 at 06:33:11 PM EDT, Trent Maetzold <tr...@ma...> wrote: > > Create the IborIndex directly. https://quantlib-python-docs.readthedocs.io/en/latest/indexes.html#ql.IborIndex > Sent from Proton Mail for iOS > > On Wed, Nov 1, 2023 at 17:27, ze73 man via QuantLib-users <qua...@li...> wrote: > Hi QuantLib Gurus! > I am experimenting with ql.FuturesRateHelper to use this market data 3-Month EuriBor Futures Prices to evaluate if a EURIBOR forward curve created this way might be viable for my use-case. The index class ql.Euribor3M() in theory facilitates the setup however it represents the IMM index so the calendar is different, the expiration dates different, etc... > I did see a FuturesEU calendar in the QuantExt project derived from QuantLib, meant to represent the ICE Futures Europe calendar, which could be a starting point, but is there no standard ql.Euribor3M() equivalent in quantlib for ICE? Does anyone know of an example set up of a ICE Europe futures contract using quantlib, please? Would this warrant a new rate helper or at least new index class? > Kind regards > > Ze > > | > | > | > | | | > > | > > | > | > | | > 3-Month EuriBor Prices and 3-Month EuriBor Futures Prices - Barchart.com > > Today's 3-Month EuriBor prices with latest 3-Month EuriBor charts, news and 3-Month EuriBor futures quotes. > | > > | > > | > > > > > > > -- "Ah", said Arthur, "this is obviously some strange usage of the word 'safe' that I wasn't previously aware of." |
|
From: ze73 m. <ze7...@ya...> - 2023-11-03 22:28:51
|
After recompiling quantlib without the IMM date check, it seems to work as expected when using a variant of ql.FuturesRateHelper that does not need it to determine the maturity. Thanks.
On Friday, November 3, 2023 at 11:13:44 AM EDT, ze73 man via QuantLib-users <qua...@li...> wrote:
Hi Trent, looking at the underlying implementation here, these other contructors also verifies that the iborStartDate is an IMM date.
On Friday, November 3, 2023 at 10:24:19 AM EDT, Trent Maetzold <tr...@ma...> wrote:
The FuturesRateHelper constructor is overloaded. There is a definition that takes a start date and end date instead of calculating it internally. Try this one.
Sent with Proton Mail secure email.
------- Original Message -------
On Friday, November 3rd, 2023 at 09:20, ze73 man <ze7...@ya...> wrote:
I might be misunderstanding your last message, Trent. Take for example the 3-Month EuriBor Nov '23, expiring on 13 Nov 2024 (as also confirmed by ICE). What iborStartDate is ql.FuturesRateHelper expecting for this contract? I thought this needed a "type" argument different than Futures::IMM since none of these dates are IMM dates that are also not matching the dates obtained with ql.IMM.nextDate()?
Thank you!
On Thursday, November 2, 2023 at 05:08:19 PM EDT, Trent Maetzold <tr...@ma...> wrote:
I’m looking at mine and they follow imm dates, monthly starts for the first six contracts then the standard imm dates for the next 6. Use ql.IMM.nextDate(date, False) to get the series of monthly IMM dates.
Then pass the start and end date to the futures rate helper constructor.
Sent from Proton Mail for iOS
On Thu, Nov 2, 2023 at 15:55, ze73 man <ze7...@ya...> wrote:
Thanks, Trent. I followed your suggestion and created a new index.
However ql.FuturesRateHelper expects IMM futures and checks for IMM dates here so I get the error below. It seems the only way to use the rate helper with non-IMM futures is to add support for it in C++ and recompile quantlib? These futures are trading on ICE Futures Europe (Three Month Euribor Futures) and the expiration schedules are different. I don't see a way to use the underlying RateHelper class or /BootstrapHelper template in Python.
RuntimeError: November 13th, 2023 is not a valid IMM date
Any thoughts on this are welcome. Thanks, everyone!
On Wednesday, November 1, 2023 at 06:33:11 PM EDT, Trent Maetzold <tr...@ma...> wrote:
Create the IborIndex directly. https://quantlib-python-docs.readthedocs.io/en/latest/indexes.html#ql.IborIndex
Sent from Proton Mail for iOS
On Wed, Nov 1, 2023 at 17:27, ze73 man via QuantLib-users <qua...@li...> wrote:
Hi QuantLib Gurus!
I am experimenting with ql.FuturesRateHelper to use this market data 3-Month EuriBor Futures Prices to evaluate if a EURIBOR forward curve created this way might be viable for my use-case. The index class ql.Euribor3M() in theory facilitates the setup however it represents the IMM index so the calendar is different, the expiration dates different, etc...
I did see a FuturesEU calendar in the QuantExt project derived from QuantLib, meant to represent the ICE Futures Europe calendar, which could be a starting point, but is there no standard ql.Euribor3M() equivalent in quantlib for ICE? Does anyone know of an example set up of a ICE Europe futures contract using quantlib, please? Would this warrant a new rate helper or at least new index class?
Kind regards
Ze
|
|
|
| | |
|
|
|
| |
3-Month EuriBor Prices and 3-Month EuriBor Futures Prices - Barchart.com
Today's 3-Month EuriBor prices with latest 3-Month EuriBor charts, news and 3-Month EuriBor futures quotes.
|
|
|
_______________________________________________
QuantLib-users mailing list
Qua...@li...
https://lists.sourceforge.net/lists/listinfo/quantlib-users
|
|
From: ze73 m. <ze7...@ya...> - 2023-11-03 15:10:45
|
Hi Trent, looking at the underlying implementation here, these other contructors also verifies that the iborStartDate is an IMM date.
On Friday, November 3, 2023 at 10:24:19 AM EDT, Trent Maetzold <tr...@ma...> wrote:
The FuturesRateHelper constructor is overloaded. There is a definition that takes a start date and end date instead of calculating it internally. Try this one.
Sent with Proton Mail secure email.
------- Original Message -------
On Friday, November 3rd, 2023 at 09:20, ze73 man <ze7...@ya...> wrote:
I might be misunderstanding your last message, Trent. Take for example the 3-Month EuriBor Nov '23, expiring on 13 Nov 2024 (as also confirmed by ICE). What iborStartDate is ql.FuturesRateHelper expecting for this contract? I thought this needed a "type" argument different than Futures::IMM since none of these dates are IMM dates that are also not matching the dates obtained with ql.IMM.nextDate()?
Thank you!
On Thursday, November 2, 2023 at 05:08:19 PM EDT, Trent Maetzold <tr...@ma...> wrote:
I’m looking at mine and they follow imm dates, monthly starts for the first six contracts then the standard imm dates for the next 6. Use ql.IMM.nextDate(date, False) to get the series of monthly IMM dates.
Then pass the start and end date to the futures rate helper constructor.
Sent from Proton Mail for iOS
On Thu, Nov 2, 2023 at 15:55, ze73 man <ze7...@ya...> wrote:
Thanks, Trent. I followed your suggestion and created a new index.
However ql.FuturesRateHelper expects IMM futures and checks for IMM dates here so I get the error below. It seems the only way to use the rate helper with non-IMM futures is to add support for it in C++ and recompile quantlib? These futures are trading on ICE Futures Europe (Three Month Euribor Futures) and the expiration schedules are different. I don't see a way to use the underlying RateHelper class or /BootstrapHelper template in Python.
RuntimeError: November 13th, 2023 is not a valid IMM date
Any thoughts on this are welcome. Thanks, everyone!
On Wednesday, November 1, 2023 at 06:33:11 PM EDT, Trent Maetzold <tr...@ma...> wrote:
Create the IborIndex directly. https://quantlib-python-docs.readthedocs.io/en/latest/indexes.html#ql.IborIndex
Sent from Proton Mail for iOS
On Wed, Nov 1, 2023 at 17:27, ze73 man via QuantLib-users <qua...@li...> wrote:
Hi QuantLib Gurus!
I am experimenting with ql.FuturesRateHelper to use this market data 3-Month EuriBor Futures Prices to evaluate if a EURIBOR forward curve created this way might be viable for my use-case. The index class ql.Euribor3M() in theory facilitates the setup however it represents the IMM index so the calendar is different, the expiration dates different, etc...
I did see a FuturesEU calendar in the QuantExt project derived from QuantLib, meant to represent the ICE Futures Europe calendar, which could be a starting point, but is there no standard ql.Euribor3M() equivalent in quantlib for ICE? Does anyone know of an example set up of a ICE Europe futures contract using quantlib, please? Would this warrant a new rate helper or at least new index class?
Kind regards
Ze
|
|
|
| | |
|
|
|
| |
3-Month EuriBor Prices and 3-Month EuriBor Futures Prices - Barchart.com
Today's 3-Month EuriBor prices with latest 3-Month EuriBor charts, news and 3-Month EuriBor futures quotes.
|
|
|
|
|
From: Trent M. <tr...@ma...> - 2023-11-03 14:24:32
|
The FuturesRateHelper constructor is overloaded. There is a definition that takes a start date and end date instead of calculating it internally. Try [this one](https://quantlib-python-docs.readthedocs.io/en/latest/thelpers.html#id11). Sent with [Proton Mail](https://proton.me/) secure email. ------- Original Message ------- On Friday, November 3rd, 2023 at 09:20, ze73 man <ze7...@ya...> wrote: > I might be misunderstanding your last message, Trent. Take for example the [3-Month EuriBor Nov '23](https://www.barchart.com/futures/quotes/IMX23/overview), expiring on 13 Nov 2024 (as also confirmed by [ICE](https://www.ice.com/products/38527986/Three-Month-Euribor-Futures/expiry)). What iborStartDate is ql.FuturesRateHelper expecting for this contract? I thought this needed a "type" argument different than Futures::IMM since none of these dates are IMM dates that are also not matching the dates obtained with ql.IMM.nextDate()? > > Thank you! > > On Thursday, November 2, 2023 at 05:08:19 PM EDT, Trent Maetzold <tr...@ma...> wrote: > > I’m looking at mine and they follow imm dates, monthly starts for the first six contracts then the standard imm dates for the next 6. Use ql.IMM.nextDate(date, False) to get the series of monthly IMM dates. > > Then pass the start and end date to the futures rate helper constructor. > > Sent from [Proton Mail](https://proton.me/mail/home) for iOS > > On Thu, Nov 2, 2023 at 15:55, ze73 man <[ze7...@ya...](mailto:On Thu, Nov 2, 2023 at 15:55, ze73 man <<a href=)> wrote: > >> Thanks, Trent. I followed your suggestion and created a new index. >> >> However ql.FuturesRateHelper expects IMM futures and checks for IMM dates [here](https://github.com/quantlib/QuantLib/blob/master/ql/termstructures/yield/ratehelpers.cpp) so I get the error below. It seems the only way to use the rate helper with non-IMM futures is to add support for it in C++ and recompile quantlib? These futures are trading on ICE Futures Europe ([Three Month Euribor Futures](https://www.ice.com/products/38527986/Three-Month-Euribor-Futures)) and the expiration schedules are different. I don't see a way to use the underlying RateHelper class or /BootstrapHelper template in Python. >> >> RuntimeError: November 13th, 2023 is not a valid IMM date >> >> Any thoughts on this are welcome. Thanks, everyone! >> >> On Wednesday, November 1, 2023 at 06:33:11 PM EDT, Trent Maetzold <tr...@ma...> wrote: >> >> Create the IborIndex directly. https://quantlib-python-docs.readthedocs.io/en/latest/indexes.html#ql.IborIndex >> >> Sent from [Proton Mail](https://proton.me/mail/home) for iOS >> >> On Wed, Nov 1, 2023 at 17:27, ze73 man via QuantLib-users <[qua...@li...](mailto:On Wed, Nov 1, 2023 at 17:27, ze73 man via QuantLib-users <<a href=)> wrote: >> >>> Hi QuantLib Gurus! >>> >>> I am experimenting with ql.FuturesRateHelper to use this market data [3-Month EuriBor Futures Prices](https://www.barchart.com/futures/quotes/IMX23/futures-prices) to evaluate if a EURIBOR forward curve created this way might be viable for my use-case. The index class ql.Euribor3M() in theory facilitates the setup however it represents the IMM index so the calendar is different, the expiration dates different, etc... >>> >>> I did see a FuturesEU calendar in the QuantExt project derived from QuantLib, meant to represent the ICE Futures Europe calendar, which could be a starting point, but is there no standard ql.Euribor3M() equivalent in quantlib for ICE? Does anyone know of an example set up of a ICE Europe futures contract using quantlib, please? Would this warrant a new rate helper or at least new index class? >>> >>> Kind regards >>> >>> Ze >>> >>> https://www.barchart.com/futures/quotes/IMX23/futures-prices >>> >>> 3-Month EuriBor Prices and 3-Month EuriBor Futures Prices - Barchart.com >>> >>> Today's 3-Month EuriBor prices with latest 3-Month EuriBor charts, news and 3-Month EuriBor futures quotes. |