From a165d1a4bffdc1b69d48ef825417564b29dfa7e1 Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Tue, 7 Nov 2023 21:34:52 -0500 Subject: [PATCH] move bond instruments to follow upstream hierarchy --- quantlib/cashflows/coupon_pricer.pyx | 2 - quantlib/instruments/_bond.pxd | 72 +++++ quantlib/instruments/_bonds.pxd | 140 -------- quantlib/instruments/bond.pxd | 13 + quantlib/instruments/bond.pyx | 107 ++++++ quantlib/instruments/bonds.pxd | 5 - quantlib/instruments/bonds.pyx | 305 ------------------ quantlib/instruments/bonds/__init__.py | 3 + quantlib/instruments/bonds/_cpibond.pxd | 36 +++ quantlib/instruments/bonds/_fixedratebond.pxd | 27 ++ .../instruments/bonds/_floatingratebond.pxd | 50 +++ .../instruments/bonds/_zerocouponbond.pxd | 15 + quantlib/instruments/bonds/cpibond.pxd | 10 + quantlib/instruments/bonds/cpibond.pyx | 44 +++ quantlib/instruments/bonds/fixedratebond.pxd | 4 + quantlib/instruments/bonds/fixedratebond.pyx | 72 +++++ .../instruments/bonds/floatingratebond.pxd | 4 + .../instruments/bonds/floatingratebond.pyx | 71 ++++ quantlib/instruments/bonds/zerocouponbond.pxd | 4 + quantlib/instruments/bonds/zerocouponbond.pyx | 43 +++ quantlib/pricingengines/_bondfunctions.pxd | 2 +- quantlib/pricingengines/bondfunctions.pyx | 22 +- .../termstructures/yields/_bond_helpers.pxd | 8 +- .../termstructures/yields/bond_helpers.pyx | 18 +- 24 files changed, 596 insertions(+), 481 deletions(-) create mode 100644 quantlib/instruments/_bond.pxd delete mode 100644 quantlib/instruments/_bonds.pxd create mode 100644 quantlib/instruments/bond.pxd create mode 100644 quantlib/instruments/bond.pyx delete mode 100644 quantlib/instruments/bonds.pxd delete mode 100644 quantlib/instruments/bonds.pyx create mode 100644 quantlib/instruments/bonds/__init__.py create mode 100644 quantlib/instruments/bonds/_cpibond.pxd create mode 100644 quantlib/instruments/bonds/_fixedratebond.pxd create mode 100644 quantlib/instruments/bonds/_floatingratebond.pxd create mode 100644 quantlib/instruments/bonds/_zerocouponbond.pxd create mode 100644 quantlib/instruments/bonds/cpibond.pxd create mode 100644 quantlib/instruments/bonds/cpibond.pyx create mode 100644 quantlib/instruments/bonds/fixedratebond.pxd create mode 100644 quantlib/instruments/bonds/fixedratebond.pyx create mode 100644 quantlib/instruments/bonds/floatingratebond.pxd create mode 100644 quantlib/instruments/bonds/floatingratebond.pyx create mode 100644 quantlib/instruments/bonds/zerocouponbond.pxd create mode 100644 quantlib/instruments/bonds/zerocouponbond.pyx diff --git a/quantlib/cashflows/coupon_pricer.pyx b/quantlib/cashflows/coupon_pricer.pyx index 5cc103ed2..cefeb626c 100644 --- a/quantlib/cashflows/coupon_pricer.pyx +++ b/quantlib/cashflows/coupon_pricer.pyx @@ -2,7 +2,6 @@ include '../types.pxi' from cython.operator cimport dereference as deref from quantlib.cashflow cimport Leg -cimport quantlib.instruments._bonds as _bonds from quantlib.termstructures.volatility.optionlet.optionlet_volatility_structure cimport OptionletVolatilityStructure cimport quantlib.termstructures.volatility.optionlet._optionlet_volatility_structure as _ovs from quantlib.termstructures.volatility.swaption.swaption_vol_structure \ @@ -16,7 +15,6 @@ from quantlib.time.daycounter cimport DayCounter from quantlib.quote cimport Quote from quantlib.quotes.simplequote cimport SimpleQuote from .coupon_pricer cimport FloatingRateCouponPricer -from quantlib.instruments.bonds cimport Bond cimport quantlib._cashflow as _cf cdef class FloatingRateCouponPricer: diff --git a/quantlib/instruments/_bond.pxd b/quantlib/instruments/_bond.pxd new file mode 100644 index 000000000..b6b90d798 --- /dev/null +++ b/quantlib/instruments/_bond.pxd @@ -0,0 +1,72 @@ +from quantlib.types cimport Natural, Rate, Real, Size + +from libcpp.vector cimport vector +from libcpp cimport bool + +from .._instrument cimport Instrument +from quantlib.time._calendar cimport BusinessDayConvention, Calendar +from quantlib.time._date cimport Date +from quantlib.time._period cimport Frequency, Period +from quantlib.time._daycounter cimport DayCounter +from quantlib.time._schedule cimport Schedule +from quantlib._cashflow cimport Leg +from quantlib.indexes._ibor_index cimport IborIndex +from quantlib.indexes._inflation_index cimport ZeroInflationIndex +from quantlib.time._schedule cimport DateGeneration +from quantlib.compounding cimport Compounding + +cdef extern from 'ql/instruments/bond.hpp' namespace 'QuantLib' nogil: + cdef cppclass Bond(Instrument): + cppclass Price: + enum Type: + Dirty + Clean + Price(Real amount, Type type) + Real amount() + Type type() + Natural settlementDays() + Calendar& calendar() + vector[Real]& notionals() + Real notional(Date d) + const Leg& cashflows() + const Leg& redemptions() + Date startDate() const + Date maturityDate() + Date issueDate() + Date settlementDate(Date d) + bool isTradable(Date d) + Real accruedAmount(Date d) except + + + + Real cleanPrice() except + + Real dirtyPrice() except + + Real settlementValue() except + + + Rate bond_yield 'yield'( + DayCounter& dc, + Compounding comp, + Frequency freq, + Real accuracy, # = 1e-8 + Size maxEvaluations, # = 100 + Real guess, # = 0.5, + Bond.Price.Type price_type # = Bond.Price.Clean + ) except + + + Rate bond_yield 'yield'( + Real price, + DayCounter& dc, + Compounding comp, + Frequency freq, + Date settlementDate, # = Date() + Real accuracy, # = 1e-8 + Size maxEvaluations, # = 100 + Real guess, # = 0.5, + Bond.Price.Type price_type # = Bond.Price.Clean + ) except + + + Rate nextCouponRate(Date d) const + + Rate previousCouponRate(Date d) const + + Date nextCashFlowDate(Date d) except + + Date previousCashFlowDate(Date d) except + diff --git a/quantlib/instruments/_bonds.pxd b/quantlib/instruments/_bonds.pxd deleted file mode 100644 index b85af6823..000000000 --- a/quantlib/instruments/_bonds.pxd +++ /dev/null @@ -1,140 +0,0 @@ -include '../types.pxi' - -from libcpp.vector cimport vector -from libcpp cimport bool - -from quantlib.handle cimport shared_ptr, Handle -from .._instrument cimport Instrument -from quantlib.time._calendar cimport BusinessDayConvention, Calendar -from quantlib.time._date cimport Date -from quantlib.time._period cimport Frequency, Period -from quantlib.time._daycounter cimport DayCounter -from quantlib.time._schedule cimport Schedule -from quantlib._cashflow cimport Leg -from quantlib.indexes._ibor_index cimport IborIndex -from quantlib.indexes._inflation_index cimport ZeroInflationIndex -from quantlib.time._schedule cimport DateGeneration -from quantlib._compounding cimport Compounding - -cdef extern from 'ql/instruments/bond.hpp' namespace 'QuantLib': - cdef cppclass Bond(Instrument): - - bool isExpired() - Natural settlementDays() - Calendar& calendar() - vector[Real]& notionals() - Real notional(Date d) - Leg cashflows() - Date maturityDate() - Date issueDate() - Date settlementDate(Date d) - bool isTradable(Date d) - Real accruedAmount(Date d) except + - - - Real cleanPrice() except + - Real dirtyPrice() except + - Real settlementValue() except + - - Rate clean_yield 'yield'( - Real cleanPrice, - DayCounter& dc, - Compounding comp, - Frequency freq, - Date settlementDate, - Real accuracy, - Size maxEvaluations) except + - - Date nextCashFlowDate(Date d) except + - Date previousCashFlowDate(Date d) except + - -cdef extern from 'ql/instruments/bonds/fixedratebond.hpp' namespace 'QuantLib': - cdef cppclass FixedRateBond(Bond): - FixedRateBond(Natural settlementDays, - Real faceAmount, - const Schedule& schedule, - vector[Rate]& coupons, - DayCounter& accrualDayCounter, - BusinessDayConvention paymentConvention, - Real redemption, # 100.0 - const Date& issueDate, # Date() - const Calendar& payemntCalendar, # Calendar() - const Period& exCouponPeriod, # Period() - const Calendar& exCouponCalendar, # Calendar() - const BusinessDayConvention exCouponConvention, # Unadjusted, - bool exCouponEndOfMonth, # false - ) except + - -cdef extern from 'ql/instruments/bonds/zerocouponbond.hpp' namespace 'QuantLib': - cdef cppclass ZeroCouponBond(Bond): - ZeroCouponBond(Natural settlementDays, - Calendar calendar, - Real faceAmount, - Date maturityDate, - BusinessDayConvention paymentConvention, - Real redemption, - Date& issueDate) except + - -cdef extern from 'ql/instruments/bonds/floatingratebond.hpp' namespace 'QuantLib': - cdef cppclass FloatingRateBond(Bond): - FloatingRateBond(Natural settlementDays, - Real faceAmount, - Schedule& schedule, - const shared_ptr[IborIndex]& iborIndex, - DayCounter& accrualDayCounter, - BusinessDayConvention paymentConvention, - Natural fixingDays, # Null() - vector[Real]& gearings, # std::vector(1, 1.0) - vector[Spread]& spreads, #std::vector(1, 0.0) - vector[Rate]& caps, # std::vector() - vector[Rate]& floors, # std::vector() - bool inArrears, # false - Real redemption, # 100. - Date& issueDate # Date() - ) except + - FloatingRateBond(Natural settlementDays, - Real faceAmount, - Date& startDate, - Date& maturityDate, - Frequency couponFrequency, - Calendar& calendar, - shared_ptr[IborIndex]& iborIndex, - DayCounter& accrualDayCounter, - BusinessDayConvention accrualConvention, - BusinessDayConvention paymentConvention, - Natural fixingDays, - vector[Real]& gearings, - vector[Spread]& spreads, - vector[Rate]& caps, - vector[Rate]& floors, - Real redemption, - Date& issueDate, - Date& stubDate, - DateGeneration rule) except + - -cdef extern from 'ql/cashflows/cpicoupon.hpp' namespace 'QuantLib::CPI': - cdef enum InterpolationType: - AsIndex - Flat - Linear - -cdef extern from 'ql/instruments/bonds/cpibond.hpp' namespace 'QuantLib': - cdef cppclass CPIBond(Bond): - CPIBond(Natural settlementDays, - Real faceAmount, - bool growthOnly, - Real baseCPI, - const Period& observationLag, - shared_ptr[ZeroInflationIndex]& cpiIndex, - InterpolationType observationInterpolation, - const Schedule& schedule, - vector[Rate]& coupons, - const DayCounter& accrualDayCounter, - BusinessDayConvention paymentConvention, - const Date& issueDate, # Date() - const Calendar& paymentCalendar, #Calendar() - const Period& exCouponPeriod, # Period() - const Calendar& exCouponCalendar, # Calendar() - const BusinessDayConvention exCouponConvention, # Unadjusted - bool exCouponEndOfMonth # false - ) except + diff --git a/quantlib/instruments/bond.pxd b/quantlib/instruments/bond.pxd new file mode 100644 index 000000000..8845d74b0 --- /dev/null +++ b/quantlib/instruments/bond.pxd @@ -0,0 +1,13 @@ +from quantlib.instrument cimport Instrument +from . cimport _bond + +cdef extern from "ql/instruments/bond.hpp" namespace "QuantLib::Bond::Price" nogil: + cpdef enum Type: + Dirty + Clean + +cdef class BondPrice: + pass + +cdef class Bond(Instrument): + cdef inline _bond.Bond* as_ptr(self) diff --git a/quantlib/instruments/bond.pyx b/quantlib/instruments/bond.pyx new file mode 100644 index 000000000..53209e02d --- /dev/null +++ b/quantlib/instruments/bond.pyx @@ -0,0 +1,107 @@ +from quantlib.types cimport Real, Size +from . cimport _bond +cimport quantlib.time._date as _date + +from cython.operator cimport dereference as deref +from libcpp.vector cimport vector +from libcpp cimport bool +from quantlib.cashflow cimport Leg +from quantlib.compounding cimport Compounding +from quantlib.time.businessdayconvention cimport BusinessDayConvention +from quantlib.time.calendar cimport Calendar +from quantlib.time.date cimport Date, date_from_qldate, Period +from quantlib.time.daycounter cimport DayCounter +from quantlib.time._period cimport Frequency + +cdef class Price: + Clean = Type.Clean + Dirty = Type.Dirty + +cdef class Bond(Instrument): + """ Base bond class + + .. warning:: + + Most methods assume that the cash flows are stored + sorted by date, the redemption(s) being after any + cash flow at the same date. In particular, if there's + one single redemption, it must be the last cash flow, + + """ + def __init__(self): + raise NotImplementedError('Cannot instantiate a Bond. Please use child classes.') + + cdef inline _bond.Bond* as_ptr(self): + return <_bond.Bond*>self._thisptr.get() + + @property + def settlement_days(self): + return self.as_ptr().settlementDays() + + @property + def calendar(self): + cdef Calendar c = Calendar.__new__(Calendar) + c._thisptr = self.as_ptr().calendar() + return c + + @property + def start_date(self): + """ Bond start date. """ + return date_from_qldate(self.as_ptr().startDate()) + + + @property + def maturity_date(self): + """ Bond maturity date. """ + return date_from_qldate(self.as_ptr().maturityDate()) + + @property + def issue_date(self): + """ Bond issue date. """ + return date_from_qldate(self.as_ptr().issueDate()) + + def settlement_date(self, Date from_date=Date()): + """ Returns the bond settlement date after the given date.""" + return date_from_qldate(self.as_ptr().settlementDate(deref(from_date._thisptr))) + + @property + def clean_price(self): + """ Bond clean price. """ + return self.as_ptr().cleanPrice() + + @property + def dirty_price(self): + """ Bond dirty price. """ + return self.as_ptr().dirtyPrice() + + def bond_yield(self, Real price, DayCounter dc not None, + Compounding comp, Frequency freq, + Date settlement_date=Date(), Real accuracy=1e-08, + Size max_evaluations=100, Real guess=0.5, Type price_type = Price.Clean): + """ Return the yield given a (clean) price and settlement date + + The default bond settlement is used if no date is given. + + This method is the original Bond.yield method in C++. + Python does not allow us to use the yield statement as a method name. + + """ + return self.as_ptr().bond_yield( + price, deref(dc._thisptr), comp, + freq, deref(settlement_date._thisptr), + accuracy, max_evaluations, guess, price_type + ) + + def accrued_amount(self, Date date=Date()): + """ Returns the bond accrued amount at the given date. """ + return self.as_ptr().accruedAmount(deref(date._thisptr)) + + @property + def cashflows(self): + """ cash flow stream as a Leg """ + cdef Leg leg = Leg.__new__(Leg) + leg._thisptr = self.as_ptr().cashflows() + return leg + + def notional(self, Date date=Date()): + return self.as_ptr().notional(deref(date._thisptr)) diff --git a/quantlib/instruments/bonds.pxd b/quantlib/instruments/bonds.pxd deleted file mode 100644 index 5eacef429..000000000 --- a/quantlib/instruments/bonds.pxd +++ /dev/null @@ -1,5 +0,0 @@ - -from quantlib.instrument cimport Instrument - -cdef class Bond(Instrument): - pass diff --git a/quantlib/instruments/bonds.pyx b/quantlib/instruments/bonds.pyx deleted file mode 100644 index ed1ec9f97..000000000 --- a/quantlib/instruments/bonds.pyx +++ /dev/null @@ -1,305 +0,0 @@ -# Copyright (C) 2011, Enthought Inc -# Copyright (C) 2011, Patrick Henaff -# -# 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. - -include '../types.pxi' - -cimport quantlib.instruments._bonds as _bonds -cimport quantlib._instrument as _instrument -cimport quantlib.pricingengines._pricing_engine as _pe -cimport quantlib.time._date as _date - -from cython.operator cimport dereference as deref -from libcpp.vector cimport vector -from libcpp cimport bool -from quantlib.handle cimport Handle, shared_ptr, RelinkableHandle, static_pointer_cast -from quantlib.pricingengines.engine cimport PricingEngine -from quantlib.time.businessdayconvention cimport ( - BusinessDayConvention, Following, Unadjusted ) -from quantlib.time._daycounter cimport DayCounter as QlDayCounter -from quantlib.time._schedule cimport Schedule as QlSchedule -from quantlib.time.calendar cimport Calendar -from quantlib.time.date cimport Date, date_from_qldate, Period -from quantlib.time.schedule cimport Schedule -from quantlib.time.daycounter cimport DayCounter -from quantlib.time._period cimport Frequency -from quantlib.indexes.ibor_index cimport IborIndex -from quantlib.indexes.inflation_index cimport ZeroInflationIndex - -cimport quantlib._cashflow as _cashflow -cimport quantlib.cashflow as cashflow -cimport quantlib.indexes._ibor_index as _ii -cimport quantlib.indexes._inflation_index as _inf - -cpdef enum InterpolationType: - AsIndex = _bonds.AsIndex - Flat = _bonds.Flat - Linear = _bonds.Linear - -cdef inline _bonds.Bond* get_bond(Bond bond): - """ Utility function to extract a properly casted Bond pointer out of the - internal _thisptr attribute of the Instrument base class. """ - - return <_bonds.Bond*>bond._thisptr.get() - - -cdef class Bond(Instrument): - """ Base bond class - - .. warning:: - - Most methods assume that the cash flows are stored - sorted by date, the redemption(s) being after any - cash flow at the same date. In particular, if there's - one single redemption, it must be the last cash flow, - - """ - - def __init__(self): - raise NotImplementedError('Cannot instantiate a Bond. Please use child classes.') - - - property issue_date: - """ Bond issue date. """ - def __get__(self): - cdef _date.Date issue_date = get_bond(self).issueDate() - return date_from_qldate(issue_date) - - property maturity_date: - """ Bond maturity date. """ - def __get__(self): - cdef _date.Date maturity_date = get_bond(self).maturityDate() - return date_from_qldate(maturity_date) - - property valuation_date: - """ Bond valuation date. """ - def __get__(self): - cdef _date.Date valuation_date = get_bond(self).valuationDate() - return date_from_qldate(valuation_date) - - def settlement_date(self, Date from_date=Date()): - """ Returns the bond settlement date after the given date.""" - return date_from_qldate(get_bond(self).settlementDate(deref(from_date._thisptr))) - - property clean_price: - """ Bond clean price. """ - def __get__(self): - return get_bond(self).cleanPrice() - - property dirty_price: - """ Bond dirty price. """ - def __get__(self): - return get_bond(self).dirtyPrice() - - def clean_yield(self, Real clean_price, DayCounter dc not None, - _bonds.Compounding comp, _bonds.Frequency freq, - Date settlement_date not None, Real accuracy=1e-08, - Size max_evaluations=100): - """ Return the yield given a (clean) price and settlement date - - The default bond settlement is used if no date is given. - - This method is the original Bond.yield method in C++. - Python does not allow us to use the yield statement as a method name. - - """ - return get_bond(self).clean_yield( - clean_price, deref(dc._thisptr), comp, - freq, deref(settlement_date._thisptr), - accuracy, max_evaluations - ) - - def accrued_amount(self, Date date=Date()): - """ Returns the bond accrued amount at the given date. """ - return get_bond(self).accruedAmount(deref(date._thisptr)) - - @property - def cashflows(self): - """ cash flow stream as a Leg """ - cdef cashflow.Leg leg = cashflow.Leg.__new__(cashflow.Leg) - leg._thisptr = get_bond(self).cashflows() - return leg - - def notional(self, Date date=Date()): - return get_bond(self).notional(deref(date._thisptr)) - -cdef class FixedRateBond(Bond): - """ Fixed rate bond. - - Support: - - simple annual compounding coupon rates - - Unsupported: (needs interfacing) - - simple annual compounding coupon rates with internal schedule calculation - - generic compounding and frequency InterestRate coupons - """ - - def __init__(self, Natural settlement_days, Real face_amount, - Schedule schedule, vector[Rate] coupons, - DayCounter accrual_day_counter, - BusinessDayConvention payment_convention=Following, - Real redemption=100.0, Date issue_date=Date(), - Calendar payment_calendar=Calendar(), - Period ex_coupon_period=Period(), - Calendar ex_coupon_calendar=Calendar(), - BusinessDayConvention ex_coupon_convention=Unadjusted, - bool ex_coupon_end_of_month=False): - """ Fixed rate bond - - Parameters - ---------- - settlement_days : int - Number of days before bond settles - face_amount : float (C double in python) - Amount of face value of bond - schedule : Schedule - Schedule of payments for bond - coupons : list[float] - Interest[s] to be acquired for bond. - accrual_day_counter: DayCounter - dayCounter for Bond - payment_convention: BusinessDayConvention - The business day convention for the payment schedule - redemption : float - Amount at redemption - issue_date : Date - Date bond was issued - """ - - self._thisptr = shared_ptr[_instrument.Instrument]( - new _bonds.FixedRateBond(settlement_days, - face_amount, - deref(schedule._thisptr), - coupons, - deref(accrual_day_counter._thisptr), - payment_convention, - redemption, deref(issue_date._thisptr), - payment_calendar._thisptr, - deref(ex_coupon_period._thisptr), - ex_coupon_calendar._thisptr, - ex_coupon_convention, - ex_coupon_end_of_month) - ) - -cdef class ZeroCouponBond(Bond): - """ Zero coupon bond """ - def __init__(self, Natural settlement_days, Calendar calendar, - Real face_amount, Date maturity_date not None, - BusinessDayConvention payment_convention=Following, - Real redemption=100.0, Date issue_date=Date()): - """ Zero coupon bond (constructor) - - Parameters - ---------- - settlement_days : int - Number of days before bond settles - calendar : Calendar - Type of Calendar - face_amount: float (C double in python) - Amount of face value of bond - maturity_date: Date - Date bond matures (pays off) - payment_convention : BusinessDayConvention - The business day convention for the payment schedule - redemption : float - Amount at redemption - issue_date : Date - Date bond was issued""" - - self._thisptr = shared_ptr[_instrument.Instrument]( - new _bonds.ZeroCouponBond(settlement_days, - calendar._thisptr, face_amount, - deref(maturity_date._thisptr), - payment_convention, redemption, - deref(issue_date._thisptr) - ) - ) - -cdef class FloatingRateBond(Bond): - """ Floating rate bond """ - def __init__(self, Natural settlement_days, Real face_amount, - Schedule schedule, IborIndex ibor_index, - DayCounter accrual_day_counter, Natural fixing_days, - vector[Real] gearings=[1.], vector[Spread] spreads=[0.], - vector[Rate] caps=[], vector[Rate] floors=[], - BusinessDayConvention payment_convention=Following, - bool in_arrears=True, - Real redemption=100.0, Date issue_date=Date() - ): - """ Floating rate bond - - Parameters - ---------- - settlement_days : int - Number of days before bond settles - face_amount : float (C double in python) - Amount of face value of bond - float_schedule : Schedule - Schedule of payments for bond - ibor_index : IborIndex - Ibor index - accrual_day_counter: DayCounter - dayCounter for Bond - fixing_days : int - Number of fixing days for bond - gearings: list [float] - Gearings defaulted to [1.] - spreads: list [float] - Spread on ibor index, default to [0.] - caps: list [float] - Caps on the spread - floors: list[float] - Floors on the spread - payment_convention: BusinessDayConvention - The business day convention for the payment schedule - in_arrears: bool - redemption : float - Amount at redemption - issue_date : Date - Date bond was issued - """ - - self._thisptr = shared_ptr[_instrument.Instrument]( - new _bonds.FloatingRateBond( - settlement_days, face_amount, - deref(schedule._thisptr), - static_pointer_cast[_ii.IborIndex](ibor_index._thisptr), - deref(accrual_day_counter._thisptr), - payment_convention, - fixing_days, gearings, spreads, caps, floors, True, - redemption, - deref(issue_date._thisptr) - ) - ) - -cdef class CPIBond(Bond): - """ CPI bond """ - def __init__(self, Natural settlement_days, Real face_amount, bool growth_only, - Real baseCPI, Period observation_lag not None, - ZeroInflationIndex cpi_index not None, - InterpolationType observation_interpolation, - Schedule schedule, vector[Rate] coupons, - DayCounter accrual_day_counter, - BusinessDayConvention payment_convention=Following, - Date issue_date=Date(), Calendar payment_calendar=Calendar(), - Period ex_coupon_period=Period(), Calendar ex_coupon_calendar=Calendar(), - BusinessDayConvention ex_coupon_convention=Unadjusted, - bool ex_coupon_end_of_month=False): - - self._thisptr = shared_ptr[_instrument.Instrument]( - new _bonds.CPIBond( - settlement_days, face_amount, growth_only, baseCPI, - deref(observation_lag._thisptr), - static_pointer_cast[_inf.ZeroInflationIndex]( - cpi_index._thisptr), - observation_interpolation, - deref(schedule._thisptr), coupons, - deref(accrual_day_counter._thisptr), payment_convention, - deref(issue_date._thisptr), - payment_calendar._thisptr, deref(ex_coupon_period._thisptr), - ex_coupon_calendar._thisptr, ex_coupon_convention, - ex_coupon_end_of_month) - ) diff --git a/quantlib/instruments/bonds/__init__.py b/quantlib/instruments/bonds/__init__.py new file mode 100644 index 000000000..cc5dbd33a --- /dev/null +++ b/quantlib/instruments/bonds/__init__.py @@ -0,0 +1,3 @@ +from .fixedratebond import FixedRateBond +from .zerocouponbond import ZeroCouponBond +from .floatingratebond import FloatingRateBond diff --git a/quantlib/instruments/bonds/_cpibond.pxd b/quantlib/instruments/bonds/_cpibond.pxd new file mode 100644 index 000000000..4deee8a78 --- /dev/null +++ b/quantlib/instruments/bonds/_cpibond.pxd @@ -0,0 +1,36 @@ +from quantlib.types cimport Natural, Rate, Real +from libcpp cimport bool +from libcpp.vector cimport vector +from .._bond cimport Bond + +from quantlib.time.businessdayconvention cimport BusinessDayConvention +from quantlib.time._calendar cimport Calendar +from quantlib.time._date cimport Date +from quantlib.time._daycounter cimport DayCounter +from quantlib.time._period cimport Period +from quantlib.time._schedule cimport Schedule +from quantlib.handle cimport shared_ptr +from quantlib.indexes._inflation_index cimport ZeroInflationIndex + +from .cpibond cimport InterpolationType + +cdef extern from 'ql/instruments/bonds/cpibond.hpp' namespace 'QuantLib' nogil: + cdef cppclass CPIBond(Bond): + CPIBond(Natural settlementDays, + Real faceAmount, + bool growthOnly, + Real baseCPI, + const Period& observationLag, + shared_ptr[ZeroInflationIndex]& cpiIndex, + InterpolationType observationInterpolation, + const Schedule& schedule, + vector[Rate]& coupons, + const DayCounter& accrualDayCounter, + BusinessDayConvention paymentConvention, + const Date& issueDate, # Date() + const Calendar& paymentCalendar, #Calendar() + const Period& exCouponPeriod, # Period() + const Calendar& exCouponCalendar, # Calendar() + const BusinessDayConvention exCouponConvention, # Unadjusted + bool exCouponEndOfMonth # false + ) except + diff --git a/quantlib/instruments/bonds/_fixedratebond.pxd b/quantlib/instruments/bonds/_fixedratebond.pxd new file mode 100644 index 000000000..53fd43178 --- /dev/null +++ b/quantlib/instruments/bonds/_fixedratebond.pxd @@ -0,0 +1,27 @@ +from quantlib.types cimport Natural, Rate, Real +from libcpp cimport bool +from quantlib.time.businessdayconvention cimport BusinessDayConvention +from quantlib.time._calendar cimport Calendar +from quantlib.time._date cimport Date +from quantlib.time._period cimport Period +from quantlib.time._daycounter cimport DayCounter +from quantlib.time._schedule cimport Schedule +from libcpp.vector cimport vector +from .._bond cimport Bond + +cdef extern from 'ql/instruments/bonds/fixedratebond.hpp' namespace 'QuantLib' nogil: + cdef cppclass FixedRateBond(Bond): + FixedRateBond(Natural settlementDays, + Real faceAmount, + const Schedule& schedule, + vector[Rate]& coupons, + DayCounter& accrualDayCounter, + BusinessDayConvention paymentConvention, + Real redemption, # 100.0 + const Date& issueDate, # Date() + const Calendar& payemntCalendar, # Calendar() + const Period& exCouponPeriod, # Period() + const Calendar& exCouponCalendar, # Calendar() + const BusinessDayConvention exCouponConvention, # Unadjusted, + bool exCouponEndOfMonth, # false + ) except + diff --git a/quantlib/instruments/bonds/_floatingratebond.pxd b/quantlib/instruments/bonds/_floatingratebond.pxd new file mode 100644 index 000000000..20bd5d09d --- /dev/null +++ b/quantlib/instruments/bonds/_floatingratebond.pxd @@ -0,0 +1,50 @@ +from .._bond cimport Bond +from quantlib.indexes._ibor_index cimport IborIndex +from quantlib.types cimport Natural, Rate, Real, Spread +from quantlib.handle cimport shared_ptr +from quantlib.time._calendar cimport Calendar +from quantlib.time._date cimport Date +from quantlib.time.frequency cimport Frequency +from quantlib.time.businessdayconvention cimport BusinessDayConvention +from quantlib.time.dategeneration cimport DateGeneration +from quantlib.time._schedule cimport Schedule +from quantlib.time._daycounter cimport DayCounter +from libcpp.vector cimport vector +from libcpp cimport bool + +cdef extern from 'ql/instruments/bonds/floatingratebond.hpp' namespace 'QuantLib' nogil: + cdef cppclass FloatingRateBond(Bond): + FloatingRateBond(Natural settlementDays, + Real faceAmount, + Schedule& schedule, + const shared_ptr[IborIndex]& iborIndex, + DayCounter& accrualDayCounter, + BusinessDayConvention paymentConvention, + Natural fixingDays, # Null() + vector[Real]& gearings, # std::vector(1, 1.0) + vector[Spread]& spreads, #std::vector(1, 0.0) + vector[Rate]& caps, # std::vector() + vector[Rate]& floors, # std::vector() + bool inArrears, # false + Real redemption, # 100. + Date& issueDate # Date() + ) except + + FloatingRateBond(Natural settlementDays, + Real faceAmount, + Date& startDate, + Date& maturityDate, + Frequency couponFrequency, + Calendar& calendar, + shared_ptr[IborIndex]& iborIndex, + DayCounter& accrualDayCounter, + BusinessDayConvention accrualConvention, + BusinessDayConvention paymentConvention, + Natural fixingDays, + vector[Real]& gearings, + vector[Spread]& spreads, + vector[Rate]& caps, + vector[Rate]& floors, + Real redemption, + Date& issueDate, + Date& stubDate, + DateGeneration rule) except + diff --git a/quantlib/instruments/bonds/_zerocouponbond.pxd b/quantlib/instruments/bonds/_zerocouponbond.pxd new file mode 100644 index 000000000..5bd902ecc --- /dev/null +++ b/quantlib/instruments/bonds/_zerocouponbond.pxd @@ -0,0 +1,15 @@ +from quantlib.types cimport Natural, Real +from .._bond cimport Bond +from quantlib.time._calendar cimport Calendar +from quantlib.time._date cimport Date +from quantlib.time.businessdayconvention cimport BusinessDayConvention + +cdef extern from 'ql/instruments/bonds/zerocouponbond.hpp' namespace 'QuantLib' nogil: + cdef cppclass ZeroCouponBond(Bond): + ZeroCouponBond(Natural settlementDays, + Calendar calendar, + Real faceAmount, + Date maturityDate, + BusinessDayConvention paymentConvention, + Real redemption, + Date& issueDate) except + diff --git a/quantlib/instruments/bonds/cpibond.pxd b/quantlib/instruments/bonds/cpibond.pxd new file mode 100644 index 000000000..a99781f11 --- /dev/null +++ b/quantlib/instruments/bonds/cpibond.pxd @@ -0,0 +1,10 @@ +from ..bond cimport Bond + +cdef extern from 'ql/cashflows/cpicoupon.hpp' namespace 'QuantLib::CPI': + cpdef enum InterpolationType: + AsIndex + Flat + Linear + +cdef class CPIBond(Bond): + pass diff --git a/quantlib/instruments/bonds/cpibond.pyx b/quantlib/instruments/bonds/cpibond.pyx new file mode 100644 index 000000000..f391c2a2c --- /dev/null +++ b/quantlib/instruments/bonds/cpibond.pyx @@ -0,0 +1,44 @@ +from cython.operator cimport dereference as deref +from quantlib.types cimport Natural, Rate, Real +from libcpp cimport bool +from libcpp.vector cimport vector +from . cimport _cpibond + +from quantlib.handle cimport static_pointer_cast +cimport quantlib.indexes._inflation_index as _inf +from quantlib.indexes.inflation_index cimport ZeroInflationIndex +from quantlib.time.businessdayconvention cimport BusinessDayConvention, Following, Unadjusted +from quantlib.time.calendar cimport Calendar +from quantlib.time.schedule cimport Schedule +from quantlib.time.date cimport Date, Period +from quantlib.time.daycounter cimport DayCounter + +cdef class CPIBond(Bond): + """ CPI bond """ + def __init__(self, Natural settlement_days, Real face_amount, bool growth_only, + Real baseCPI, Period observation_lag not None, + ZeroInflationIndex cpi_index not None, + InterpolationType observation_interpolation, + Schedule schedule, vector[Rate] coupons, + DayCounter accrual_day_counter, + BusinessDayConvention payment_convention=Following, + Date issue_date=Date(), Calendar payment_calendar=Calendar(), + Period ex_coupon_period=Period(), Calendar ex_coupon_calendar=Calendar(), + BusinessDayConvention ex_coupon_convention=Unadjusted, + bool ex_coupon_end_of_month=False): + + self._thisptr.reset( + new _cpibond.CPIBond( + settlement_days, face_amount, growth_only, baseCPI, + deref(observation_lag._thisptr), + static_pointer_cast[_inf.ZeroInflationIndex]( + cpi_index._thisptr), + observation_interpolation, + deref(schedule._thisptr), coupons, + deref(accrual_day_counter._thisptr), payment_convention, + deref(issue_date._thisptr), + payment_calendar._thisptr, deref(ex_coupon_period._thisptr), + ex_coupon_calendar._thisptr, ex_coupon_convention, + ex_coupon_end_of_month + ) + ) diff --git a/quantlib/instruments/bonds/fixedratebond.pxd b/quantlib/instruments/bonds/fixedratebond.pxd new file mode 100644 index 000000000..7be054d36 --- /dev/null +++ b/quantlib/instruments/bonds/fixedratebond.pxd @@ -0,0 +1,4 @@ +from ..bond cimport Bond + +cdef class FixedRateBond(Bond): + pass diff --git a/quantlib/instruments/bonds/fixedratebond.pyx b/quantlib/instruments/bonds/fixedratebond.pyx new file mode 100644 index 000000000..0162b0223 --- /dev/null +++ b/quantlib/instruments/bonds/fixedratebond.pyx @@ -0,0 +1,72 @@ +from cython.operator cimport dereference as deref + +from quantlib.types cimport Natural, Real, Rate +from quantlib.time.businessdayconvention cimport BusinessDayConvention, Following, Unadjusted +from quantlib.time.calendar cimport Calendar +from quantlib.time.date cimport Period, Date +from quantlib.time.daycounter cimport DayCounter +from quantlib.time.schedule cimport Schedule + +from libcpp cimport bool +from libcpp.vector cimport vector +from . cimport _fixedratebond as _frb + +cdef class FixedRateBond(Bond): + """ Fixed rate bond. + + Support: + - simple annual compounding coupon rates + + Unsupported: (needs interfacing) + - simple annual compounding coupon rates with internal schedule calculation + - generic compounding and frequency InterestRate coupons + """ + + def __init__(self, Natural settlement_days, Real face_amount, + Schedule schedule, vector[Rate] coupons, + DayCounter accrual_day_counter, + BusinessDayConvention payment_convention=Following, + Real redemption=100.0, Date issue_date=Date(), + Calendar payment_calendar=Calendar(), + Period ex_coupon_period=Period(), + Calendar ex_coupon_calendar=Calendar(), + BusinessDayConvention ex_coupon_convention=Unadjusted, + bool ex_coupon_end_of_month=False): + """ Fixed rate bond + + Parameters + ---------- + settlement_days : int + Number of days before bond settles + face_amount : float (C double in python) + Amount of face value of bond + schedule : Schedule + Schedule of payments for bond + coupons : list[float] + Interest[s] to be acquired for bond. + accrual_day_counter: DayCounter + dayCounter for Bond + payment_convention: BusinessDayConvention + The business day convention for the payment schedule + redemption : float + Amount at redemption + issue_date : Date + Date bond was issued + """ + + self._thisptr.reset( + new _frb.FixedRateBond( + settlement_days, + face_amount, + deref(schedule._thisptr), + coupons, + deref(accrual_day_counter._thisptr), + payment_convention, + redemption, deref(issue_date._thisptr), + payment_calendar._thisptr, + deref(ex_coupon_period._thisptr), + ex_coupon_calendar._thisptr, + ex_coupon_convention, + ex_coupon_end_of_month + ) + ) diff --git a/quantlib/instruments/bonds/floatingratebond.pxd b/quantlib/instruments/bonds/floatingratebond.pxd new file mode 100644 index 000000000..96c6a1e02 --- /dev/null +++ b/quantlib/instruments/bonds/floatingratebond.pxd @@ -0,0 +1,4 @@ +from ..bond cimport Bond + +cdef class FloatingRateBond(Bond): + pass diff --git a/quantlib/instruments/bonds/floatingratebond.pyx b/quantlib/instruments/bonds/floatingratebond.pyx new file mode 100644 index 000000000..2e1d71ee4 --- /dev/null +++ b/quantlib/instruments/bonds/floatingratebond.pyx @@ -0,0 +1,71 @@ +from quantlib.types cimport Natural, Rate, Real, Spread +from cython.operator cimport dereference as deref +from libcpp.vector cimport vector +from libcpp cimport bool +from quantlib.handle cimport static_pointer_cast +from quantlib.indexes.ibor_index cimport IborIndex +cimport quantlib.indexes._ibor_index as _ii +from quantlib.time.businessdayconvention cimport BusinessDayConvention, Following +from quantlib.time.date cimport Date +from quantlib.time.daycounter cimport DayCounter +from quantlib.time.schedule cimport Schedule + + +from . cimport _floatingratebond as _frb + +cdef class FloatingRateBond(Bond): + """ Floating rate bond """ + def __init__(self, Natural settlement_days, Real face_amount, + Schedule schedule, IborIndex ibor_index, + DayCounter accrual_day_counter, Natural fixing_days, + vector[Real] gearings=[1.], vector[Spread] spreads=[0.], + vector[Rate] caps=[], vector[Rate] floors=[], + BusinessDayConvention payment_convention=Following, + bool in_arrears=True, + Real redemption=100.0, Date issue_date=Date() + ): + """ Floating rate bond + + Parameters + ---------- + settlement_days : int + Number of days before bond settles + face_amount : float (C double in python) + Amount of face value of bond + float_schedule : Schedule + Schedule of payments for bond + ibor_index : IborIndex + Ibor index + accrual_day_counter: DayCounter + dayCounter for Bond + fixing_days : int + Number of fixing days for bond + gearings: list [float] + Gearings defaulted to [1.] + spreads: list [float] + Spread on ibor index, default to [0.] + caps: list [float] + Caps on the spread + floors: list[float] + Floors on the spread + payment_convention: BusinessDayConvention + The business day convention for the payment schedule + in_arrears: bool + redemption : float + Amount at redemption + issue_date : Date + Date bond was issued + """ + + self._thisptr.reset( + new _frb.FloatingRateBond( + settlement_days, face_amount, + deref(schedule._thisptr), + static_pointer_cast[_ii.IborIndex](ibor_index._thisptr), + deref(accrual_day_counter._thisptr), + payment_convention, + fixing_days, gearings, spreads, caps, floors, True, + redemption, + deref(issue_date._thisptr) + ) + ) diff --git a/quantlib/instruments/bonds/zerocouponbond.pxd b/quantlib/instruments/bonds/zerocouponbond.pxd new file mode 100644 index 000000000..c450b7073 --- /dev/null +++ b/quantlib/instruments/bonds/zerocouponbond.pxd @@ -0,0 +1,4 @@ +from ..bond cimport Bond + +cdef class ZeroCouponBond(Bond): + pass diff --git a/quantlib/instruments/bonds/zerocouponbond.pyx b/quantlib/instruments/bonds/zerocouponbond.pyx new file mode 100644 index 000000000..5f432c520 --- /dev/null +++ b/quantlib/instruments/bonds/zerocouponbond.pyx @@ -0,0 +1,43 @@ +from cython.operator cimport dereference as deref + +from quantlib.types cimport Natural, Real +from quantlib.time.businessdayconvention cimport BusinessDayConvention, Following +from quantlib.time.calendar cimport Calendar +from quantlib.time.date cimport Date + +from . cimport _zerocouponbond as _zcb + +cdef class ZeroCouponBond(Bond): + """ Zero coupon bond """ + def __init__(self, Natural settlement_days, Calendar calendar, + Real face_amount, Date maturity_date, + BusinessDayConvention payment_convention=Following, + Real redemption=100.0, Date issue_date=Date()): + """ Zero coupon bond (constructor) + + Parameters + ---------- + settlement_days : int + Number of days before bond settles + calendar : Calendar + Type of Calendar + face_amount: float (C double in python) + Amount of face value of bond + maturity_date: Date + Date bond matures (pays off) + payment_convention : BusinessDayConvention + The business day convention for the payment schedule + redemption : float + Amount at redemption + issue_date : Date + Date bond was issued""" + + self._thisptr.reset( + new _zcb.ZeroCouponBond( + settlement_days, calendar._thisptr, + face_amount, + deref(maturity_date._thisptr), + payment_convention, redemption, + deref(issue_date._thisptr) + ) + ) diff --git a/quantlib/pricingengines/_bondfunctions.pxd b/quantlib/pricingengines/_bondfunctions.pxd index b4f6a8d76..1bf062a49 100644 --- a/quantlib/pricingengines/_bondfunctions.pxd +++ b/quantlib/pricingengines/_bondfunctions.pxd @@ -1,6 +1,6 @@ include '../types.pxi' -from quantlib.instruments._bonds cimport Bond +from quantlib.instruments._bond cimport Bond from quantlib.handle cimport shared_ptr from quantlib.time._period cimport Frequency from quantlib.time._date cimport Date diff --git a/quantlib/pricingengines/bondfunctions.pyx b/quantlib/pricingengines/bondfunctions.pyx index b798a96d2..319bd56de 100644 --- a/quantlib/pricingengines/bondfunctions.pyx +++ b/quantlib/pricingengines/bondfunctions.pyx @@ -1,6 +1,5 @@ include '../types.pxi' -from quantlib.instruments._bonds cimport Bond as QLBond from quantlib.time._date cimport Day, Month, Year, Date as QLDate from quantlib.time._period cimport Frequency from quantlib.time._daycounter cimport DayCounter as _DayCounter @@ -8,7 +7,7 @@ cimport quantlib.pricingengines._bondfunctions as _bf from quantlib.handle cimport shared_ptr, Handle from cython.operator cimport dereference as deref -from quantlib.instruments.bonds cimport Bond +from quantlib.instruments.bond cimport Bond from quantlib.time.date cimport date_from_qldate, Date from quantlib.termstructures.yield_term_structure cimport YieldTermStructure from quantlib.time.daycounter cimport DayCounter @@ -22,8 +21,7 @@ cpdef enum DurationType: def startDate(Bond bond): - cdef QLBond* _bp = bond._thisptr.get() - return date_from_qldate(_bf.startDate(deref(_bp))) + return date_from_qldate(_bf.startDate(deref(bond.as_ptr()))) def duration(Bond bond not None, @@ -33,10 +31,8 @@ def duration(Bond bond not None, Frequency frequency, DurationType type, Date settlementDate=Date()): - cdef QLBond* _bp = bond._thisptr.get() - return _bf.duration( - deref(_bp), + deref(bond.as_ptr()), yld, deref(dayCounter._thisptr), compounding, @@ -55,10 +51,8 @@ def bond_yield(Bond bond not None, Size maxIterations, Rate guess): - cdef QLBond* _bp = bond._thisptr.get() - return _bf.bf_yield( - deref(_bp), + deref(bond.as_ptr()), cleanPrice, deref(dayCounter._thisptr), compounding, @@ -75,10 +69,8 @@ def basisPointValue(Bond bond not None, Compounding compounding, Frequency frequency, Date settlementDate not None): - cdef QLBond* _bp = bond._thisptr.get() - return _bf.basisPointValue( - deref(_bp), + deref(bond.as_ptr()), yld, deref(dayCounter._thisptr), compounding, @@ -96,10 +88,8 @@ def zSpread(Bond bond, Real cleanPrice, Size maxIterations, Rate guess): - cdef QLBond* _bp = bond._thisptr.get() - return _bf.zSpread( - deref(_bp), + deref(bond.as_ptr()), cleanPrice, yts.as_shared_ptr(), deref(dayCounter._thisptr), diff --git a/quantlib/termstructures/yields/_bond_helpers.pxd b/quantlib/termstructures/yields/_bond_helpers.pxd index 147154597..8d7ecebee 100644 --- a/quantlib/termstructures/yields/_bond_helpers.pxd +++ b/quantlib/termstructures/yields/_bond_helpers.pxd @@ -4,7 +4,8 @@ from libcpp.vector cimport vector from quantlib.handle cimport shared_ptr, Handle from quantlib._quote cimport Quote -from quantlib.instruments._bonds cimport Bond +from quantlib.instruments._bond cimport Bond +from quantlib.instruments.bond cimport Type from quantlib.termstructures._helpers cimport BootstrapHelper from quantlib.time._date cimport Date from quantlib.time._daycounter cimport DayCounter @@ -18,11 +19,10 @@ cdef extern from 'ql/termstructures/yield/bondhelpers.hpp' namespace 'QuantLib': cdef cppclass BondHelper(RateHelper): # this is added because of Cython. This empty constructor does not exist # and should never be used - BondHelper() BondHelper( Handle[Quote]& cleanPrice, - shared_ptr[Bond]& bond - ) except + + shared_ptr[Bond]& bond, + Type priceType) except + cdef cppclass FixedRateBondHelper(BondHelper): FixedRateBondHelper( diff --git a/quantlib/termstructures/yields/bond_helpers.pyx b/quantlib/termstructures/yields/bond_helpers.pyx index 126a5259a..7c1510a62 100644 --- a/quantlib/termstructures/yields/bond_helpers.pyx +++ b/quantlib/termstructures/yields/bond_helpers.pyx @@ -5,28 +5,30 @@ from libcpp.vector cimport vector from quantlib.handle cimport shared_ptr, static_pointer_cast -cimport quantlib.instruments._bonds as _bonds cimport quantlib.time._calendar as _calendar from . cimport _bond_helpers as _bh -from quantlib.instruments.bonds cimport Bond +from quantlib.instruments.bond cimport Bond, Type, Clean +cimport quantlib.instruments._bond as _bond from quantlib.quote cimport Quote from quantlib.time.date cimport Date from quantlib.time.schedule cimport Schedule from quantlib.time.daycounter cimport DayCounter -from quantlib.time.businessdayconvention cimport Following +from quantlib.time.businessdayconvention cimport BusinessDayConvention, Following from quantlib.termstructures.yields.rate_helpers cimport RateHelper cdef class BondHelper(RateHelper): - def __init__(self, Quote clean_price, Bond bond not None): + def __init__(self, Quote clean_price, Bond bond not None, Type price_type=Clean): self._thisptr = shared_ptr[_bh.RateHelper]( new _bh.BondHelper( clean_price.handle(), - static_pointer_cast[_bonds.Bond](bond._thisptr) - )) + static_pointer_cast[_bond.Bond](bond._thisptr), + price_type + ) + ) cdef class FixedRateBondHelper(BondHelper): @@ -34,7 +36,7 @@ cdef class FixedRateBondHelper(BondHelper): def __init__(self, Quote clean_price, Natural settlement_days, Real face_amount, Schedule schedule not None, vector[Rate] coupons, - DayCounter day_counter not None, int payment_conv=Following, + DayCounter day_counter not None, BusinessDayConvention payment_conv=Following, Real redemption=100.0, Date issue_date=Date()): self._thisptr = shared_ptr[_bh.RateHelper]( @@ -45,7 +47,7 @@ cdef class FixedRateBondHelper(BondHelper): deref(schedule._thisptr), coupons, deref(day_counter._thisptr), - <_calendar.BusinessDayConvention> payment_conv, + payment_conv, redemption, deref(issue_date._thisptr) ))