Hello everybody,
I'm trying to calculate the NPV of a couple of bonds, zero coupon and fixed income, using QuantLib in Python, via SWIG interface (QuantLib 1.3, SWIG 1.2). In C++, starting from the discounting curve which is embedded within the code snippet posted below, I obtain the correct values: NPV (ZCB) = 99.2665 NPV (FRB) = 103.733 However, from Python side, I've got different results: NPV (ZCB) = 96.45 NPV (FRB) = 100.79 Could you help me to understand the reason of this mis-behaviour? Thanks in advance, Antonio #!/usr/bin/env python # Copyright (C) 2008 Florent Grenier # Copyright (C) 2010 Lluis Pujol Bajador # # This file is part of QuantLib, a free-software/open-source library # for financial quantitative analysts and developers - http://quantlib.org/ # # QuantLib is free software: you can redistribute it and/or modify it # under the terms of the QuantLib license. You should have received a # copy of the license along with this program; if not, please email # <quantlib-dev@lists.sf.net>. The license is also available online at # <http://quantlib.org/license.shtml>. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the license for more details. # This example shows how to set up a term structure and then price # some simple bonds. The last part is dedicated to peripherical # computations such as "Yield to Price" or "Price to Yield" # this script should be the prototype which demonstrate how to # use discounting curve for calculating the Net Present Value # of a Bond (Fixed Rate, Zero Coupon, and Floating Rate) # Test cases for Bonds pricing module # Fixed rate bond # Zero coupon bond # Floating rate bond from QuantLib import * # global data calendar = TARGET() settlementDate = Date(01,January,2014) settlementDate = calendar.adjust(settlementDate) fixingDays = 0 settlementDays = 0 todaysDate = calendar.adjust(calendar.advance(settlementDate, -fixingDays, Days)) Settings.instance().evaluationDate = todaysDate termStructureDayCounter = ActualActual(ActualActual.ISDA) print 'Today: ' + str(todaysDate) print 'Settlement Date: ' + str(settlementDate) # dates and rates vectors dates = [ settlementDate, settlementDate + 1*QuantLib.Weeks, settlementDate + 1*QuantLib.Months, settlementDate + 2*QuantLib.Months, settlementDate + 3*QuantLib.Months, settlementDate + 4*QuantLib.Months, settlementDate + 5*QuantLib.Months, settlementDate + 6*QuantLib.Months, settlementDate + 9*QuantLib.Months, settlementDate + 1*12*QuantLib.Months, settlementDate + 18*QuantLib.Months, settlementDate + 2*12*QuantLib.Months, settlementDate + 3*12*QuantLib.Months, settlementDate + 4*12*QuantLib.Months, settlementDate + 5*12*QuantLib.Months, settlementDate + 6*12*QuantLib.Months, settlementDate + 7*12*QuantLib.Months, settlementDate + 8*12*QuantLib.Months, settlementDate + 9*12*QuantLib.Months, settlementDate + 10*12*QuantLib.Months, settlementDate + 11*12*QuantLib.Months, settlementDate + 12*12*QuantLib.Months, settlementDate + 15*12*QuantLib.Months, settlementDate + 20*12*QuantLib.Months, settlementDate + 25*12*QuantLib.Months, settlementDate + 30*12*30] rates = [ 0.002762549, 0.002762549, 0.002762549, 0.002762549, 0.002762549, 0.00347872, 0.004126332, 0.004714056, 0.006191223, 0.007362001, 0.009215772, 0.01082479, 0.01404554, 0.01738827, 0.02061265, 0.02351719, 0.02602376, 0.02813818, 0.0299055, 0.03138197, 0.0326213, 0.03366947, 0.03600337, 0.03835103, 0.03976059, 0.04070031 ] ####################################### # BONDS TO BE PRICED # ####################################### # common data faceAmount = 100; # Discounting curve built up on the provided dates/rates bondDiscountingTermStructure = ZeroCurve(dates, rates, termStructureDayCounter) discountingTermStructure = RelinkableYieldTermStructureHandle() bondEngine = DiscountingBondEngine(discountingTermStructure) # zero coupon bond zeroCouponBond = ZeroCouponBond(settlementDays, UnitedStates(UnitedStates.GovernmentBond), faceAmount, Date(01,January,2015), Following, 100, Date(01,January,2005)) zeroCouponBond.setPricingEngine(bondEngine) # fixed 4.5% US Treasury note fixedBondSchedule = Schedule(Date(01, January, 2005), Date(01, January, 2015), Period(Annual), UnitedStates(UnitedStates.GovernmentBond), Unadjusted, Unadjusted, DateGeneration.Backward, False) fixedRateBond = FixedRateBond(settlementDays, faceAmount, fixedBondSchedule, [0.045], ActualActual(ActualActual.Bond), ModifiedFollowing, 100.0, Date(01, January, 2005)) fixedRateBond.setPricingEngine(bondEngine); discountingTermStructure.linkTo(bondDiscountingTermStructure) ############################# # BOND PRICING # ############################# # write column headings def formatPrice(p,digits=2): format = '%%.%df' % digits return format % p def formatRate(r,digits=2): format = '%%.%df %%%%' % digits return format % (r*100) def report(Info, Zc, Fix, Frn, format): if format== "Price": Zc = formatPrice(Zc) Fix = formatPrice(Fix) Frn = formatPrice(Frn) else: if Info.find("coupon")==-1: Zc = formatRate(Zc) else: Zc = "N/A" Fix = formatRate(Fix) Frn = formatRate(Frn) print '%19s' % Info + ' |' + \ ' |'.join(['%10s' % y for y in [Zc, Fix, Frn] ]) headers = [ "ZC", "Fixed", "Floating" ] print '' print '%19s' % '' + ' |' + \ ' |'.join(['%10s' % y for y in headers]) separator = " | " widths = [ 18, 10, 10, 10 ] width = widths[0] + widths[1] + widths[2] + widths[3] + widths[3]; rule = "-" * width dblrule = "=" * width tab = " " * 8 print rule report( "Net present value", zeroCouponBond.NPV(), fixedRateBond.NPV(), #floatingRateBond.NPV(), 0, "Price") print '' |
The expression
settlementDate + 2*QuantLib.Months doesn't work as you expect in Python, since there's no real enumeration in the language and QuantLib.Months is just an integer. You need to use settlementDate + QuantLib.Period(2, QuantLib.Months) instead. Luigi On Wed, Feb 12, 2014 at 10:37 AM, asavoldi <[hidden email]> wrote: > Hello everybody, > > I'm trying to calculate the NPV of a couple of bonds, zero coupon and fixed > income, using QuantLib in Python, via SWIG interface (QuantLib 1.3, SWIG > 1.2). In C++, starting from the discounting curve which is embedded within > the code snippet posted below, I obtain the correct values: > > NPV (ZCB) = 99.2665 > NPV (FRB) = 103.733 > > However, from Python side, I've got different results: > > NPV (ZCB) = 96.45 > NPV (FRB) = 100.79 > > Could you help me to understand the reason of this mis-behaviour? > > Thanks in advance, > Antonio > > > > > > > > > #!/usr/bin/env python > > # Copyright (C) 2008 Florent Grenier > # Copyright (C) 2010 Lluis Pujol Bajador > # > # This file is part of QuantLib, a free-software/open-source library > # for financial quantitative analysts and developers - http://quantlib.org/ > # > # QuantLib is free software: you can redistribute it and/or modify it > # under the terms of the QuantLib license. You should have received a > # copy of the license along with this program; if not, please email > # <[hidden email]>. The license is also available online at > # <http://quantlib.org/license.shtml>. > # > # This program is distributed in the hope that it will be useful, but > WITHOUT > # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > FITNESS > # FOR A PARTICULAR PURPOSE. See the license for more details. > > # This example shows how to set up a term structure and then price > # some simple bonds. The last part is dedicated to peripherical > # computations such as "Yield to Price" or "Price to Yield" > > # this script should be the prototype which demonstrate how to > # use discounting curve for calculating the Net Present Value > # of a Bond (Fixed Rate, Zero Coupon, and Floating Rate) > > # Test cases for Bonds pricing module > # Fixed rate bond > # Zero coupon bond > # Floating rate bond > > from QuantLib import * > > # global data > calendar = TARGET() > settlementDate = Date(01,January,2014) > settlementDate = calendar.adjust(settlementDate) > fixingDays = 0 > settlementDays = 0 > todaysDate = calendar.adjust(calendar.advance(settlementDate, -fixingDays, > Days)) > Settings.instance().evaluationDate = todaysDate > termStructureDayCounter = ActualActual(ActualActual.ISDA) > > print 'Today: ' + str(todaysDate) > print 'Settlement Date: ' + str(settlementDate) > > # dates and rates vectors > dates = [ > settlementDate, > settlementDate + 1*QuantLib.Weeks, > settlementDate + 1*QuantLib.Months, > settlementDate + 2*QuantLib.Months, > settlementDate + 3*QuantLib.Months, > > settlementDate + 4*QuantLib.Months, > settlementDate + 5*QuantLib.Months, > settlementDate + 6*QuantLib.Months, > settlementDate + 9*QuantLib.Months, > settlementDate + 1*12*QuantLib.Months, > > settlementDate + 18*QuantLib.Months, > settlementDate + 2*12*QuantLib.Months, > settlementDate + 3*12*QuantLib.Months, > settlementDate + 4*12*QuantLib.Months, > settlementDate + 5*12*QuantLib.Months, > > settlementDate + 6*12*QuantLib.Months, > settlementDate + 7*12*QuantLib.Months, > settlementDate + 8*12*QuantLib.Months, > settlementDate + 9*12*QuantLib.Months, > settlementDate + 10*12*QuantLib.Months, > > settlementDate + 11*12*QuantLib.Months, > settlementDate + 12*12*QuantLib.Months, > settlementDate + 15*12*QuantLib.Months, > settlementDate + 20*12*QuantLib.Months, > settlementDate + 25*12*QuantLib.Months, > settlementDate + 30*12*30] > > > > rates = [ > 0.002762549, > 0.002762549, > 0.002762549, > 0.002762549, > 0.002762549, > > 0.00347872, > 0.004126332, > 0.004714056, > 0.006191223, > 0.007362001, > > 0.009215772, > 0.01082479, > 0.01404554, > 0.01738827, > 0.02061265, > > 0.02351719, > 0.02602376, > 0.02813818, > 0.0299055, > 0.03138197, > > 0.0326213, > 0.03366947, > 0.03600337, > 0.03835103, > 0.03976059, > 0.04070031 > ] > > > ####################################### > # BONDS TO BE PRICED # > ####################################### > > # common data > > faceAmount = 100; > > # Discounting curve built up on the provided dates/rates > bondDiscountingTermStructure = ZeroCurve(dates, rates, > termStructureDayCounter) > discountingTermStructure = RelinkableYieldTermStructureHandle() > bondEngine = DiscountingBondEngine(discountingTermStructure) > > # zero coupon bond > zeroCouponBond = ZeroCouponBond(settlementDays, > UnitedStates(UnitedStates.GovernmentBond), > faceAmount, > Date(01,January,2015), > Following, > 100, > Date(01,January,2005)) > > zeroCouponBond.setPricingEngine(bondEngine) > > > # fixed 4.5% US Treasury note > fixedBondSchedule = Schedule(Date(01, January, 2005), > Date(01, January, 2015), > Period(Annual), > UnitedStates(UnitedStates.GovernmentBond), > Unadjusted, > Unadjusted, > DateGeneration.Backward, > False) > > fixedRateBond = FixedRateBond(settlementDays, > faceAmount, > fixedBondSchedule, > [0.045], > ActualActual(ActualActual.Bond), > ModifiedFollowing, > 100.0, > Date(01, January, 2005)) > > fixedRateBond.setPricingEngine(bondEngine); > > > discountingTermStructure.linkTo(bondDiscountingTermStructure) > > ############################# > # BOND PRICING # > ############################# > > # write column headings > def formatPrice(p,digits=2): > format = '%%.%df' % digits > return format % p > > def formatRate(r,digits=2): > format = '%%.%df %%%%' % digits > return format % (r*100) > > def report(Info, Zc, Fix, Frn, format): > if format== "Price": > Zc = formatPrice(Zc) > Fix = formatPrice(Fix) > Frn = formatPrice(Frn) > else: > if Info.find("coupon")==-1: > Zc = formatRate(Zc) > else: > Zc = "N/A" > Fix = formatRate(Fix) > Frn = formatRate(Frn) > > print '%19s' % Info + ' |' + \ > ' |'.join(['%10s' % y for y in [Zc, Fix, Frn] ]) > > > > headers = [ "ZC", "Fixed", "Floating" ] > print '' > print '%19s' % '' + ' |' + \ > ' |'.join(['%10s' % y for y in headers]) > > separator = " | " > widths = [ 18, 10, 10, 10 ] > width = widths[0] + widths[1] + widths[2] + widths[3] + widths[3]; > rule = "-" * width > dblrule = "=" * width > tab = " " * 8 > > print rule > report( "Net present value", > zeroCouponBond.NPV(), > fixedRateBond.NPV(), > #floatingRateBond.NPV(), > 0, > "Price") > print '' > > > > -- > View this message in context: http://quantlib.10058.n7.nabble.com/NPV-calculation-in-Python-from-a-discounting-curve-tp14960.html > Sent from the quantlib-users mailing list archive at Nabble.com. > > ------------------------------------------------------------------------------ > Android apps run on BlackBerry 10 > Introducing the new BlackBerry 10.2.1 Runtime for Android apps. > Now with support for Jelly Bean, Bluetooth, Mapview and more. > Get your Android app in front of a whole new audience. Start now. > http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users -- <https://implementingquantlib.blogspot.com> <https://twitter.com/lballabio> ------------------------------------------------------------------------------ Android apps run on BlackBerry 10 Introducing the new BlackBerry 10.2.1 Runtime for Android apps. Now with support for Jelly Bean, Bluetooth, Mapview and more. Get your Android app in front of a whole new audience. Start now. http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |