diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 668ffa5c2..bd1b204d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,10 +6,10 @@ on: [push, pull_request] jobs: build: name: Build and test - runs-on: ubuntu-22.04 # required for latest QuantLib + runs-on: ubuntu-24.04 # required for latest QuantLib strategy: matrix: - python-version: ['3.8', '3.9', '3.10'] + python-version: ['3.9', '3.10', '3.11'] steps: - name: install dependencies @@ -22,7 +22,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -48,28 +48,28 @@ jobs: # Publish built docs to gh-pages branch. - name: Checkout documentation branch - if: matrix.python-version == '3.10' - uses: actions/checkout@v2 + if: matrix.python-version == '3.11' + uses: actions/checkout@v4 with: ref: gh-pages path: gh-pages persist-credentials: false - name: Build docs - if: matrix.python-version == '3.10' + if: matrix.python-version == '3.11' run: | pip install sphinx nbsphinx scikit-learn ipython sudo apt-get install pandoc texlive texlive-latex-extra dvipng make docs - uses: actions/upload-artifact@v2 - if: (matrix.python-version == '3.10') && (github.event_name == 'pull_request') + if: (matrix.python-version == '3.11') && (github.event_name == 'pull_request') with: name: "doc_${{ github.event.pull_request.number }}" path: docs/build/html - name: Move docs over - if: (matrix.python-version == '3.10') && (github.event_name == 'push') + if: (matrix.python-version == '3.11') && (github.event_name == 'push') run: | ls cp -r docs/build/html/* gh-pages/ @@ -82,7 +82,7 @@ jobs: # that. - name: Push changes - if: (matrix.python-version == '3.10') && (github.event_name== 'push') + if: (matrix.python-version == '3.11') && (github.event_name== 'push') uses: ad-m/github-push-action@master with: branch: gh-pages diff --git a/quantlib/indexes/_inflation_index.pxd b/quantlib/indexes/_inflation_index.pxd index cbba7f5a3..eb29db537 100644 --- a/quantlib/indexes/_inflation_index.pxd +++ b/quantlib/indexes/_inflation_index.pxd @@ -16,10 +16,11 @@ from quantlib.currency._currency cimport Currency from quantlib.indexes._region cimport Region from quantlib.handle cimport shared_ptr, Handle from quantlib.time._period cimport Period, Frequency +from quantlib.time._date cimport Date cimport quantlib.termstructures._inflation_term_structure as _its -cdef extern from 'ql/indexes/inflationindex.hpp' namespace 'QuantLib': +cdef extern from 'ql/indexes/inflationindex.hpp' namespace 'QuantLib' nogil: cdef cppclass CPI: enum InterpolationType: @@ -28,40 +29,35 @@ cdef extern from 'ql/indexes/inflationindex.hpp' namespace 'QuantLib': Linear cdef cppclass InflationIndex(Index): - InflationIndex() InflationIndex(string& familyName, Region& region, bool revised, - bool interpolated, Frequency frequency, Period& availabilitiyLag, Currency& currency) except + string familyName() Region region() bool revised() - bool interpolated() Frequency frequency() Period availabilityLag() Currency currency() cdef cppclass ZeroInflationIndex(Index): - ZeroInflationIndex() ZeroInflationIndex(string& familyName, Region& region, bool revised, - bool interpolated, Frequency frequency, Period& availabilitiyLag, Currency& currency, Handle[_its.ZeroInflationTermStructure]& h) except + Handle[_its.ZeroInflationTermStructure] zeroInflationTermStructure() + Date lastFixingDate() cdef cppclass YoYInflationIndex(InflationIndex): YoYInflationIndex(const string& familyName, const Region& region, bool revised, - bool interpolated, bool ratio, # is this one a genuine index or a ratio? Frequency frequency, const Period& availabilityLag, diff --git a/quantlib/indexes/inflation/_aucpi.pxd b/quantlib/indexes/inflation/_aucpi.pxd new file mode 100644 index 000000000..01e8e7cc3 --- /dev/null +++ b/quantlib/indexes/inflation/_aucpi.pxd @@ -0,0 +1,17 @@ +from libcpp cimport bool +from .._inflation_index cimport ZeroInflationIndex, YoYInflationIndex +from quantlib.handle cimport Handle +from quantlib.termstructures._inflation_term_structure cimport ZeroInflationTermStructure, YoYInflationTermStructure +from quantlib.time.frequency cimport Frequency + + +cdef extern from 'ql/indexes/inflation/aucpi.hpp' namespace 'QuantLib' nogil: + cdef cppclass AUCPI(ZeroInflationIndex): + AUCPI(Frequency frequency, + bool revised, + const Handle[ZeroInflationTermStructure]& ts) + + YYAUCPI(Frequency frequency, + bool revised, + bool interpolated, + const Handle[YoYInflationTermStructure]& ts) diff --git a/quantlib/indexes/inflation/_euhicp.pxd b/quantlib/indexes/inflation/_euhicp.pxd new file mode 100644 index 000000000..5931b4e93 --- /dev/null +++ b/quantlib/indexes/inflation/_euhicp.pxd @@ -0,0 +1,19 @@ +from libcpp cimport bool +from .._inflation_index cimport ZeroInflationIndex, YoYInflationIndex +from quantlib.handle cimport Handle +from quantlib.termstructures._inflation_term_structure cimport ZeroInflationTermStructure, YoYInflationTermStructure + +cdef extern from 'ql/indexes/inflation/euhicp.hpp' namespace 'QuantLib' nogil: + cdef cppclass EUHICP(ZeroInflationIndex): + EUHICP(const Handle[ZeroInflationTermStructure]& ts) + + cdef cppclass EUHICPXT(ZeroInflationIndex): + EUHICPXT(const Handle[ZeroInflationTermStructure]& ts) + + cdef cppclass YYEUHICP(YoYInflationIndex): + YYEUHICP(bool interpolated, + const Handle[YoYInflationTermStructure]& ts) + + cdef cppclass YYEUHICPXT(YoYInflationIndex): + YYEUHICPXT(bool interpolated, + const Handle[YoYInflationTermStructure]& ts) diff --git a/quantlib/indexes/inflation/_ukrpi.pxd b/quantlib/indexes/inflation/_ukrpi.pxd new file mode 100644 index 000000000..83236008a --- /dev/null +++ b/quantlib/indexes/inflation/_ukrpi.pxd @@ -0,0 +1,7 @@ +from .._inflation_index cimport ZeroInflationIndex +from quantlib.handle cimport Handle +from quantlib.termstructures._inflation_term_structure cimport ZeroInflationTermStructure + +cdef extern from 'ql/indexes/inflation/ukrpi.hpp' namespace 'QuantLib' nogil: + cdef cppclass UKRPI(ZeroInflationIndex): + UKRPI(const Handle[ZeroInflationTermStructure]& ts) diff --git a/quantlib/indexes/inflation/_urkpi.pxd b/quantlib/indexes/inflation/_urkpi.pxd new file mode 100644 index 000000000..e69de29bb diff --git a/quantlib/indexes/inflation/aucpi.pxd b/quantlib/indexes/inflation/aucpi.pxd new file mode 100644 index 000000000..7aa59d8d3 --- /dev/null +++ b/quantlib/indexes/inflation/aucpi.pxd @@ -0,0 +1,7 @@ +from quantlib.indexes.inflation_index cimport ZeroInflationIndex, YoYInflationIndex + +cdef class AUCPI(ZeroInflationIndex): + pass + +cdef class YYAUCPI(YoYInflationIndex): + pass diff --git a/quantlib/indexes/inflation/aucpi.pyx b/quantlib/indexes/inflation/aucpi.pyx new file mode 100644 index 000000000..501406dea --- /dev/null +++ b/quantlib/indexes/inflation/aucpi.pyx @@ -0,0 +1,11 @@ +from libcpp cimport bool +from . cimport _aucpi +from quantlib.time.frequency cimport Frequency +from quantlib.termstructures.inflation_term_structure cimport ZeroInflationTermStructure + +cdef class AUCPI(ZeroInflationIndex): + def __init__(self, + Frequency frequency, + bool revised, + ZeroInflationTermStructure ts=ZeroInflationTermStructure()): + self._thisptr.reset(new _aucpi.AUCPI(frequency, revised, ts._handle)) diff --git a/quantlib/indexes/inflation/australia.pyx b/quantlib/indexes/inflation/australia.pyx deleted file mode 100644 index 8e0de4ba8..000000000 --- a/quantlib/indexes/inflation/australia.pyx +++ /dev/null @@ -1,18 +0,0 @@ -from libcpp cimport bool - -from quantlib.currency.api import AUDCurrency -from quantlib.indexes.regions import AustraliaRegion -from quantlib.indexes.inflation_index cimport ZeroInflationIndex -from quantlib.time._period cimport Frequency, Months -from quantlib.time.date cimport Period -from quantlib.termstructures.inflation_term_structure cimport ZeroInflationTermStructure - -cdef class AUCPI(ZeroInflationIndex): - def __init__(self, Frequency frequency, - bool revised, - bool interpolated, - ZeroInflationTermStructure ts=ZeroInflationTermStructure()): - - super().__init__("CPI", AustraliaRegion(), revised, - interpolated, frequency, Period(2, Months), - AUDCurrency(), ts) diff --git a/quantlib/indexes/inflation/euhicp.pxd b/quantlib/indexes/inflation/euhicp.pxd new file mode 100644 index 000000000..ae23d96a5 --- /dev/null +++ b/quantlib/indexes/inflation/euhicp.pxd @@ -0,0 +1,13 @@ +from quantlib.indexes.inflation_index cimport ZeroInflationIndex, YoYInflationIndex + +cdef class EUHICP(ZeroInflationIndex): + pass + +cdef class EUHICPXT(ZeroInflationIndex): + pass + +cdef class YYEUHICP(YoYInflationIndex): + pass + +cdef class YYEUHICPXT(YoYInflationIndex): + pass diff --git a/quantlib/indexes/inflation/euhicp.pyx b/quantlib/indexes/inflation/euhicp.pyx index d02233d87..ba7d9924b 100644 --- a/quantlib/indexes/inflation/euhicp.pyx +++ b/quantlib/indexes/inflation/euhicp.pyx @@ -1,44 +1,21 @@ +from . cimport _euhicp from libcpp cimport bool - -from quantlib.currency.api import EURCurrency -from quantlib.indexes.regions import EURegion -from quantlib.indexes.inflation_index cimport ( - ZeroInflationIndex, YoYInflationIndex) -from quantlib.time.frequency cimport Monthly -from quantlib.time._period cimport Months -from quantlib.time.date cimport Period from quantlib.termstructures.inflation_term_structure cimport ( ZeroInflationTermStructure, YoYInflationTermStructure) cdef class EUHICP(ZeroInflationIndex): - def __init__(self, bool interpolated, - ZeroInflationTermStructure ts=ZeroInflationTermStructure()): - - super().__init__("HICP", EURegion(), False, - interpolated, Monthly, Period(1, Months), - EURCurrency(), ts) + def __init__(self, ZeroInflationTermStructure ts=ZeroInflationTermStructure()): + self._thisptr.reset(new _euhicp.EUHICP(ts._handle)) cdef class EUHICPXT(ZeroInflationIndex): - def __init__(self, bool interpolated, - ZeroInflationTermStructure ts=ZeroInflationTermStructure()): - - super().__init__("HICPXT", EURegion(), False, - interpolated, Monthly, Period(1, Months), - EURCurrency(), ts) + def __init__(self, ZeroInflationTermStructure ts=ZeroInflationTermStructure()): + self._thisptr.reset(new _euhicp.EUHICPXT(ts._handle)) cdef class YYEUHICP(YoYInflationIndex): - def __init__(self, bool interpolated, - YoYInflationTermStructure ts=YoYInflationTermStructure()): - - super().__init__("YY_HICP", EURegion(), False, - interpolated, Monthly, Period(1, Months), - EURCurrency(), ts) + def __init__(self, bool interpolated, YoYInflationTermStructure ts=YoYInflationTermStructure()): + self._thisptr.reset(new _euhicp.YYEUHICP(interpolated, ts._handle)) cdef class YYEUHICPXT(YoYInflationIndex): - def __init__(self, bool interpolated, - YoYInflationTermStructure ts=YoYInflationTermStructure()): - - super().__init__("YY_HICPXT", EURegion(), False, - interpolated, Monthly, Period(1, Months), - EURCurrency(), ts) + def __init__(self, bool interpolated, YoYInflationTermStructure ts=YoYInflationTermStructure()): + self._thisptr.reset(new _euhicp.YYEUHICPXT(interpolated, ts._handle)) diff --git a/quantlib/indexes/inflation/ukrpi.pxd b/quantlib/indexes/inflation/ukrpi.pxd new file mode 100644 index 000000000..8df045a92 --- /dev/null +++ b/quantlib/indexes/inflation/ukrpi.pxd @@ -0,0 +1,4 @@ +from quantlib.indexes.inflation_index cimport ZeroInflationIndex + +cdef class UKRPI(ZeroInflationIndex): + pass diff --git a/quantlib/indexes/inflation/ukrpi.pyx b/quantlib/indexes/inflation/ukrpi.pyx index e274ad51e..27447e9fe 100644 --- a/quantlib/indexes/inflation/ukrpi.pyx +++ b/quantlib/indexes/inflation/ukrpi.pyx @@ -1,18 +1,9 @@ -from libcpp cimport bool +from . cimport _ukrpi -from quantlib.currency.api import GBPCurrency -from quantlib.indexes.regions import UKRegion -from quantlib.time.date cimport Period -from quantlib.time.date import Months -from quantlib.time.frequency cimport Monthly from quantlib.indexes.inflation_index cimport ZeroInflationIndex from quantlib.termstructures.inflation_term_structure \ cimport ZeroInflationTermStructure cdef class UKRPI(ZeroInflationIndex): - def __init__(self, bool interpolated, - ZeroInflationTermStructure ts=ZeroInflationTermStructure()): - - super().__init__("RPI", UKRegion(), False, - interpolated, Monthly, Period(1, Months), - GBPCurrency(), ts) + def __init__(self, ZeroInflationTermStructure ts=ZeroInflationTermStructure()): + self._thisptr.reset(new _ukrpi.UKRPI(ts._handle)) diff --git a/quantlib/indexes/inflation_index.pyx b/quantlib/indexes/inflation_index.pyx index 13ec35e1c..ec3c51616 100644 --- a/quantlib/indexes/inflation_index.pyx +++ b/quantlib/indexes/inflation_index.pyx @@ -16,7 +16,7 @@ from libcpp cimport bool from libcpp.string cimport string from quantlib.index cimport Index -from quantlib.time.date cimport Period, period_from_qlperiod +from quantlib.time.date cimport Period, period_from_qlperiod, date_from_qldate from quantlib.time.frequency cimport Frequency from quantlib.indexes.region cimport Region @@ -61,11 +61,6 @@ cdef class InflationIndex(Index): c._thisptr = new _cu.Currency(ref.currency()) return c - @property - def interpolated(self): - cdef _ii.InflationIndex* ref = <_ii.InflationIndex*>self._thisptr.get() - return ref.interpolated() - @property def region(self): cdef _ii.InflationIndex* ref = <_ii.InflationIndex*>self._thisptr.get() @@ -77,7 +72,6 @@ cdef class ZeroInflationIndex(InflationIndex): def __init__(self, str family_name, Region region, bool revised, - bool interpolated, Frequency frequency, Period availabilityLag, Currency currency, @@ -91,7 +85,6 @@ cdef class ZeroInflationIndex(InflationIndex): c_family_name, deref(region._thisptr), revised, - interpolated, frequency, deref(availabilityLag._thisptr), deref(currency._thisptr), @@ -104,9 +97,16 @@ cdef class ZeroInflationIndex(InflationIndex): (<_ii.ZeroInflationIndex*>(self._thisptr.get())). zeroInflationTermStructure().currentLink()) + @property + def last_fixing_date(self): + return date_from_qldate( + (<_ii.ZeroInflationIndex*>(self._thisptr.get())).lastFixingDate() + ) + + cdef class YoYInflationIndex(ZeroInflationIndex): def __init__(self, family_name, Region region, bool revised, - bool interpolated, bool ratio, Frequency frequency, + bool ratio, Frequency frequency, Period availability_lag, Currency currency, YoYInflationTermStructure ts=YoYInflationTermStructure()): @@ -115,6 +115,6 @@ cdef class YoYInflationIndex(ZeroInflationIndex): self._thisptr = shared_ptr[_in.Index]( new _ii.YoYInflationIndex( c_family_name, deref(region._thisptr), revised, - interpolated, ratio, frequency, + ratio, frequency, deref(availability_lag._thisptr), deref(currency._thisptr), ts._handle)) diff --git a/quantlib/termstructures/_inflation_term_structure.pxd b/quantlib/termstructures/_inflation_term_structure.pxd index d7be9ca3e..067adbbe9 100644 --- a/quantlib/termstructures/_inflation_term_structure.pxd +++ b/quantlib/termstructures/_inflation_term_structure.pxd @@ -20,7 +20,7 @@ from quantlib.termstructures._yield_term_structure cimport YieldTermStructure from quantlib.termstructures.inflation._seasonality cimport Seasonality -cdef extern from 'ql/termstructures/inflationtermstructure.hpp' namespace 'QuantLib': +cdef extern from 'ql/termstructures/inflationtermstructure.hpp' namespace 'QuantLib' nogil: cdef cppclass InflationTermStructure: diff --git a/quantlib/termstructures/inflation/_interpolated_zero_inflation_curve.pxd b/quantlib/termstructures/inflation/_interpolated_zero_inflation_curve.pxd index 101b69296..0a953b090 100644 --- a/quantlib/termstructures/inflation/_interpolated_zero_inflation_curve.pxd +++ b/quantlib/termstructures/inflation/_interpolated_zero_inflation_curve.pxd @@ -9,17 +9,17 @@ from quantlib.time._date cimport Date from quantlib.time._daycounter cimport DayCounter from quantlib.time._calendar cimport Calendar from quantlib.time._period cimport Frequency, Period -from quantlib.handle cimport Handle +from quantlib.handle cimport Handle, shared_ptr +from ._seasonality cimport Seasonality -cdef extern from 'ql/termstructures/inflation/interpolatedzeroinflationcurve.hpp' namespace 'QuantLib': +cdef extern from 'ql/termstructures/inflation/interpolatedzeroinflationcurve.hpp' namespace 'QuantLib' nogil: cdef cppclass InterpolatedZeroInflationCurve[T](ZeroInflationTermStructure): InterpolatedZeroInflationCurve(const Date& referenceDate, - const Calendar& calendar, - const DayCounter& dayCounter, - const Period& lag, + vector[Date]& dates, + vector[Rate]& rates, Frequency frequency, - const vector[Date]& dates, - vector[Rate]& rates) #should be const here + DayCounter dayCounter, + shared_ptr[Seasonality] seasonality) vector[Date]& dates() vector[Real]& data() vector[Rate]& rates() diff --git a/quantlib/termstructures/inflation/_piecewise_zero_inflation_curve.pxd b/quantlib/termstructures/inflation/_piecewise_zero_inflation_curve.pxd index dd669af88..be9517fd1 100644 --- a/quantlib/termstructures/inflation/_piecewise_zero_inflation_curve.pxd +++ b/quantlib/termstructures/inflation/_piecewise_zero_inflation_curve.pxd @@ -1,24 +1,19 @@ -include '../../types.pxi' - -from libcpp cimport bool +from quantlib.types cimport Real from libcpp.vector cimport vector -from quantlib.handle cimport shared_ptr, Handle -from quantlib.time._date cimport Date, Period +from quantlib.handle cimport shared_ptr +from quantlib.time._date cimport Date from quantlib.time._period cimport Frequency -from quantlib.time._calendar cimport Calendar from quantlib.time._daycounter cimport DayCounter -from quantlib.termstructures._yield_term_structure cimport YieldTermStructure -from quantlib.termstructures.inflation._interpolated_zero_inflation_curve cimport \ - InterpolatedZeroInflationCurve -from quantlib.termstructures.inflation.inflation_traits cimport ZeroInflationTraits +from ._interpolated_zero_inflation_curve cimport InterpolatedZeroInflationCurve +from ._seasonality cimport Seasonality +from .inflation_traits cimport ZeroInflationTraits -cdef extern from 'ql/termstructures/inflation/piecewisezeroinflationcurve.hpp' namespace 'QuantLib': +cdef extern from 'ql/termstructures/inflation/piecewisezeroinflationcurve.hpp' namespace 'QuantLib' nogil: cdef cppclass PiecewiseZeroInflationCurve[T](InterpolatedZeroInflationCurve[T]): PiecewiseZeroInflationCurve(const Date& referenceDate, - const Calendar& calendar, - const DayCounter& dayCounter, - const Period& lag, + Date baseDate, Frequency frequency, - Rate baseZeroRate, + const DayCounter& dayCounter, const vector[shared_ptr[ZeroInflationTraits.helper]]& instruments, + shared_ptr[Seasonality] seasonality, Real accuracy) #= 1.0e-12, diff --git a/quantlib/termstructures/inflation/_seasonality.pxd b/quantlib/termstructures/inflation/_seasonality.pxd index f00de2a7f..9f1ee07bc 100644 --- a/quantlib/termstructures/inflation/_seasonality.pxd +++ b/quantlib/termstructures/inflation/_seasonality.pxd @@ -7,17 +7,17 @@ FOR A PARTICULAR PURPOSE. See the license for more details. """ -include '../../types.pxi' +from quantlib.types cimport Rate from libcpp cimport bool from libcpp.vector cimport vector from quantlib.time._date cimport Date -from quantlib.time._period cimport Period, Frequency +from quantlib.time._period cimport Frequency -from quantlib.termstructures._inflation_term_structure cimport InflationTermStructure +from .._inflation_term_structure cimport InflationTermStructure -cdef extern from 'ql/indexes/iborindex.hpp' namespace 'QuantLib': +cdef extern from 'ql/termstructures/inflation/seasonality.hpp' namespace 'QuantLib' nogil: cdef cppclass Seasonality: Seasonality() @@ -28,7 +28,7 @@ cdef extern from 'ql/indexes/iborindex.hpp' namespace 'QuantLib': Rate r, InflationTermStructure& iTS) bool isConsistent(InflationTermStructure& iTS) - + cdef cppclass MultiplicativePriceSeasonality(Seasonality): MultiplicativePriceSeasonality() MultiplicativePriceSeasonality(Date& seasonalityBaseDate, @@ -41,12 +41,8 @@ cdef extern from 'ql/indexes/iborindex.hpp' namespace 'QuantLib': # inspectors Date seasonalityBaseDate() - Frequency frequency() + Frequency frequency() vector[Rate] seasonalityFactors() Rate seasonalityFactor(Date &d) bool isConsistent(InflationTermStructure& iTS) - - - - diff --git a/quantlib/termstructures/inflation/interpolated_zero_inflation_curve.pyx b/quantlib/termstructures/inflation/interpolated_zero_inflation_curve.pyx index 20c63497e..45e668698 100644 --- a/quantlib/termstructures/inflation/interpolated_zero_inflation_curve.pyx +++ b/quantlib/termstructures/inflation/interpolated_zero_inflation_curve.pyx @@ -1,6 +1,4 @@ -include '../../types.pxi' - -from libcpp cimport bool +from quantlib.types cimport Rate from libcpp.vector cimport vector from cython.operator import dereference as deref @@ -9,18 +7,20 @@ cimport quantlib.termstructures.inflation._interpolated_zero_inflation_curve as cimport quantlib.math._interpolations as intpl cimport quantlib.time._date as _date from quantlib.time.date cimport Date, Period -from quantlib.time.calendar cimport Calendar from quantlib.time.daycounter cimport DayCounter from quantlib.time._period cimport Frequency +from .seasonality cimport Seasonality cdef class InterpolatedZeroInflationCurve(ZeroInflationTermStructure): def __init__(self, Interpolator interpolator, - Date reference_date, Calendar calendar not None, + Date reference_date, list dates, vector[Rate] rates, + Frequency frequency, DayCounter day_counter not None, - Period lag not None, Frequency frequency, - list dates, vector[Rate] rates): + Seasonality seasonality): cdef vector[_date.Date] _dates + cdef object date + for date in dates: _dates.push_back(deref((date)._thisptr)) @@ -28,27 +28,27 @@ cdef class InterpolatedZeroInflationCurve(ZeroInflationTermStructure): if interpolator == Linear: - self._thisptr.reset(new _izic.InterpolatedZeroInflationCurve[intpl.Linear]( - deref(reference_date._thisptr), calendar._thisptr, - deref(day_counter._thisptr), - deref(lag._thisptr), frequency, - _dates, rates)) - + self._thisptr.reset( + new _izic.InterpolatedZeroInflationCurve[intpl.Linear]( + deref(reference_date._thisptr), _dates, + rates, frequency, + deref(day_counter._thisptr), seasonality._thisptr) + ) elif interpolator == LogLinear: self._thisptr.reset( new _izic.InterpolatedZeroInflationCurve[intpl.LogLinear]( - deref(reference_date._thisptr), calendar._thisptr, - deref(day_counter._thisptr), - deref(lag._thisptr), frequency, - _dates, rates)) + deref(reference_date._thisptr), _dates, + rates, frequency, + deref(day_counter._thisptr), seasonality._thisptr) + ) elif interpolator == BackwardFlat: self._thisptr.reset( new _izic.InterpolatedZeroInflationCurve[intpl.BackwardFlat]( - deref(reference_date._thisptr), calendar._thisptr, - deref(day_counter._thisptr), - deref(lag._thisptr), frequency, - _dates, rates)) + deref(reference_date._thisptr), _dates, + rates, frequency, + deref(day_counter._thisptr), seasonality._thisptr) + ) else: raise ValueError("interpolator needs to be any of Linear, LogLinear or BackwardFlat") diff --git a/quantlib/termstructures/inflation/piecewise_zero_inflation_curve.pyx b/quantlib/termstructures/inflation/piecewise_zero_inflation_curve.pyx index 46756d592..3c016bcd7 100644 --- a/quantlib/termstructures/inflation/piecewise_zero_inflation_curve.pyx +++ b/quantlib/termstructures/inflation/piecewise_zero_inflation_curve.pyx @@ -1,30 +1,28 @@ -include '../../types.pxi' - -from libcpp cimport bool +from quantlib.types cimport Real from libcpp.vector cimport vector from cython.operator cimport dereference as deref from quantlib.handle cimport shared_ptr -from quantlib.time.calendar cimport Calendar from quantlib.time._period cimport Frequency -from quantlib.time.date cimport Date, Period +from quantlib.time.date cimport Date from quantlib.time.daycounter cimport DayCounter -from quantlib.termstructures.yield_term_structure cimport YieldTermStructure -from quantlib.termstructures.inflation.inflation_helpers cimport ZeroCouponInflationSwapHelper -from quantlib.termstructures.inflation.inflation_traits cimport ZeroInflationTraits +from .inflation_helpers cimport ZeroCouponInflationSwapHelper +from .inflation_traits cimport ZeroInflationTraits cimport quantlib.math._interpolations as intpl cimport quantlib.termstructures._inflation_term_structure as _its cimport quantlib.termstructures.inflation._piecewise_zero_inflation_curve as _pzic +from .seasonality cimport Seasonality cdef class PiecewiseZeroInflationCurve(InterpolatedZeroInflationCurve): def __init__(self, Interpolator interpolator, - Date reference_date not None, Calendar calendar not None, - DayCounter day_counter not None, Period lag not None, + Date reference_date not None, Date base_date, Frequency frequency, - Rate base_zero_rate, - list instruments, Real accuracy=1e-12): + DayCounter day_counter not None, + list instruments, Seasonality seasonality=Seasonality(), + Real accuracy=1e-12): cdef vector[shared_ptr[ZeroInflationTraits.helper]] instruments_cpp + cdef object i for i in instruments: instruments_cpp.push_back((i)._thisptr) @@ -35,30 +33,37 @@ cdef class PiecewiseZeroInflationCurve(InterpolatedZeroInflationCurve): self._thisptr.reset( new _pzic.PiecewiseZeroInflationCurve[intpl.Linear]( deref(reference_date._thisptr), - calendar._thisptr, + deref(base_date._thisptr), + frequency, deref(day_counter._thisptr), - deref(lag._thisptr), - frequency, base_zero_rate, instruments_cpp, - accuracy)) + seasonality._thisptr, + accuracy + ) + ) + elif interpolator == Interpolator.LogLinear: self._thisptr.reset( new _pzic.PiecewiseZeroInflationCurve[intpl.LogLinear]( - deref(reference_date._thisptr), - calendar._thisptr, + deref(reference_date._thisptr), + deref(base_date._thisptr), + frequency, deref(day_counter._thisptr), - deref(lag._thisptr), - frequency, base_zero_rate, instruments_cpp, - accuracy)) + seasonality._thisptr, + accuracy + ) + ) else: self._thisptr.reset( new _pzic.PiecewiseZeroInflationCurve[intpl.BackwardFlat]( deref(reference_date._thisptr), - calendar._thisptr, + deref(base_date._thisptr), + frequency, deref(day_counter._thisptr), - deref(lag._thisptr), - frequency, base_zero_rate, instruments_cpp, - accuracy)) + seasonality._thisptr, + accuracy + ) + ) diff --git a/quantlib/termstructures/inflation/seasonality.pyx b/quantlib/termstructures/inflation/seasonality.pyx index f7d7a26e4..ebf52c11b 100644 --- a/quantlib/termstructures/inflation/seasonality.pyx +++ b/quantlib/termstructures/inflation/seasonality.pyx @@ -7,9 +7,8 @@ FOR A PARTICULAR PURPOSE. See the license for more details. """ -include '../../types.pxi' - -from quantlib.handle cimport shared_ptr, Handle +from quantlib.types cimport Rate +from quantlib.handle cimport shared_ptr from cython.operator cimport dereference as deref from libcpp.vector cimport vector @@ -30,11 +29,6 @@ cimport quantlib._interest_rate as _ir cdef class Seasonality: - def __init__(self): - raise ValueError( - 'This is an abstract class: use MultiplicativePriceSeasonality instead.' - ) - def correctZeroRate(self, Date d, Rate r, diff --git a/test/test_inflation.py b/test/test_inflation.py index 0a1fe7ab3..b731362bb 100644 --- a/test/test_inflation.py +++ b/test/test_inflation.py @@ -9,7 +9,7 @@ import unittest -from quantlib.indexes.inflation.australia import AUCPI +from quantlib.indexes.inflation.aucpi import AUCPI from quantlib.time.date import Months, Period, Date from quantlib.time.api import ( UnitedKingdom, ModifiedFollowing, ActualActual, Schedule, Actual365Fixed, Unadjusted, Monthly ) @@ -31,7 +31,7 @@ class TestInflationIndex(unittest.TestCase): def test_zero_index(self): - aucpi = AUCPI(Monthly, True, True) + aucpi = AUCPI(Monthly, True) self.assertEqual(aucpi.name, "Australia CPI") self.assertEqual(aucpi.frequency, Monthly) self.assertEqual(aucpi.availability_lag, Period(2, Months)) @@ -51,7 +51,7 @@ def setUp(self): ModifiedFollowing) self.cpi_ts = ZeroInflationTermStructure() self.yts = FlatForward(evaluation_date, 0.05, day_counter) - self.ii = UKRPI(False, self.cpi_ts) + self.ii = UKRPI(self.cpi_ts) fix_data = [206.1, 207.3, 208.0, 208.9, 209.7, 210.9, 209.8, 211.4, 212.1, 214.0, 215.1, 216.8, 216.5, 217.2, 218.4, 217.7, 216, @@ -103,22 +103,22 @@ def setUp(self): observation_lag, maturity, self.calendar, ModifiedFollowing, day_counter, self.ii, InterpolationType.AsIndex, self.yts) \ for maturity, r in zip(dates, rates)] - base_zero_rate = rates[0] / 100 + base_date = self.ii.last_fixing_date self.cpi_ts.link_to( PiecewiseZeroInflationCurve(Interpolator.Linear, - evaluation_date, self.calendar, day_counter, - observation_lag, self.ii.frequency, - base_zero_rate, self.helpers)) + evaluation_date, base_date, self.ii.frequency, + day_counter, self.helpers) + ) def test_clean_price(self): - notional = 1000000.0; + notional = 1000000.0 fixed_rates = [0.1] fixed_day_count = Actual365Fixed() fixed_calendar = self.calendar fixed_index = self.ii - contractObservationLag = Period(3, Months); - observationInterpolation = InterpolationType.Flat; + contractObservationLag = Period(3, Months) + observationInterpolation = InterpolationType.Flat settlement_days = 3 growth_only = True @@ -139,7 +139,7 @@ def test_clean_price(self): engine = DiscountingBondEngine(self.yts) cpi_bond.set_pricing_engine(engine) set_coupon_pricer(cpi_bond.cashflows, CPICouponPricer(self.yts)) - storedPrice = 383.01816406 + storedPrice = 383.04297558 calculated = cpi_bond.clean_price self.assertAlmostEqual(storedPrice, calculated) diff --git a/test/test_swaption.py b/test/test_swaption.py index 75398eea9..7e684d444 100644 --- a/test/test_swaption.py +++ b/test/test_swaption.py @@ -42,10 +42,10 @@ def test_pricing_engine(self): swaption = self.factory() pe = BlackSwaptionEngine(self.yc, 0.3) swaption.set_pricing_engine(pe) - self.assertAlmostEqual(swaption.npv, 0.008429678) + self.assertAlmostEqual(swaption.npv, 0.008420333) self.assertAlmostEqual(swaption.atm_forward, 0.030234093) - self.assertAlmostEqual(swaption.vega, 0.07405690295) - self.assertAlmostEqual(swaption.annuity, 8.08710479) + self.assertAlmostEqual(swaption.vega, 0.0739748) + self.assertAlmostEqual(swaption.annuity, 8.0781391) if __name__ == '__main__': unittest.main()