Re: NPV calculation in Python from a discounting curve

Posted by Luigi Ballabio on
URL: http://quantlib.414.s1.nabble.com/NPV-calculation-in-Python-from-a-discounting-curve-tp14960p14961.html

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