diff options
| -rw-r--r-- | python/analytics/utils.py | 46 | ||||
| -rw-r--r-- | python/tests/test_dates.py | 53 |
2 files changed, 97 insertions, 2 deletions
diff --git a/python/analytics/utils.py b/python/analytics/utils.py index c499c65f..e3ffecaa 100644 --- a/python/analytics/utils.py +++ b/python/analytics/utils.py @@ -1,4 +1,5 @@ import numpy as np +import pandas as pd from scipy.special import h_roots from dateutil.relativedelta import relativedelta import datetime @@ -9,10 +10,51 @@ def GHquad(n): return Z*np.sqrt(2), w/np.sqrt(np.pi) def previous_twentieth(d): - r = datetime.date(d.year, d.month, 20) + r = d + relativedelta(day=20) if r > d: r -= relativedelta(months=1) mod = r.month % 3 if mod != 0: - r -= relativedelta(months = mod) + r -= relativedelta(months=mod) return r + +def next_twentieth(d): + r = d + relativedelta(day=20) + if(r < d): + r += relativedelta(months=1) + mod = r.month % 3 + if mod != 0: + r += relativedelta(months=3 - mod) + return r + +def roll_date(d, tenor): + """ roll date d to the next CDS maturity""" + cutoff = pd.Timestamp('2015-12-20') + if not isinstance(d, pd.Timestamp): + cutoff = cutoff.date() + if d <= cutoff: + if isinstance(tenor, (int, float)): + d_rolled = d + relativedelta(years=tenor, days=1) + return next_twentieth(d_rolled) + elif hasattr(tenor, '__iter__'): + d_rolled = [next_twentieth(d + relativedelta(years=t, days=1)) for t in tenor] + else: + raise TypeError('tenor is not a number nor an iterable') + else: #semi-annual rolling starting 2015-12-20 + if isinstance(tenor, (int, float)): + d_rolled = d + relativedelta(years=tenor) + elif hasattr(tenor, '__iter__'): + d_rolled = d + relativedelta(years=1) + else: + raise TypeError('tenor is not a number nor an iterable') + if((d >= d + relativedelta(month=9, day=20)) or \ + (d < d + relativedelta(month=3, day=20))): + d_rolled += relativedelta(month=12, day=20) + if d.month <= 3: + d_rolled -= relativedelta(years=1) + else: + d_rolled += relativedelta(month=6, day=20) + if isinstance(tenor, (int, float)): + return d_rolled + else: + return [d_rolled + relativedelta(years=t-1) for t in tenor] diff --git a/python/tests/test_dates.py b/python/tests/test_dates.py new file mode 100644 index 00000000..860d9426 --- /dev/null +++ b/python/tests/test_dates.py @@ -0,0 +1,53 @@ +import unittest +import datetime +import pandas as pd + +import sys +sys.path.append('..') +from analytics.utils import * + +class TestStartDate(unittest.TestCase): + + def test_previous_twentieth(self): + self.assertEqual(previous_twentieth(datetime.date(2016, 9, 20)), + datetime.date(2016, 9, 20)) + self.assertEqual(previous_twentieth(datetime.date(2016, 10, 15)), + datetime.date(2016, 9, 20)) + self.assertEqual(previous_twentieth(datetime.date(2016, 12, 20)), + datetime.date(2016, 12, 20)) + self.assertEqual(previous_twentieth(datetime.date(2017, 3, 19)), + datetime.date(2016, 12, 20)) + + def test_previous_twentieth_timestamp(self): + self.assertEqual(previous_twentieth(pd.Timestamp('2016-09-20')), + pd.Timestamp('2016-09-20')) + self.assertEqual(previous_twentieth(pd.Timestamp('2016-10-15')), + pd.Timestamp('2016-09-20')) + self.assertEqual(previous_twentieth(pd.Timestamp('2016-12-20')), + pd.Timestamp('2016-12-20')) + self.assertEqual(previous_twentieth(pd.Timestamp('2017-03-19')), + pd.Timestamp('2016-12-20')) + +class TestEndDate(unittest.TestCase): + def test_enddate(self): + self.assertEqual(roll_date(datetime.date(2016, 9, 20), 5), + datetime.date(2021, 12, 20)) + self.assertEqual(roll_date(datetime.date(2016, 10, 15), 5), + datetime.date(2021, 12, 20)) + self.assertEqual(roll_date(datetime.date(2017, 3, 19), 5), + datetime.date(2021, 12, 20)) + self.assertEqual(roll_date(datetime.date(2017, 3, 20), 5), + datetime.date(2022, 6, 20)) + + def test_enddate_pre2015(self): + self.assertEqual(roll_date(datetime.date(2014, 9, 20), 5), + datetime.date(2019, 12, 20)) + self.assertEqual(roll_date(datetime.date(2014, 10, 15), 5), + datetime.date(2019, 12, 20)) + self.assertEqual(roll_date(datetime.date(2015, 3, 19), 5), + datetime.date(2020, 3, 20)) + self.assertEqual(roll_date(datetime.date(2015, 3, 20), 5), + datetime.date(2020, 6, 20)) + +if __name__=="__main__": + unittest.main() |
