2013-03-07 7 views
5

Ich versuche, eine sehr einfache Floating-Rate-Bond in Python mit der Quantlib (v1.2) SWIG-Wrapper Preis. Ich habe das in der Dokumentation enthaltene Beispiel modifiziert.Pricing eine Floating Bond in Quantlib mit Python

Meine Anleihe hat eine 4-jährige Laufzeit. Der Libor wird auf 10% gesetzt und der Spread der Obligation ist 0. Meine Frage ist, ob ich die Rate von 10% diskontieren soll, warum ist der PV der Obligation nicht 100? Ich bekomme einen Wert von 99,54.

Danke!

from QuantLib import * 

frequency_enum, settle_date = 4, Date(5, 1, 2010) 
maturity_date = Date(5, 1, 2014) 
face_amount = 100.0 
settlement_days = 0 
fixing_days = 0 

calendar = NullCalendar() 
settle_date = calendar.adjust(settle_date) 
todays_date = calendar.advance(settle_date, -fixing_days, Days) 
Settings.instance().evaluationDate = todays_date 

rate = 10.0/100.0 

flat_forward = FlatForward(settle_date, 
          rate, 
          Thirty360(), 
          Compounded, 
          frequency_enum) 

discounting_term_structure = RelinkableYieldTermStructureHandle(flat_forward) 
index_term_structure = RelinkableYieldTermStructureHandle(flat_forward) 

index = USDLibor(Period(3, Months), index_term_structure) 

schedule = Schedule(settle_date, 
        maturity_date, Period(frequency_enum), 
        NullCalendar(), 
        Unadjusted, Unadjusted, 
        DateGeneration.Forward, False) 

floating_bond = FloatingRateBond(settlement_days, 
           face_amount, 
           schedule, 
           index, 
           Thirty360(), 
           Unadjusted, 
           fixing_days, 
           [], # Gearings 
           [0], # Spreads 
           [],  # Caps 
           [],  # Floors 
           False, # Fixing in arrears 
           face_amount, 
           settle_date) 

bond_engine = DiscountingBondEngine(discounting_term_structure) 
floating_bond.setPricingEngine(bond_engine) 

# coupon pricers 
pricer = BlackIborCouponPricer() 

volatility = 0.0 
vol = ConstantOptionletVolatility(settlement_days, 
            calendar, 
            Unadjusted, 
            volatility, 
            Thirty360()) 

pricer.setCapletVolatility(OptionletVolatilityStructureHandle(vol)) 
setCouponPricer(floating_bond.cashflows(), pricer) 

print floating_bond.NPV(), floating_bond.cleanPrice(), floating_bond.dirtyPrice() 

Antwort

4

Die Coupons Raten der USDLibor- Tageszähler festgelegt verwenden (das heißt, Actual/360), die nicht die Zahlung Tageszähler passt Ihnen zur Verfügung gestellten (30/360). Sie können es sehen, indem Sie die Coupons Inspektion:

cfs = floating_bond.cashflows() 
coupons = [ as_coupon(c) for c in cfs[:-1] ] # the last one is the redemption 
print [ (c.rate(), c.accrualPeriod()) for c in coupons ] 

, die Sie T = 0,25 für alle Coupons gibt, aber Raten von weniger als 10%.

Um den gewünschten Preis zu erhalten, müssen Sie den Kurs und die Abgrenzungsdauer abgleichen. Eine Möglichkeit besteht darin, Actual360() als Bondday-Zähler zu übergeben, was auf meiner Maschine einen Preis von 100,002 ergibt (ich habe nicht weiter untersucht, aber die Diskrepanz könnte auf das Enddatum für die LIBOR-Fixierung zurückzuführen sein, das mit der USD-Kalender und stimmt möglicherweise nicht genau mit dem Ende des Coupons überein). Eine andere Möglichkeit besteht darin, einen benutzerdefinierten LIBOR-Index mit einem internen 30/360 Tageszähler zu erstellen. Ich habe das selbst nicht versucht, aber Sie können es tun, indem Sie eine geeignete Instanz der IborIndex-Klasse erstellen.

+2

Vielen Dank. Ich habe einen benutzerdefinierten Index erstellt und ein genaues Ergebnis von 100.0 erhalten! Der benutzerdefinierte Index lautet: 'index = IborIndex ('USD Libor', Periode (3, Monate), settlement_days, USDCurrency(), NullCalendar(), Nicht angepasst, False, Thirty360(), index_term_structure)' – ducky