diff --git a/quantlib/indexes/inflation/ukrpi.pyx b/quantlib/indexes/inflation/ukrpi.pyx index 21a9e2df4..e274ad51e 100644 --- a/quantlib/indexes/inflation/ukrpi.pyx +++ b/quantlib/indexes/inflation/ukrpi.pyx @@ -3,8 +3,8 @@ from libcpp cimport bool from quantlib.currency.api import GBPCurrency from quantlib.indexes.regions import UKRegion from quantlib.time.date cimport Period -from quantlib.time.date import Monthly, Months - +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 diff --git a/quantlib/indexes/inflation_index.pyx b/quantlib/indexes/inflation_index.pyx index bffe18ada..13ec35e1c 100644 --- a/quantlib/indexes/inflation_index.pyx +++ b/quantlib/indexes/inflation_index.pyx @@ -17,7 +17,7 @@ from libcpp.string cimport string from quantlib.index cimport Index from quantlib.time.date cimport Period, period_from_qlperiod -from quantlib.time._period cimport Frequency +from quantlib.time.frequency cimport Frequency from quantlib.indexes.region cimport Region from quantlib.currency.currency cimport Currency diff --git a/quantlib/mlab/fixed_income.py b/quantlib/mlab/fixed_income.py index 75caad258..aa6dfe481 100644 --- a/quantlib/mlab/fixed_income.py +++ b/quantlib/mlab/fixed_income.py @@ -21,7 +21,7 @@ from quantlib.time.calendars.null_calendar import NullCalendar from quantlib.time.calendars.target import TARGET from quantlib.time.date import ( - Date, Days, Period, Years, str_to_frequency) + Date, Days, Period, Years) from quantlib.time.schedule import Schedule from quantlib.time.dategeneration import DateGeneration @@ -88,8 +88,6 @@ def _bndprice(bond_yield, coupon_rate, pricing_date, maturity_date, Clean price and accrued interest of a bond """ - _period = str_to_frequency(period) - evaluation_date = pydate_to_qldate(pricing_date) settings = Settings() @@ -115,7 +113,7 @@ def _bndprice(bond_yield, coupon_rate, pricing_date, maturity_date, fixed_bond_schedule = Schedule.from_rule( effective_date, termination_date, - Period(_period), + Period(period), calendar, ModifiedFollowing, ModifiedFollowing, @@ -147,7 +145,7 @@ def _bndprice(bond_yield, coupon_rate, pricing_date, maturity_date, calendar=NullCalendar(), daycounter=cnt_yield, compounding=Compounded, - frequency=_period) + frequency=period) discounting_term_structure.link_to(flat_term_structure) @@ -201,8 +199,6 @@ def _cfamounts(coupon_rate, pricing_date, maturity_date, cash flow schedule """ - _period = str_to_frequency(period) - evaluation_date = pydate_to_qldate(pricing_date) settings = Settings() @@ -225,7 +221,7 @@ def _cfamounts(coupon_rate, pricing_date, maturity_date, fixed_bond_schedule = Schedule.from_rule( effective_date, termination_date, - Period(_period), + Period(period), calendar, ModifiedFollowing, ModifiedFollowing, diff --git a/quantlib/termstructures/yield_term_structure.pyx b/quantlib/termstructures/yield_term_structure.pyx index 8677e9bcd..bb7e05739 100644 --- a/quantlib/termstructures/yield_term_structure.pyx +++ b/quantlib/termstructures/yield_term_structure.pyx @@ -4,13 +4,12 @@ from cython.operator cimport dereference as deref from libcpp cimport bool from libcpp.vector cimport vector -from quantlib.time._period cimport Frequency +from quantlib.time.frequency cimport Frequency, Annual from quantlib.time.calendar cimport Calendar from quantlib.time.daycounter cimport DayCounter from quantlib.time.date cimport Date, date_from_qldate, Period from quantlib.compounding cimport Compounding -from quantlib.time.date import Annual cimport quantlib.termstructures._yield_term_structure as _yts cimport quantlib._quote as _qt @@ -56,7 +55,7 @@ cdef class YieldTermStructure(Observable): self.as_ptr().disableExtrapolation() def zero_rate(self, d, DayCounter day_counter=None, - Compounding compounding=Compounding.Continuous, int frequency=Annual, + Compounding compounding=Compounding.Continuous, Frequency frequency=Annual, bool extrapolate=False): """ Returns the implied zero-yield rate for the given date. diff --git a/quantlib/termstructures/yields/flat_forward.pyx b/quantlib/termstructures/yields/flat_forward.pyx index abf743de7..f702b7c98 100644 --- a/quantlib/termstructures/yields/flat_forward.pyx +++ b/quantlib/termstructures/yields/flat_forward.pyx @@ -9,13 +9,12 @@ include '../../types.pxi' from cython.operator cimport dereference as deref -from quantlib.time._period cimport Frequency +from quantlib.time.frequency cimport Frequency, Annual from quantlib.time.calendar cimport Calendar from quantlib.time.daycounter cimport DayCounter from quantlib.time.date cimport Date, date_from_qldate from quantlib.compounding cimport Compounding -from quantlib.time.date import Annual from quantlib.handle cimport shared_ptr, RelinkableHandle, Handle from . cimport _flat_forward as ffwd @@ -52,7 +51,7 @@ cdef class FlatForward(YieldTermStructure): DayCounter daycounter=None, int settlement_days=0, Calendar calendar=None, Compounding compounding=Compounding.Continuous, - frequency=Annual): + Frequency frequency=Annual): #local cdef's cdef shared_ptr[ffwd.YieldTermStructure] _forward @@ -70,7 +69,7 @@ cdef class FlatForward(YieldTermStructure): (forward).handle(), deref(daycounter._thisptr), compounding, - frequency + frequency )) else: _forward = shared_ptr[ffwd.YieldTermStructure](new ffwd.FlatForward( @@ -78,7 +77,7 @@ cdef class FlatForward(YieldTermStructure): forward, deref(daycounter._thisptr), compounding, - frequency + frequency )) elif settlement_days is not None and \ calendar is not None: @@ -90,7 +89,7 @@ cdef class FlatForward(YieldTermStructure): (forward).handle(), deref(daycounter._thisptr), compounding, - frequency + frequency )) else: _forward = shared_ptr[ffwd.YieldTermStructure](new ffwd.FlatForward( @@ -99,7 +98,7 @@ cdef class FlatForward(YieldTermStructure): forward, deref(daycounter._thisptr), compounding, - frequency + frequency )) else: raise ValueError('Invalid constructor') diff --git a/quantlib/time/api.py b/quantlib/time/api.py index 33546399d..d3adca9e1 100644 --- a/quantlib/time/api.py +++ b/quantlib/time/api.py @@ -33,16 +33,16 @@ from .date import ( - Date, Months, Period, today, Years, Days, Annual, Semiannual, Weeks, - Quarterly, Frequency, + Date, Months, Period, today, Years, Days, Weeks, January, February, March, April, May, June, July, August, September, November, December, Jan, Feb, Mar, Apr, Jun, Jul, Aug, Sep, Oct, Nov, Dec, - Daily, Monthly, Annual, NoFrequency, Once, pydate_from_qldate, qldate_from_pydate, local_date_time, universal_date_time ) - +from .frequency import ( + Frequency, Daily, Monthly, Quarterly, Semiannual, Annual, NoFrequency, Once +) from .schedule import Schedule from .dategeneration import DateGeneration diff --git a/quantlib/time/date.pyx b/quantlib/time/date.pyx index fc0de8f6d..8961284f8 100644 --- a/quantlib/time/date.pyx +++ b/quantlib/time/date.pyx @@ -62,30 +62,6 @@ cpdef enum Weekday: Fri = _date.Fri Sat = _date.Sat -cpdef enum Frequency: - NoFrequency = frequency.NoFrequency # null frequency - Once = frequency.Once # only once, e.g., a zero-coupon - Annual = frequency.Annual # once a year - Semiannual = frequency.Semiannual # twice a year - EveryFourthMonth = frequency.EveryFourthMonth # every fourth month - Quarterly = frequency.Quarterly # every third month - Bimonthly = frequency.Bimonthly # every second month - Monthly = frequency.Monthly # once a month - EveryFourthWeek = frequency.EveryFourthWeek # every fourth week - Biweekly = frequency.Biweekly # every second week - Weekly = frequency.Weekly # once a week - Daily = frequency.Daily # once a day - OtherFrequency = frequency.OtherFrequency # some other unknown frequency - -def frequency_to_str(Frequency f): - """ Converts a PyQL Frequency to a human readable string. """ - cdef frequency.stringstream ss - ss << f - return ss.str().decode() - -def str_to_frequency(str name): - """ Converts a string to a PyQL Frequency. """ - return Frequency[name] class TimeUnit(IntEnum): Days = _period.Days #: Days = 0 @@ -141,7 +117,7 @@ cdef class Period: property frequency: def __get__(self): - return Frequency(self._thisptr.get().frequency()) + return self._thisptr.get().frequency() def normalize(self): '''Normalises the units.''' diff --git a/quantlib/time/frequency.pxd b/quantlib/time/frequency.pxd index a82dab3de..7048c8fff 100644 --- a/quantlib/time/frequency.pxd +++ b/quantlib/time/frequency.pxd @@ -1,7 +1,7 @@ from libcpp.string cimport string -cdef extern from 'ql/time/frequency.hpp' namespace "QuantLib": - cdef enum Frequency: +cdef extern from 'ql/time/frequency.hpp' namespace "QuantLib" nogil: + cpdef enum Frequency: NoFrequency = -1 # null frequency Once = 0 # only once, e.g., a zero-coupon Annual = 1 # once a year diff --git a/quantlib/time/frequency.pyx b/quantlib/time/frequency.pyx new file mode 100644 index 000000000..e69de29bb diff --git a/test/test_bondfunctions.py b/test/test_bondfunctions.py index 824401d56..49a3c4eb5 100644 --- a/test/test_bondfunctions.py +++ b/test/test_bondfunctions.py @@ -13,12 +13,12 @@ from quantlib.time.calendars.null_calendar import NullCalendar from quantlib.compounding import Compounded, Continuous from quantlib.time.date import ( - Date, Days, Semiannual, January, August, Period, March, February, April, May, - Jul, Annual, Years + Date, Days, January, August, Period, March, February, April, May, + Jul, Years ) from quantlib.time.api import (TARGET, Period, Months, Years, Days,September, ISDA, today, Mar, ModifiedFollowing, Unadjusted, Actual360, Thirty360, ActualActual, Actual365Fixed, - Annual, UnitedStates, Months, Actual365Fixed) + Annual, UnitedStates, Months, Actual365Fixed, Annual, Semiannual) from quantlib.time.daycounters.actual_actual import Bond, ISMA from quantlib.time.schedule import Schedule from quantlib.time.dategeneration import DateGeneration diff --git a/test/test_bonds.py b/test/test_bonds.py index 524c88ddd..9ed719c75 100644 --- a/test/test_bonds.py +++ b/test/test_bonds.py @@ -10,9 +10,10 @@ from quantlib.time.calendars.null_calendar import NullCalendar from quantlib.time.calendars.target import TARGET from quantlib.compounding import Compounded, Continuous +from quantlib.time.frequency import Quarterly, Semiannual, Annual from quantlib.time.date import ( - Date, Days, Semiannual, January, August, Period, March, February,Oct,Nov, - Jul, Annual, Years, Quarterly + Date, Days, January, August, Period, March, February,Oct,Nov, + Jul, Years ) from quantlib.time.daycounters.simple import Actual365Fixed, Actual360 from quantlib.time.daycounters.actual_actual import ActualActual, Bond, ISMA diff --git a/test/test_date.py b/test/test_date.py index 63efeeaf5..28387410a 100644 --- a/test/test_date.py +++ b/test/test_date.py @@ -3,12 +3,40 @@ import unittest from quantlib.time.date import ( - Date, Jan, Feb, Mar, Apr, May, Jun, Jul, Sep, Nov, Thursday, Friday, + Date, + Jan, + Feb, + Mar, + Apr, + May, + Jun, + Jul, + Sep, + Nov, + Thursday, + Friday, Period, - Annual, Semiannual, Bimonthly, EveryFourthMonth, Months, Years, Weeks, - Days, OtherFrequency, end_of_month, is_end_of_month, is_leap, - next_weekday, nth_weekday, today, pydate_from_qldate, qldate_from_pydate, - local_date_time + Months, + Years, + Weeks, + Days, + end_of_month, + is_end_of_month, + is_leap, + next_weekday, + nth_weekday, + today, + pydate_from_qldate, + qldate_from_pydate, + local_date_time, +) +from quantlib.time.frequency import ( + Frequency, + Annual, + Semiannual, + EveryFourthMonth, + Bimonthly, + OtherFrequency, ) import quantlib.time.imm as imm @@ -16,9 +44,7 @@ class TestQuantLibDate(unittest.TestCase): - def test_today(self): - py_today = datetime.date.today() ql_today = today() @@ -48,7 +74,7 @@ def test_date_creation(self): # getting an invalid day date2 = Date(29, Feb, 2009) - date1 = Date('2017-08-18') + date1 = Date("2017-08-18") date2 = Date(18, 8, 2017) self.assertEqual(date1, date2) @@ -120,12 +146,12 @@ def test_arithmetic_operators(self): self.assertTrue(expected_date == date1) def test_next_weekday(self): - ''' Test next weekday + """Test next weekday The Friday following Tuesday, January 15th, 2002 was January 18th, 2002. see http://www.cpearson.com/excel/DateTimeWS.htm - ''' + """ date1 = Date(15, Jan, 2002) date2 = next_weekday(date1, Friday) @@ -134,9 +160,9 @@ def test_next_weekday(self): self.assertTrue(expected_date == date2) def test_nth_weekday(self): - ''' The 4th Thursday of Mar, 1998 was Mar 26th, 1998. + """The 4th Thursday of Mar, 1998 was Mar 26th, 1998. see http://www.cpearson.com/excel/DateTimeWS.htm - ''' + """ date1 = nth_weekday(4, Thursday, Mar, 1998) @@ -281,26 +307,24 @@ def test_adding_period_to_date(self): self.assertTrue(expected_date == date2) def test_period_subtraction(self): - period1 = Period(11, Months) period2 = Period(EveryFourthMonth) period3 = period1 - period2 self.assertEqual(7, period3.length) self.assertEqual(Months, period3.units) - with self.assertRaisesRegexp(RuntimeError, 'impossible addition'): - period1 - Period('3W') - self.assertEqual(-Period('3M') + Period('6M'), Period('3M')) + with self.assertRaisesRegex(RuntimeError, "impossible addition"): + period1 - Period("3W") + self.assertEqual(-Period("3M") + Period("6M"), Period("3M")) def test_period_addition(self): period1 = Period(4, Months) period2 = Period(7, Months) - self.assertEqual(period1+period2, Period(11, Months)) - with self.assertRaisesRegexp(RuntimeError, 'impossible addition'): - period1 + Period('2W') + self.assertEqual(period1 + period2, Period(11, Months)) + with self.assertRaisesRegex(RuntimeError, "impossible addition"): + period1 + Period("2W") def test_multiplication(self): - period = Period(Bimonthly) period2 = period * 10 @@ -388,17 +412,16 @@ def test_is_imm_date(self): self.assertFalse(is_imm) def test_is_imm_code(self): - - is_good = imm.is_IMM_code('H9') + is_good = imm.is_IMM_code("H9") self.assertTrue(is_good) - is_bad = imm.is_IMM_code('WX') + is_bad = imm.is_IMM_code("WX") self.assertFalse(is_bad) def test_imm_date(self): - dt = imm.date('M9') + dt = imm.date("M9") cd = imm.code(dt) - self.assertEqual(cd, 'M9') + self.assertEqual(cd, "M9") def test_next_date(self): dt = Date(19, Jun, 2014) @@ -406,7 +429,7 @@ def test_next_date(self): # 17 sep 2014 self.assertEqual(dt_2, date(2014, 9, 17)) - dt_3 = imm.next_date('M9', True, Date(1, 6, 2019)) + dt_3 = imm.next_date("M9", True, Date(1, 6, 2019)) # 18 sep 2019 self.assertEqual(dt_3, date(2019, 9, 18)) @@ -416,6 +439,6 @@ def test_next_code(self): # M4 self.assertEqual(cd_2, "M4") - cd_3 = imm.next_code('M9', True, today()) + cd_3 = imm.next_code("M9", True, today()) # U9 self.assertEqual(cd_3, "U9") diff --git a/test/test_inflation.py b/test/test_inflation.py index 92dbe026d..0a1fe7ab3 100644 --- a/test/test_inflation.py +++ b/test/test_inflation.py @@ -10,9 +10,9 @@ import unittest from quantlib.indexes.inflation.australia import AUCPI -from quantlib.time.date import Monthly, Months, Period, Date +from quantlib.time.date import Months, Period, Date from quantlib.time.api import ( UnitedKingdom, ModifiedFollowing, ActualActual, - Schedule, Actual365Fixed, Unadjusted ) + Schedule, Actual365Fixed, Unadjusted, Monthly ) from quantlib.time.dategeneration import DateGeneration from quantlib.instruments.bonds.cpibond import CPIBond, InterpolationType from quantlib.pricingengines.bond import DiscountingBondEngine diff --git a/test/test_mlab.py b/test/test_mlab.py index 67e4f15ba..8ff27b19b 100644 --- a/test/test_mlab.py +++ b/test/test_mlab.py @@ -13,7 +13,7 @@ from quantlib.termstructures.yields.api import ( PiecewiseYieldCurve, BootstrapTrait ) from quantlib.math.interpolation import LogLinear -from quantlib.time.api import ActualActual, ISDA +from quantlib.time.api import ActualActual, ISDA, Frequency from quantlib.util.converter import pydate_to_qldate @@ -117,9 +117,9 @@ def test_bndprice(self): (price, ac) = bndprice(bond_yield=Yield, coupon_rate=CouponRate, pricing_date='18-Jan-1997', maturity_date=Maturity, - period='Semiannual', + period=Frequency['Semiannual'], basis='Actual/Actual (Bond)', - compounding_frequency='Semiannual') + compounding_frequency=Frequency['Semiannual']) # Matlab values ml_price = [104.8106, 99.9951, 95.4384] @@ -141,7 +141,7 @@ def test_cfamounts(self): res = cfamounts(coupon_rate=CouponRate, pricing_date='29-oct-1993', maturity_date=Maturity, - period='Semiannual', + period=Frequency['Semiannual'], basis='Actual/Actual (Bond)') for cf, dt in zip(*res): diff --git a/test/test_sensitivity_analysis.py b/test/test_sensitivity_analysis.py index 302617afe..66d5ea73e 100644 --- a/test/test_sensitivity_analysis.py +++ b/test/test_sensitivity_analysis.py @@ -7,12 +7,12 @@ from quantlib.instruments.option import VanillaOption, OptionType from quantlib.instruments.exercise import EuropeanExercise from quantlib.time.date import ( - Date, Days, Semiannual, January, - Period, May, Annual, Years) + Date, Days, January, + Period, May, Years) from quantlib.time.api import (Months, ISDA, ModifiedFollowing, Unadjusted, Actual360, Thirty360, ActualActual, - Actual365Fixed) + Actual365Fixed, Semiannual, Annual) from quantlib.time.daycounters.actual_actual import Bond from quantlib.time.schedule import Schedule from quantlib.time.dategeneration import DateGeneration