|
From: Philippe H. <phi...@ex...> - 2023-12-18 18:49:56
|
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">That’s the other solution that always works but it’s just more code. It s a bit weird that the instrument level NPV() method cannot take a settle date. Your decisions on how to proceed are going to be driven by how much code you want to so yourself and speed considerations. <br id="lineBreakAtBeginningOfSignature"><div dir="ltr">Regards<div><br></div><div>Philippe Hatstadt</div><div>+1-203-252-0408</div><div><br></div></div><div dir="ltr"><br><blockquote type="cite">On Dec 18, 2023, at 6:24 PM, Quant <qua...@gm...> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><div dir="ltr">Hi Philippe,<div><br></div><div>Thanks for the reply. I kept on researching and I found a workaround of dividing the discount factors from evaluation date to accrual end date by the discount factor from evaluation date to bond settlement date as shown in the code below;</div><div><br></div><div><div style="background-color:rgb(30,31,34);color:rgb(188,190,196)"><pre style="font-family:"JetBrains Mono",monospace">fields = [<span style="color:rgb(106,171,115)">'accrualStartDate'</span>, <span style="color:rgb(106,171,115)">'accrualEndDate'</span>, <span style="color:rgb(106,171,115)">'date'</span>, <span style="color:rgb(106,171,115)">'nominal'</span>, <span style="color:rgb(106,171,115)">'rate'</span>,<br> <span style="color:rgb(106,171,115)">'amount'</span>, <span style="color:rgb(106,171,115)">'accrualDays'</span>, <span style="color:rgb(106,171,115)">'accrualPeriod'</span>]<br>BondCashflows = []<br><span style="color:rgb(207,142,109)">for </span>cf <span style="color:rgb(207,142,109)">in </span><span style="color:rgb(136,136,198)">list</span>(<span style="color:rgb(136,136,198)">map</span>(ql.as_fixed_rate_coupon, bond.cashflows()))[:-<span style="color:rgb(42,172,184)">1</span>]:<br> row = {fld: <span style="color:rgb(136,136,198)">eval</span>(<span style="color:rgb(106,171,115)">f"cf.</span><span style="color:rgb(207,142,109)">{</span>fld<span style="color:rgb(207,142,109)">}</span><span style="color:rgb(106,171,115)">()"</span>) <span style="color:rgb(207,142,109)">for </span>fld <span style="color:rgb(207,142,109)">in </span>fields}<br> row[<span style="color:rgb(106,171,115)">'AccrualPeriod'</span>] = <span style="color:rgb(136,136,198)">round</span>((row[<span style="color:rgb(106,171,115)">'accrualEndDate'</span>] - row[<span style="color:rgb(106,171,115)">'accrualStartDate'</span>]) / <span style="color:rgb(42,172,184)">365</span>, <span style="color:rgb(42,172,184)">4</span>)<br> <span style="color:rgb(207,142,109)">if </span>row[<span style="color:rgb(106,171,115)">'date'</span>] >= today:<br> row[<span style="color:rgb(106,171,115)">'ZeroRate (NPV)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.zeroRate(row[<span style="color:rgb(106,171,115)">'date'</span>], day_count, ql.Compounded, ql.Annual).rate(), <span style="color:rgb(42,172,184)">9</span>)<br> row[<span style="color:rgb(106,171,115)">'ZeroRate (Dirty Price)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.forwardRate(bond.settlementDate(), row[<span style="color:rgb(106,171,115)">'date'</span>], day_count, ql.Compounded, ql.Annual).rate(), <span style="color:rgb(42,172,184)">9</span>)<br> row[<span style="color:rgb(106,171,115)">'DiscFactor (NPV)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.discount(row[<span style="color:rgb(106,171,115)">'date'</span>]), <span style="color:rgb(42,172,184)">9</span>)<br> row[<span style="color:rgb(106,171,115)">'DiscFactor (Dirty Price)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.discount(row[<span style="color:rgb(106,171,115)">'date'</span>]) / curve.discount(bond.settlementDate()), <span style="color:rgb(42,172,184)">9</span>)<br> <span style="color:rgb(207,142,109)">else</span>:<br> row[<span style="color:rgb(106,171,115)">'ZeroRate (NPV)'</span>] = <span style="color:rgb(42,172,184)">0<br></span><span style="color:rgb(42,172,184)"> </span>row[<span style="color:rgb(106,171,115)">'ZeroRate (Dirty Price)'</span>] = <span style="color:rgb(42,172,184)">0<br></span><span style="color:rgb(42,172,184)"> </span>row[<span style="color:rgb(106,171,115)">'DiscFactor (NPV)'</span>] = <span style="color:rgb(42,172,184)">0 </span><span style="color:rgb(122,126,133)"># or any other appropriate handling for dates before today<br></span><span style="color:rgb(122,126,133)"> </span>row[<span style="color:rgb(106,171,115)">'DiscFactor (Dirty Price)'</span>] = <span style="color:rgb(42,172,184)">0 </span><span style="color:rgb(122,126,133)"># or any other appropriate handling for dates before today<br></span><span style="color:rgb(122,126,133)"> </span>row[<span style="color:rgb(106,171,115)">'NPV'</span>] = <span style="color:rgb(136,136,198)">round</span>(row[<span style="color:rgb(106,171,115)">'DiscFactor (NPV)'</span>] * row[<span style="color:rgb(106,171,115)">'amount'</span>], <span style="color:rgb(42,172,184)">9</span>)<br> row[<span style="color:rgb(106,171,115)">'Dirty Price'</span>] = <span style="color:rgb(136,136,198)">round</span>(row[<span style="color:rgb(106,171,115)">'DiscFactor (Dirty Price)'</span>] * row[<span style="color:rgb(106,171,115)">'amount'</span>], <span style="color:rgb(42,172,184)">9</span>)<br> BondCashflows.append(row)<br><br>BondCashflows = pd.DataFrame(BondCashflows)</pre></div></div><div><br></div><div>Hope that makes sense.</div><div><br></div><div>Thanks & regards,</div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Dec 17, 2023 at 10:37 PM Philippe Hatstadt <<a href="mailto:phi...@ex...">phi...@ex...</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">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 <br id="m_883891212213335717lineBreakAtBeginningOfSignature"><div dir="ltr">Regards<div><br></div><div>Philippe Hatstadt</div><div>+1-203-252-0408</div><div><br></div></div><div dir="ltr"><br><blockquote type="cite">On Dec 17, 2023, at 3:22 PM, Quant <<a href="mailto:qua...@gm..." target="_blank">qua...@gm...</a>> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><div dir="ltr">Hi Quantlib Users,<div><br></div><div>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.</div><div><br></div><div>Find below a part of the code that I have tried to use to extract the discount factors;</div><div><div style="background-color:rgb(30,31,34);color:rgb(188,190,196)"><pre style="font-family:"JetBrains Mono",monospace">fields = [<span style="color:rgb(106,171,115)">'accrualStartDate'</span>, <span style="color:rgb(106,171,115)">'accrualEndDate'</span>, <span style="color:rgb(106,171,115)">'date'</span>, <span style="color:rgb(106,171,115)">'nominal'</span>, <span style="color:rgb(106,171,115)">'rate'</span>,<br> <span style="color:rgb(106,171,115)">'amount'</span>, <span style="color:rgb(106,171,115)">'accrualDays'</span>, <span style="color:rgb(106,171,115)">'accrualPeriod'</span>]<br>BondCashflows = []<br><span style="color:rgb(207,142,109)">for </span>cf <span style="color:rgb(207,142,109)">in </span><span style="color:rgb(136,136,198)">list</span>(<span style="color:rgb(136,136,198)">map</span>(ql.as_fixed_rate_coupon, bond.cashflows()))[:-<span style="color:rgb(42,172,184)">1</span>]:<br> row = {fld: <span style="color:rgb(136,136,198)">eval</span>(<span style="color:rgb(106,171,115)">f"cf.</span><span style="color:rgb(207,142,109)">{</span>fld<span style="color:rgb(207,142,109)">}</span><span style="color:rgb(106,171,115)">()"</span>) <span style="color:rgb(207,142,109)">for </span>fld <span style="color:rgb(207,142,109)">in </span>fields}<br> row[<span style="color:rgb(106,171,115)">'AccrualPeriod'</span>] = <span style="color:rgb(136,136,198)">round</span>((row[<span style="color:rgb(106,171,115)">'accrualEndDate'</span>] - row[<span style="color:rgb(106,171,115)">'accrualStartDate'</span>]) / <span style="color:rgb(42,172,184)">365</span>, <span style="color:rgb(42,172,184)">4</span>)<br> <span style="color:rgb(207,142,109)">if </span>row[<span style="color:rgb(106,171,115)">'date'</span>] >= today:<br> row[<span style="color:rgb(106,171,115)">'ZeroRate (NPV)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.zeroRate(row[<span style="color:rgb(106,171,115)">'date'</span>], day_count, ql.Compounded, ql.Annual).rate(), <span style="color:rgb(42,172,184)">9</span>)<br> row[<span style="color:rgb(106,171,115)">'ZeroRate (Dirty Price)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.forwardRate(bond.settlementDate(), row[<span style="color:rgb(106,171,115)">'date'</span>], day_count, ql.Compounded, ql.Annual).rate(), <span style="color:rgb(42,172,184)">9</span>)<br> row[<span style="color:rgb(106,171,115)">'DiscFactor (NPV)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.discount(row[<span style="color:rgb(106,171,115)">'date'</span>]), <span style="color:rgb(42,172,184)">9</span>)<br> row[<span style="color:rgb(106,171,115)">'DiscFactor (Dirty Price)'</span>] = <span style="color:rgb(136,136,198)">round</span>(curve.discount(bond.settlementDate(), row[<span style="color:rgb(106,171,115)">'date'</span>]), <span style="color:rgb(42,172,184)">9</span>)<br> <span style="color:rgb(207,142,109)">else</span>:<br> row[<span style="color:rgb(106,171,115)">'ZeroRate (NPV)'</span>] = <span style="color:rgb(42,172,184)">0<br></span><span style="color:rgb(42,172,184)"> </span>row[<span style="color:rgb(106,171,115)">'ZeroRate (Dirty Price)'</span>] = <span style="color:rgb(42,172,184)">0<br></span><span style="color:rgb(42,172,184)"> </span>row[<span style="color:rgb(106,171,115)">'DiscFactor (NPV)'</span>] = <span style="color:rgb(42,172,184)">0 </span><span style="color:rgb(122,126,133)"># or any other appropriate handling for dates before today<br></span><span style="color:rgb(122,126,133)"> </span>row[<span style="color:rgb(106,171,115)">'DiscFactor (Dirty Price)'</span>] = <span style="color:rgb(42,172,184)">0 </span><span style="color:rgb(122,126,133)"># or any other appropriate handling for dates before today<br></span><span style="color:rgb(122,126,133)"> </span>row[<span style="color:rgb(106,171,115)">'NPV'</span>] = <span style="color:rgb(136,136,198)">round</span>(row[<span style="color:rgb(106,171,115)">'DiscFactor (NPV)'</span>] * row[<span style="color:rgb(106,171,115)">'amount'</span>], <span style="color:rgb(42,172,184)">9</span>)<br> BondCashflows.append(row)<br><br>BondCashflows = pd.DataFrame(BondCashflows)<br><br><span style="color:rgb(136,136,198)">print</span>(BondCashflows)</pre></div></div><div><br></div><div>Thanks & regards</div></div>
<span>_______________________________________________</span><br><span>QuantLib-users mailing list</span><br><span><a href="mailto:Qua...@li..." target="_blank">Qua...@li...</a></span><br><span><a href="https://lists.sourceforge.net/lists/listinfo/quantlib-users" target="_blank">https://lists.sourceforge.net/lists/listinfo/quantlib-users</a></span><br></div></blockquote></div>
<br>
<p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">1370 Broadway, Suite 1450 | New York, NY | 10018</span></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><a href="https://www.exosfinancial.com/" target="_blank"><img src="https://exos-website-media.s3.amazonaws.com/Disclosures/img1.jpg" alt="https://www.exosfinancial.com/" data-unique-identifier=""></a> <a href="https://www.linkedin.com/company/meetexos/about/" target="_blank"><img src="https://exos-website-media.s3.amazonaws.com/Disclosures/img3.jpg" alt="https://www.linkedin.com/company/meetexos/about/" data-unique-identifier=""></a> <br></span></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">Broker-Dealer services offered through Exos Securities LLC, Member SIPC, FINRA. For important disclosures including Form CRS and Regulation BI click </span><a href="https://www.exosfinancial.com/general-disclosures" target="_blank"><span style="font-size:11pt;font-family:Arial;color:rgb(17,85,204);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">here</span></a>.<br></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="background-color:transparent;font-size:9pt;font-family:Arial;color:rgb(0,0,0);font-weight:700;vertical-align:baseline;white-space:pre-wrap"><br></span></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="background-color:transparent;font-size:9pt;font-family:Arial;color:rgb(0,0,0);font-weight:700;vertical-align:baseline;white-space:pre-wrap">Confidentiality Notice</span><span style="background-color:transparent;font-size:9pt;font-family:Arial;color:rgb(0,0,0);vertical-align:baseline;white-space:pre-wrap">: 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. </span><br></p></blockquote></div>
</div></blockquote></body></html>
<br>
<p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">1370 Broadway, Suite 1450 | New York, NY | 10018</span></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><a href="https://www.exosfinancial.com/" target="_blank"><img src="https://exos-website-media.s3.amazonaws.com/Disclosures/img1.jpg" alt="https://www.exosfinancial.com/"></a> <a href="https://www.linkedin.com/company/meetexos/about/" target="_blank"><img src="https://exos-website-media.s3.amazonaws.com/Disclosures/img3.jpg" alt="https://www.linkedin.com/company/meetexos/about/"></a> <br></span></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">Broker-Dealer services offered through Exos Securities LLC, Member SIPC, FINRA. For important disclosures including Form CRS and Regulation BI click </span><a href="https://www.exosfinancial.com/general-disclosures" target="_blank"><span style="font-size:11pt;font-family:Arial;color:rgb(17,85,204);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">here</span></a>.<br></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="background-color:transparent;font-size:9pt;font-family:Arial;color:rgb(0,0,0);font-weight:700;vertical-align:baseline;white-space:pre-wrap"><br></span></p><p dir="ltr" style="line-height:1.38;background-color:rgb(239,239,239);margin-top:0pt;margin-bottom:0pt"><span style="background-color:transparent;font-size:9pt;font-family:Arial;color:rgb(0,0,0);font-weight:700;vertical-align:baseline;white-space:pre-wrap">Confidentiality Notice</span><span style="background-color:transparent;font-size:9pt;font-family:Arial;color:rgb(0,0,0);vertical-align:baseline;white-space:pre-wrap">: 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. </span><br></p>
|