diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/dates.py | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/python/dates.py b/python/dates.py index 348c2b48..7d178f69 100644 --- a/python/dates.py +++ b/python/dates.py @@ -3,6 +3,7 @@ import pandas as pd import unittest from dateutil.relativedelta import relativedelta, WE, MO + try: from dateutil.parser import isoparse except ImportError: @@ -11,17 +12,21 @@ except ImportError: from pandas.tseries.offsets import CustomBusinessDay, Day, QuarterBegin from pandas.tseries.holiday import get_calendar, HolidayCalendarFactory, GoodFriday -fed_cal = get_calendar('USFederalHolidayCalendar') -bond_cal = HolidayCalendarFactory('BondCalendar', fed_cal, GoodFriday) +fed_cal = get_calendar("USFederalHolidayCalendar") +bond_cal = HolidayCalendarFactory("BondCalendar", fed_cal, GoodFriday) bus_day = CustomBusinessDay(calendar=bond_cal()) + def imm_dates(start_date, end_date): start_date = bus_day.rollback(start_date) - 19 * Day() start_date = QuarterBegin(startingMonth=3).rollback(start_date) - #should be close=left I think - return (pd.date_range(start_date, end_date, freq='QS-MAR', closed=None). - shift(19, freq='D'). - shift(0, bus_day)) + # should be close=left I think + return ( + pd.date_range(start_date, end_date, freq="QS-MAR", closed=None) + .shift(19, freq="D") + .shift(0, bus_day) + ) + def previous_twentieth(d): r = datetime.date(d.year, d.month, 20) @@ -29,56 +34,68 @@ def previous_twentieth(d): r -= relativedelta(months=1) mod = r.month % 3 if mod != 0: - r -= relativedelta(months = mod) + r -= relativedelta(months=mod) return r + def imm_date(d): if isinstance(d, str): d = isoparse(d) r = d + relativedelta(day=1, weekday=WE(3)) - return r + relativedelta(weekday=MO(-1)) + if r <= d: + return imm_date(r + relativedelta(months=1, day=1)) + return r + def days_accrued(tradedate): tradedate = pd.Timestamp(tradedate) start_protection = tradedate + Day() # we want the the largest twentieth imm date rolled forward such that # it's less than start_protection - effective_date = pd.Timestamp(previous_twentieth(bus_day.rollback(start_protection).date())) + effective_date = pd.Timestamp( + previous_twentieth(bus_day.rollback(start_protection).date()) + ) effective_date = bus_day.rollforward(effective_date) delta = start_protection - effective_date return delta.days + def isleapyear(date): - return ((date.year % 4) == 0 & (~(date.year % 100 == 0) | date.year % 400 == 0)) + return (date.year % 4) == 0 & (~(date.year % 100 == 0) | date.year % 400 == 0) + def yearfrac(date1, date2, daycount): - if daycount == '30/360': + if daycount == "30/360": d1 = date1.dt.day.copy() d2 = date2.dt.day.copy() - d2[(d2==31) & (d1.isin([30,31]))] = 30 - d1.replace({31:30}) + d2[(d2 == 31) & (d1.isin([30, 31]))] = 30 + d1.replace({31: 30}) y1 = date1.dt.year y2 = date2.dt.year m1 = date1.dt.month m2 = date2.dt.month - return (360*(y2-y1)+30*(m2-m1)+d2-d1)/360 + return (360 * (y2 - y1) + 30 * (m2 - m1) + d2 - d1) / 360 days_accrued = date2 - date1 - if daycount == 'ACT/365': - return days_accrued.dt.days/365 - if daycount == 'ACT/360': - return days_accrued.dt.days/360 + if daycount == "ACT/365": + return days_accrued.dt.days / 365 + if daycount == "ACT/360": + return days_accrued.dt.days / 360 + class TestDaysAccrued(unittest.TestCase): def test(self): - dates = [('2015-01-07', 17), - ('2015-06-19', 92), - ('2015-03-19', 0), - ('2015-06-20', 93), - ('2015-06-21', 0), - ('2015-12-21', 1), - ('2015-12-28', 8)] + dates = [ + ("2015-01-07", 17), + ("2015-06-19", 92), + ("2015-03-19", 0), + ("2015-06-20", 93), + ("2015-06-21", 0), + ("2015-12-21", 1), + ("2015-12-28", 8), + ] for date, days in dates: self.assertEqual(days_accrued(date), days) -if __name__=="__main__": + +if __name__ == "__main__": unittest.main() |
