def test_date_advance_out_of_bounds(self): test_date = Date(2199, 12, 30) with self.assertRaises(ValueError): _ = test_date + '1w' test_date = Date(1901, 1, 1) with self.assertRaises(ValueError): _ = test_date - '1w'
def test_schedule_initialize_yearly(self): start_date = Date(2012, 2, 29) end_date = Date(2013, 3, 1) tenor = Period('1y') cal = Calendar('NullCalendar') sch = Schedule(start_date, end_date, tenor, cal) expected = [Date(2012, 2, 29), Date(2013, 2, 28), Date(2013, 3, 1)] for i in range(sch.size()): self.assertEqual(expected[i], sch[i])
def test_schedule_deep_copy(self): start_date = Date(2013, 3, 31) end_date = Date(2013, 7, 1) tenor = Period('1m') cal = Calendar('NullCalendar') sch = Schedule(start_date, end_date, tenor, cal) copied_sch = copy.deepcopy(sch) self.assertEqual(sch, copied_sch)
def test_parse_dates(self): input_date = "2006-01-15" d = Date.strptime(input_date, "%Y-%m-%d") flag = d == Date(2006, 1, 15) self.assertTrue( flag, "date parsing failed\n" " input date: {0:s}\n" " parsed: {1}".format(input_date, d)) input_date = "12/02/2012" d = Date.strptime(input_date, "%m/%d/%Y") flag = d == Date(2012, 12, 2) self.assertTrue( flag, "date parsing failed\n" " input date: {0:s}\n" " parsed: {1}".format(input_date, d)) d = Date.strptime(input_date, "%d/%m/%Y") flag = d == Date(2012, 2, 12) self.assertTrue( flag, "date parsing failed\n" " input date: {0:s}\n" " parsed: {1}".format(input_date, d)) input_date = "20011002" d = Date.strptime(input_date, "%Y%m%d") flag = d == Date(2001, 10, 2) self.assertTrue( flag, "date parsing failed\n" " input date: {0:s}\n" " parsed: {1}".format(input_date, d))
def test_calendar_with_date_convention(self): sse_cal = Calendar('China.SSE') reference_date = Date(2015, 2, 14) test_date = sse_cal.adjust_date( reference_date, BizDayConventions.HalfMonthModifiedFollowing) self.assertEqual(test_date, Date(2015, 2, 13)) reference_date = Date(2014, 2, 4) test_date = sse_cal.adjust_date( reference_date, BizDayConventions.ModifiedPreceding) self.assertEqual(test_date, Date(2014, 2, 7)) reference_date = Date(2014, 2, 3) test_date = sse_cal.adjust_date(reference_date, BizDayConventions.Nearest) self.assertEqual(test_date, Date(2014, 2, 7)) reference_date = Date(2014, 2, 2) test_date = sse_cal.adjust_date(reference_date, BizDayConventions.Nearest) self.assertEqual(test_date, Date(2014, 1, 30)) with self.assertRaises(ValueError): _ = sse_cal.adjust_date(reference_date, -1)
def test_schedule_pickle(self): start_date = Date(2013, 3, 31) end_date = Date(2013, 7, 1) tenor = Period('1m') cal = Calendar('NullCalendar') sch = Schedule(start_date, end_date, tenor, cal) f = tempfile.NamedTemporaryFile('w+b', delete=False) pickle.dump(sch, f) f.close() with open(f.name, 'rb') as f2: pickled_sch = pickle.load(f2) self.assertEqual(sch, pickled_sch) os.unlink(f.name)
def test_date_pickle(self): benchmark_date = Date(2016, 1, 2) f = tempfile.NamedTemporaryFile('w+b', delete=False) pickle.dump(benchmark_date, f) f.close() with open(f.name, 'rb') as f2: pickled_date = pickle.load(f2) self.assertEqual(benchmark_date, pickled_date) os.unlink(f.name)
def test_ios_dates(self): input_date = "2006-01-15" d = Date.parse_iso(input_date) flag = d.day_of_month() == 15 and \ d.month() == 1 and \ d.year() == 2006 self.assertTrue( flag, "Iso date failed\n" " input date: {0}\n" " day of month: {1:d}\n" " month: {2:d}\n" " year: {3:d}".format(input_date, d.day_of_month(), d.month(), d.year()))
def test_adjust_date(self): # April 30, 2005 is a working day under IB, but a holiday under SSE reference_date = Date(2005, Months.April, 30) sse_cal = Calendar('China.SSE') ib_cal = Calendar('China.IB') biz_day_conv = BizDayConventions.Unadjusted self.assertEqual(sse_cal.adjust_date(reference_date, biz_day_conv), reference_date) self.assertEqual(ib_cal.adjust_date(reference_date, biz_day_conv), reference_date) biz_day_conv = BizDayConventions.Following self.assertEqual(sse_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.May, 9)) self.assertEqual(ib_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.April, 30)) biz_day_conv = BizDayConventions.ModifiedFollowing self.assertEqual(sse_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.April, 29)) self.assertEqual(ib_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.April, 30))
def test_schedule_initialize(self): start_date = Date(2013, 3, 31) end_date = Date(2013, 7, 1) tenor = Period('1m') cal = Calendar('NullCalendar') sch = Schedule(start_date, end_date, tenor, cal) expected = [ Date(2013, 4, 1), Date(2013, 4, 30), Date(2013, 5, 31), Date(2013, 7, 1) ] for i in range(sch.size()): self.assertEqual(expected[i], sch[i])
def test_advance_date(self): reference_date = Date(2014, 1, 31) sse_cal = Calendar('China.SSE') ib_cal = Calendar('China.IB') biz_day_conv = BizDayConventions.Following # test null period self.assertEqual( sse_cal.advance_date(reference_date, Period('0b'), biz_day_conv), Date(2014, 2, 7)) # test negative period self.assertEqual( sse_cal.advance_date(reference_date, Period('-5b'), biz_day_conv), Date(2014, 1, 24)) # The difference is caused by Feb 8 is SSE holiday but a working day for IB market self.assertEqual( sse_cal.advance_date(reference_date, Period('2b'), biz_day_conv), Date(2014, 2, 10)) self.assertEqual( sse_cal.advance_date(reference_date, Period('2d'), biz_day_conv), Date(2014, 2, 7)) self.assertEqual( ib_cal.advance_date(reference_date, Period('2b'), biz_day_conv), Date(2014, 2, 8)) self.assertEqual( ib_cal.advance_date(reference_date, Period('2d'), biz_day_conv), Date(2014, 2, 7)) biz_day_conv = BizDayConventions.ModifiedFollowing # May 31, 2014 is a holiday self.assertEqual( sse_cal.advance_date(reference_date, Period('4m'), biz_day_conv, True), Date(2014, 5, 30))
def test_basic_functions(self): test_date = Date(2015, 7, 11) cal = Calendar('China.SSE') self.assertTrue(cal.is_weekend(test_date.weekday()), "{0} is expected to be a weekend".format(test_date)) test_date = Date(2015, 7, 13) self.assertTrue( not cal.is_weekend(test_date.weekday()), "{0} is expected not to be a weekend".format(test_date)) test_date = Date(2015, 5, 29) cal = Calendar('China.SSE') self.assertTrue( cal.is_end_of_month(test_date), "{0} is expected to be a end of month".format(test_date)) test_date = Date(2015, 5, 1) cal = Calendar('China.SSE') end_of_month = cal.end_of_month(test_date) self.assertEqual( end_of_month, Date(2015, 5, 29), "The month end of 2015/5 is expected to be {0}".format( Date(2015, 5, 29))) biz_dates1 = cal.biz_days_between(Date(2015, 1, 1), Date(2015, 12, 31), True, False) biz_dates2 = cal.biz_days_between(Date(2015, 12, 31), Date(2015, 1, 1), False, True) self.assertEqual(biz_dates1, biz_dates2)
def test_daily_schedule(self): # Jan 2 and Jan 3 are skipped as New Year holiday # Jan 7 is skipped as weekend # Jan 8 is adjusted to Jan 9 with following convention start_date = Date(2012, 1, 1) s = Schedule(start_date, start_date + 7, Period(length=1, units=TimeUnits.Days), Calendar("China.SSE"), BizDayConventions.Preceding) expected = [ Date(2011, 12, 30), Date(2012, 1, 4), Date(2012, 1, 5), Date(2012, 1, 6), Date(2012, 1, 9) ] self.check_dates(s, expected) # The schedule should skip Saturday 21st and Sunday 22rd. # Previously, it would adjust them to Friday 20th, resulting # in three copies of the same date. start_date = Date(2012, 1, 17) s = Schedule(start_date, start_date + 7, Period(length=1, units=TimeUnits.Days), Calendar("Target"), BizDayConventions.Preceding) expected = [ Date(2012, 1, 17), Date(2012, 1, 18), Date(2012, 1, 19), Date(2012, 1, 20), Date(2012, 1, 23), Date(2012, 1, 24) ] self.check_dates(s, expected)
def test_date_input_without_complete_information_on_year_month_day(self): year = 2015 month = None day = 18 with self.assertRaises(TypeError): _ = Date(year=year, month=month, day=day)
def test_china_sse(self): # China Shanghai Securities Exchange holiday list in the year 2014 expected_hol = [ Date(2014, 1, 1), Date(2014, 1, 31), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6), Date(2014, 4, 7), Date(2014, 5, 1), Date(2014, 5, 2), Date(2014, 6, 2), Date(2014, 9, 8), Date(2014, 10, 1), Date(2014, 10, 2), Date(2014, 10, 3), Date(2014, 10, 6), Date(2014, 10, 7), # China Shanghai Securities Exchange holiday list in the year 2015 Date(2015, 1, 1), Date(2015, 1, 2), Date(2015, 2, 18), Date(2015, 2, 19), Date(2015, 2, 20), Date(2015, 2, 23), Date(2015, 2, 24), Date(2015, 4, 6), Date(2015, 5, 1), Date(2015, 6, 22), Date(2015, 9, 3), Date(2015, 9, 4), Date(2015, 10, 1), Date(2015, 10, 2), Date(2015, 10, 5), Date(2015, 10, 6), Date(2015, 10, 7), # China Shanghai Securities Exchange holiday list in the year 2016 Date(2016, 1, 1), Date(2016, 2, 8), Date(2016, 2, 9), Date(2016, 2, 10), Date(2016, 2, 11), Date(2016, 2, 12), Date(2016, 4, 4), Date(2016, 5, 2), Date(2016, 6, 9), Date(2016, 6, 10), Date(2016, 9, 15), Date(2016, 9, 16), Date(2016, 10, 3), Date(2016, 10, 4), Date(2016, 10, 5), Date(2016, 10, 6), Date(2016, 10, 7), # China Shanghai Securities Exchange holiday list in the year 2017 Date(2017, 1, 1), Date(2017, 1, 2), Date(2017, 1, 27), Date(2017, 1, 28), Date(2017, 1, 29), Date(2017, 1, 30), Date(2017, 1, 31), Date(2017, 2, 1), Date(2017, 2, 2), Date(2017, 4, 2), Date(2017, 4, 3), Date(2017, 4, 4), Date(2017, 5, 1), Date(2017, 5, 28), Date(2017, 5, 29), Date(2017, 5, 30), Date(2017, 10, 1), Date(2017, 10, 2), Date(2017, 10, 3), Date(2017, 10, 4), Date(2017, 10, 5), Date(2017, 10, 6), Date(2017, 10, 7), Date(2017, 10, 8), # China Shanghai Securities Exchange holiday list in the year 2018 Date(2018, 1, 1), Date(2018, 2, 15), Date(2018, 2, 16), Date(2018, 2, 17), Date(2018, 2, 18), Date(2018, 2, 19), Date(2018, 2, 20), Date(2018, 2, 21), Date(2018, 4, 5), Date(2018, 4, 6), Date(2018, 4, 7), Date(2018, 4, 29), Date(2018, 4, 30), Date(2018, 5, 1), Date(2018, 6, 16), Date(2018, 6, 17), Date(2018, 6, 18), Date(2018, 9, 22), Date(2018, 9, 23), Date(2018, 9, 24), Date(2018, 10, 1), Date(2018, 10, 2), Date(2018, 10, 3), Date(2018, 10, 4), Date(2018, 10, 5), Date(2018, 10, 6), Date(2018, 10, 7) ] cal = Calendar('China.SSE') for day in expected_hol: self.assertEqual( cal.is_holiday(day), True, "{0} is expected to be a holiday in {1}".format(day, cal)) self.assertEqual( cal.is_biz_day(day), False, "{0} is expected not to be a working day in {1} ".format( day, cal))
def test_null_calendar(self): cal = Calendar("Null") test_date = Date(2015, 1, 1) self.assertTrue(cal.is_biz_day(test_date)) self.assertTrue(not cal.is_holiday(test_date)) self.assertTrue(cal.is_weekend(Weekdays.Saturday)) self.assertTrue(cal.is_weekend(Weekdays.Sunday)) self.assertTrue(not cal.is_weekend(Weekdays.Friday)) self.assertEquals( cal.holiday_dates_list(Date(2018, 10, 29), Date(2018, 11, 5), True), [Date(2018, 11, 3), Date(2018, 11, 4)]) def test_china_sse(self): # China Shanghai Securities Exchange holiday list in the year 2014 expected_hol = [ Date(2014, 1, 1), Date(2014, 1, 31), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6), Date(2014, 4, 7), Date(2014, 5, 1), Date(2014, 5, 2), Date(2014, 6, 2), Date(2014, 9, 8), Date(2014, 10, 1), Date(2014, 10, 2), Date(2014, 10, 3), Date(2014, 10, 6), Date(2014, 10, 7), # China Shanghai Securities Exchange holiday list in the year 2015 Date(2015, 1, 1), Date(2015, 1, 2), Date(2015, 2, 18), Date(2015, 2, 19), Date(2015, 2, 20), Date(2015, 2, 23), Date(2015, 2, 24), Date(2015, 4, 6), Date(2015, 5, 1), Date(2015, 6, 22), Date(2015, 9, 3), Date(2015, 9, 4), Date(2015, 10, 1), Date(2015, 10, 2), Date(2015, 10, 5), Date(2015, 10, 6), Date(2015, 10, 7), # China Shanghai Securities Exchange holiday list in the year 2016 Date(2016, 1, 1), Date(2016, 2, 8), Date(2016, 2, 9), Date(2016, 2, 10), Date(2016, 2, 11), Date(2016, 2, 12), Date(2016, 4, 4), Date(2016, 5, 2), Date(2016, 6, 9), Date(2016, 6, 10), Date(2016, 9, 15), Date(2016, 9, 16), Date(2016, 10, 3), Date(2016, 10, 4), Date(2016, 10, 5), Date(2016, 10, 6), Date(2016, 10, 7), # China Shanghai Securities Exchange holiday list in the year 2017 Date(2017, 1, 1), Date(2017, 1, 2), Date(2017, 1, 27), Date(2017, 1, 28), Date(2017, 1, 29), Date(2017, 1, 30), Date(2017, 1, 31), Date(2017, 2, 1), Date(2017, 2, 2), Date(2017, 4, 2), Date(2017, 4, 3), Date(2017, 4, 4), Date(2017, 5, 1), Date(2017, 5, 28), Date(2017, 5, 29), Date(2017, 5, 30), Date(2017, 10, 1), Date(2017, 10, 2), Date(2017, 10, 3), Date(2017, 10, 4), Date(2017, 10, 5), Date(2017, 10, 6), Date(2017, 10, 7), Date(2017, 10, 8), # China Shanghai Securities Exchange holiday list in the year 2018 Date(2018, 1, 1), Date(2018, 2, 15), Date(2018, 2, 16), Date(2018, 2, 17), Date(2018, 2, 18), Date(2018, 2, 19), Date(2018, 2, 20), Date(2018, 2, 21), Date(2018, 4, 5), Date(2018, 4, 6), Date(2018, 4, 7), Date(2018, 4, 29), Date(2018, 4, 30), Date(2018, 5, 1), Date(2018, 6, 16), Date(2018, 6, 17), Date(2018, 6, 18), Date(2018, 9, 22), Date(2018, 9, 23), Date(2018, 9, 24), Date(2018, 10, 1), Date(2018, 10, 2), Date(2018, 10, 3), Date(2018, 10, 4), Date(2018, 10, 5), Date(2018, 10, 6), Date(2018, 10, 7) ] cal = Calendar('China.SSE') for day in expected_hol: self.assertEqual( cal.is_holiday(day), True, "{0} is expected to be a holiday in {1}".format(day, cal)) self.assertEqual( cal.is_biz_day(day), False, "{0} is expected not to be a working day in {1} ".format( day, cal)) def testChinaIB(self): # China Inter Bank working weekend list in the year 2014 expected_working_week_end = [ Date(2014, 1, 26), Date(2014, 2, 8), Date(2014, 5, 4), Date(2014, 9, 28), Date(2014, 10, 11), # China Inter Bank working weekend list in the year 2015 Date(2015, 1, 4), Date(2015, 2, 15), Date(2015, 2, 28), Date(2015, 9, 6), Date(2015, 10, 10), # China Inter Bank working weekend list in the year 2016 Date(2016, 2, 6), Date(2016, 2, 14), Date(2016, 6, 12), Date(2016, 9, 18), Date(2016, 10, 8), Date(2016, 10, 9), # China Inter Bank working weekend list in the year 2017 Date(2017, 1, 22), Date(2017, 2, 4), Date(2017, 4, 1), Date(2017, 5, 27), Date(2017, 9, 30), # China Inter Bank working weekend list in the year 2018 Date(2018, 2, 11), Date(2018, 2, 24), Date(2018, 4, 8), Date(2018, 4, 28), Date(2018, 9, 29), Date(2018, 9, 30) ] cal = Calendar('China.IB') for day in expected_working_week_end: self.assertEqual( cal.is_holiday(day), False, "{0} is not expected to be a holiday in {1}".format( day, cal)) self.assertEqual( cal.is_biz_day(day), True, "{0} is expected to be a working day in {1} ".format( day, cal)) def test_adjust_date(self): # April 30, 2005 is a working day under IB, but a holiday under SSE reference_date = Date(2005, Months.April, 30) sse_cal = Calendar('China.SSE') ib_cal = Calendar('China.IB') biz_day_conv = BizDayConventions.Unadjusted self.assertEqual(sse_cal.adjust_date(reference_date, biz_day_conv), reference_date) self.assertEqual(ib_cal.adjust_date(reference_date, biz_day_conv), reference_date) biz_day_conv = BizDayConventions.Following self.assertEqual(sse_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.May, 9)) self.assertEqual(ib_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.April, 30)) biz_day_conv = BizDayConventions.ModifiedFollowing self.assertEqual(sse_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.April, 29)) self.assertEqual(ib_cal.adjust_date(reference_date, biz_day_conv), Date(2005, Months.April, 30)) def test_advance_date(self): reference_date = Date(2014, 1, 31) sse_cal = Calendar('China.SSE') ib_cal = Calendar('China.IB') biz_day_conv = BizDayConventions.Following # test null period self.assertEqual( sse_cal.advance_date(reference_date, Period('0b'), biz_day_conv), Date(2014, 2, 7)) # test negative period self.assertEqual( sse_cal.advance_date(reference_date, Period('-5b'), biz_day_conv), Date(2014, 1, 24)) # The difference is caused by Feb 8 is SSE holiday but a working day for IB market self.assertEqual( sse_cal.advance_date(reference_date, Period('2b'), biz_day_conv), Date(2014, 2, 10)) self.assertEqual( sse_cal.advance_date(reference_date, Period('2d'), biz_day_conv), Date(2014, 2, 7)) self.assertEqual( ib_cal.advance_date(reference_date, Period('2b'), biz_day_conv), Date(2014, 2, 8)) self.assertEqual( ib_cal.advance_date(reference_date, Period('2d'), biz_day_conv), Date(2014, 2, 7)) biz_day_conv = BizDayConventions.ModifiedFollowing # May 31, 2014 is a holiday self.assertEqual( sse_cal.advance_date(reference_date, Period('4m'), biz_day_conv, True), Date(2014, 5, 30)) def test_date_list(self): from_date = Date(2014, 1, 31) to_date = Date(2014, 2, 28) sse_cal = Calendar('China.SSE') ib_cal = Calendar('China.IB') benchmark_hol = [ Date(2014, 1, 31), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6) ] sse_hol_list = sse_cal.holiday_dates_list(from_date, to_date, False) self.assertEqual(sse_hol_list, benchmark_hol) ib_hol_list = ib_cal.holiday_dates_list(from_date, to_date, False) self.assertEqual(ib_hol_list, benchmark_hol) sse_hol_list = sse_cal.holiday_dates_list(from_date, to_date, True) benchmark_hol = [ Date(2014, 1, 31), Date(2014, 2, 1), Date(2014, 2, 2), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6), Date(2014, 2, 8), Date(2014, 2, 9), Date(2014, 2, 15), Date(2014, 2, 16), Date(2014, 2, 22), Date(2014, 2, 23) ] self.assertEqual(sse_hol_list, benchmark_hol) ib_hol_list = ib_cal.holiday_dates_list(from_date, to_date, True) benchmark_hol = [ Date(2014, 1, 31), Date(2014, 2, 1), Date(2014, 2, 2), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6), Date(2014, 2, 9), Date(2014, 2, 15), Date(2014, 2, 16), Date(2014, 2, 22), Date(2014, 2, 23) ] self.assertEqual(ib_hol_list, benchmark_hol) sse_working_day_list = sse_cal.biz_dates_list(from_date, to_date) d = from_date while d <= to_date: if sse_cal.is_biz_day(d): self.assertTrue(d in sse_working_day_list and d not in sse_hol_list) d += 1 ib_working_day_list = ib_cal.biz_dates_list(from_date, to_date) d = from_date while d <= to_date: if ib_cal.is_biz_day(d): self.assertTrue(d in ib_working_day_list and d not in ib_hol_list) d += 1 def test_calendar_with_date_convention(self): sse_cal = Calendar('China.SSE') reference_date = Date(2015, 2, 14) test_date = sse_cal.adjust_date( reference_date, BizDayConventions.HalfMonthModifiedFollowing) self.assertEqual(test_date, Date(2015, 2, 13)) reference_date = Date(2014, 2, 4) test_date = sse_cal.adjust_date( reference_date, BizDayConventions.ModifiedPreceding) self.assertEqual(test_date, Date(2014, 2, 7)) reference_date = Date(2014, 2, 3) test_date = sse_cal.adjust_date(reference_date, BizDayConventions.Nearest) self.assertEqual(test_date, Date(2014, 2, 7)) reference_date = Date(2014, 2, 2) test_date = sse_cal.adjust_date(reference_date, BizDayConventions.Nearest) self.assertEqual(test_date, Date(2014, 1, 30)) with self.assertRaises(ValueError): _ = sse_cal.adjust_date(reference_date, -1) def test_calendar_deep_copy(self): sse_cal = Calendar('China.SSE') copied_cal = copy.deepcopy(sse_cal) self.assertEqual(sse_cal, copied_cal) def test_calendar_pickle(self): sse_cal = Calendar('China.SSE') f = tempfile.NamedTemporaryFile('w+b', delete=False) pickle.dump(sse_cal, f) f.close() with open(f.name, 'rb') as f2: pickled_cal = pickle.load(f2) self.assertEqual(sse_cal, pickled_cal) os.unlink(f.name)
def test_consistency(self): min_date = Date.min_date().serial_number + 1 max_date = Date.max_date().serial_number dyold = Date.from_excel_serial_number(min_date - 1).day_of_year() dold = Date.from_excel_serial_number(min_date - 1).day_of_month() mold = Date.from_excel_serial_number(min_date - 1).month() yold = Date.from_excel_serial_number(min_date - 1).year() wdold = Date.from_excel_serial_number(min_date - 1).weekday() for i in range(min_date, max_date + 1): t = Date.from_excel_serial_number(i) serial = t.serial_number self.assertEqual( serial, i, "inconsistent serial number:\n" " original: {0:d}\n" " serial number: {1:d}".format(i, serial)) dy = t.day_of_year() d = t.day_of_month() m = t.month() y = t.year() wd = t.weekday() flag = (dy == dyold + 1) or \ (dy == 1 and dyold == 365 and not Date.is_leap(yold)) or \ (dy == 1 and dyold == 366 and Date.is_leap(yold)) self.assertTrue( flag, "wrong day of year increment: \n" " date: {0}\n" " day of year: {1:d}\n" " previous: {2:d}".format(t, dy, dyold)) dyold = dy flag = (d == dold + 1 and m == mold and y == yold) or \ (d == 1 and m == mold + 1 and y == yold) or \ (d == 1 and m == 1 and y == yold + 1) self.assertTrue( flag, "wrong day,month,year increment: \n" " date: {0}\n" " year,month,day: {1:d}, {2:d}, {3:d}\n" " previous: {4:d}, {5:d}, {6:d}".format( t, y, m, d, yold, mold, dold)) dold = d mold = m yold = y self.assertTrue( d >= 1, "invalid day of month: \n" " date: {0}\n" " day: {1:d}".format(t, d)) flag = (m == 1 and d <= 31) or \ (m == 2 and d <= 28) or \ (m == 2 and d == 29 and Date.is_leap(y)) or \ (m == 3 and d <= 31) or \ (m == 4 and d <= 30) or \ (m == 5 and d <= 31) or \ (m == 6 and d <= 30) or \ (m == 7 and d <= 31) or \ (m == 8 and d <= 31) or \ (m == 9 and d <= 30) or \ (m == 10 and d <= 31) or \ (m == 11 and d <= 30) or \ (m == 12 and d <= 31) self.assertTrue( flag, "invalid day of month: \n" " date: {0}\n" " day: {1:d}".format(t, d)) flag = (wd == (wdold + 1)) or (wd == 1 or wdold == 7) self.assertTrue( flag, "invalid weekday: \n" " date: {0}\n" " weekday: {1:d}\n" " previous: {2:d}".format(t, wd, wdold)) wdold = wd s = Date(y, m, d) serial = s.serial_number self.assertTrue( serial == i, "inconsistent serial number:\n" " date: {0}\n" " serial number: {1:d}\n" " cloned date: {2}\n" " serial number: {3:d}".format(t, i, s, serial))
def test_date_list(self): from_date = Date(2014, 1, 31) to_date = Date(2014, 2, 28) sse_cal = Calendar('China.SSE') ib_cal = Calendar('China.IB') benchmark_hol = [ Date(2014, 1, 31), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6) ] sse_hol_list = sse_cal.holiday_dates_list(from_date, to_date, False) self.assertEqual(sse_hol_list, benchmark_hol) ib_hol_list = ib_cal.holiday_dates_list(from_date, to_date, False) self.assertEqual(ib_hol_list, benchmark_hol) sse_hol_list = sse_cal.holiday_dates_list(from_date, to_date, True) benchmark_hol = [ Date(2014, 1, 31), Date(2014, 2, 1), Date(2014, 2, 2), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6), Date(2014, 2, 8), Date(2014, 2, 9), Date(2014, 2, 15), Date(2014, 2, 16), Date(2014, 2, 22), Date(2014, 2, 23) ] self.assertEqual(sse_hol_list, benchmark_hol) ib_hol_list = ib_cal.holiday_dates_list(from_date, to_date, True) benchmark_hol = [ Date(2014, 1, 31), Date(2014, 2, 1), Date(2014, 2, 2), Date(2014, 2, 3), Date(2014, 2, 4), Date(2014, 2, 5), Date(2014, 2, 6), Date(2014, 2, 9), Date(2014, 2, 15), Date(2014, 2, 16), Date(2014, 2, 22), Date(2014, 2, 23) ] self.assertEqual(ib_hol_list, benchmark_hol) sse_working_day_list = sse_cal.biz_dates_list(from_date, to_date) d = from_date while d <= to_date: if sse_cal.is_biz_day(d): self.assertTrue(d in sse_working_day_list and d not in sse_hol_list) d += 1 ib_working_day_list = ib_cal.biz_dates_list(from_date, to_date) d = from_date while d <= to_date: if ib_cal.is_biz_day(d): self.assertTrue(d in ib_working_day_list and d not in ib_hol_list) d += 1
def test_date_input_with_serial_number_and_notnull_year_month_day(self): serial_number = 45678 _ = Date(year=2015, serial_number=serial_number)
def test_basic_functions(self): year = 2015 month = 7 day = 24 str_repr = "{0}-{1:02d}-{2:02d}".format(year, month, day) inner_repr = "Date({0}, {1}, {2})".format(year, month, day) test_date = Date(year, month, day) self.assertEqual( str(test_date), str_repr, "date string:\n" "expected: {0:s}\n" "calculated: {1:s}".format(str_repr, str(test_date))) self.assertEqual( repr(test_date), inner_repr, "date representation:\n" "expected: {0:s}\n" "calculated: {1:s}".format(inner_repr, repr(test_date))) self.assertEqual( test_date.year(), year, "date year:\n" "expected: {0:d}\n" "calculated: {1:d}".format(year, test_date.year())) self.assertEqual( test_date.month(), month, "date month:\n" "expected: {0:d}\n" "calculated: {1:d}".format(month, test_date.month())) self.assertEqual( test_date.day_of_month(), day, "date day:\n" "expected: {0:d}\n" "calculated: {1:d}".format(day, test_date.day_of_month())) self.assertEqual( test_date.day_of_year(), test_date - Date(2015, 1, 1) + 1, "date day:\n" "expected: {0:d}\n" "calculated: {1:d}".format(test_date - Date(2015, 1, 1) + 1, test_date.day_of_year())) self.assertEqual( test_date.weekday(), 6, "date weekday:\n" "expected: {0:d}\n" "calculated: {1:d}".format(5, test_date.weekday())) self.assertEqual( test_date.to_datetime(), dt.datetime(year, month, day), "date datetime representation\n" "expected: {0}\n" "calculated: {1}".format(dt.datetime(year, month, day), test_date.to_datetime())) serial_number = test_date.serial_number serial_date = Date(serial_number=serial_number) self.assertEqual( serial_date, test_date, "date excel serial number representation\n" "expected: {0:d}" "calculated: {1:d}".format(serial_date.serial_number, test_date.serial_number)) # test comparisons previous_date = test_date - 1 self.assertTrue( previous_date < test_date, "{0} is not earlier than {1}".format(previous_date, test_date)) self.assertFalse( previous_date >= test_date, "{0} should not be later than or equal to {1}".format( previous_date, test_date)) self.assertTrue((previous_date + 1) == test_date, "{0} plus one day should be equal to {1}".format( previous_date, test_date)) # check static members self.assertEqual(Date.min_date(), Date(1901, 1, 1), "min date is wrong") self.assertEqual(Date.max_date(), Date(2199, 12, 31), "max date is wrong") self.assertEqual(Date.end_of_month(test_date), Date(year, month, 31), "end of month is wrong") self.assertTrue(Date.is_end_of_month(Date(year, month, 31)), "{0} should be the end of month") self.assertEqual( Date.next_weekday(test_date, test_date.weekday()), test_date, "{0}'s next same week day should be {1}".format( test_date, test_date)) expected_date = dt.date.today() expected_date = dt.datetime(expected_date.year, expected_date.month, expected_date.day) self.assertEqual( Date.today_date().to_datetime(), expected_date, "today's date\n" "expected: {0}\n" "calculated: {1}".format(expected_date, Date.today_date())) # nth-week day with self.assertRaises(ValueError): _ = Date.nth_weekday(0, Weekdays.Friday, 1, 2015) with self.assertRaises(ValueError): _ = Date.nth_weekday(6, Weekdays.Friday, 1, 2015) self.assertEqual(Date.nth_weekday(3, Weekdays.Wednesday, 8, 2015), Date(2015, 8, 19)) # check plus/sub three_weeks_after = test_date + '3W' expected_date = test_date + 21 self.assertEqual( three_weeks_after, expected_date, "date + 3w period\n" "expected: {0}\n" "calculated: {1}".format(expected_date, three_weeks_after)) three_months_before = test_date - "3M" expected_date = Date(year, month - 3, day) self.assertEqual( three_months_before, expected_date, "date - 3m period\n" "expected: {0}\n" "calculated: {1}".format(expected_date, three_months_before)) three_months_before = test_date - Period("3M") expected_date = Date(year, month - 3, day) self.assertEqual( three_months_before, expected_date, "date - 3m period\n" "expected: {0}\n" "calculated: {1}".format(expected_date, three_months_before)) three_months_after = test_date + "3m" expected_date = Date(year, month + 3, day) self.assertEqual( three_months_after, expected_date, "date + 3m period\n" "expected: {0}\n" "calculated: {1}".format(expected_date, three_months_after)) one_year_and_two_months_before = test_date - "14m" expected_date = Date(year - 1, month - 2, day) self.assertEqual( one_year_and_two_months_before, expected_date, "date - 14m period\n" "expected: {0}\n" "calculated: {1}".format(expected_date, three_months_before)) one_year_and_two_months_before = test_date + "14m" expected_date = Date(year + 1, month + 2, day) self.assertEqual( one_year_and_two_months_before, expected_date, "date + 14m period\n" "expected: {0}\n" "calculated: {1}".format(expected_date, three_months_before)) five_months_after = test_date + "5m" expected_date = Date(year, month + 5, day) self.assertEqual( five_months_after, expected_date, "date + 5m period\n" "expected: {0}\n" "calculated: {1}".format(expected_date, five_months_after))
def testChinaIB(self): # China Inter Bank working weekend list in the year 2014 expected_working_week_end = [ Date(2014, 1, 26), Date(2014, 2, 8), Date(2014, 5, 4), Date(2014, 9, 28), Date(2014, 10, 11), # China Inter Bank working weekend list in the year 2015 Date(2015, 1, 4), Date(2015, 2, 15), Date(2015, 2, 28), Date(2015, 9, 6), Date(2015, 10, 10), # China Inter Bank working weekend list in the year 2016 Date(2016, 2, 6), Date(2016, 2, 14), Date(2016, 6, 12), Date(2016, 9, 18), Date(2016, 10, 8), Date(2016, 10, 9), # China Inter Bank working weekend list in the year 2017 Date(2017, 1, 22), Date(2017, 2, 4), Date(2017, 4, 1), Date(2017, 5, 27), Date(2017, 9, 30), # China Inter Bank working weekend list in the year 2018 Date(2018, 2, 11), Date(2018, 2, 24), Date(2018, 4, 8), Date(2018, 4, 28), Date(2018, 9, 29), Date(2018, 9, 30) ] cal = Calendar('China.IB') for day in expected_working_week_end: self.assertEqual( cal.is_holiday(day), False, "{0} is not expected to be a holiday in {1}".format( day, cal)) self.assertEqual( cal.is_biz_day(day), True, "{0} is expected to be a working day in {1} ".format( day, cal))
def test_date_deep_copy(self): benchmark_date = Date(2016, 1, 2) copied_date = copy.deepcopy(benchmark_date) self.assertEqual(benchmark_date, copied_date)
class TimeProvider: def __init__(self): logging.debug("TimeProvider __init__") def is_market_open(self, timezone): """ Return True if the market is open, false otherwise - **timezone**: string representing the timezone """ tz = pytz.timezone(timezone) now_time = datetime.now(tz=tz).strftime("%H:%M") return BankHolidays().is_work_day(datetime.now(tz=tz)) and Utils.is_between( str(now_time), ("07:55", "16:35") ) def get_seconds_to_market_opening(self, from_time): """Return the amount of seconds from now to the next market opening, taking into account UK bank holidays and weekends""" today_opening = datetime( year=from_time.year, month=from_time.month, day=from_time.day, hour=8, minute=0, second=0, microsecond=0, ) if from_time < today_opening and BankHolidays().is_work_day(from_time.date()): nextMarketOpening = today_opening else: # Get next working day nextWorkDate = BankHolidays().get_next_work_day(date=from_time.date()) nextMarketOpening = datetime( year=nextWorkDate.year, month=nextWorkDate.month, day=nextWorkDate.day, hour=8, minute=0, second=0, microsecond=0, ) # Calculate the delta from from_time to the next market opening return (nextMarketOpening - from_time).total_seconds() def wait_for(self, time_amount_type, amount=-1): """Wait for the specified amount of time. An TimeAmount type can be specified """ if time_amount_type is TimeAmount.NEXT_MARKET_OPENING: amount = self.get_seconds_to_market_opening(datetime.now()) elif time_amount_type is TimeAmount.SECONDS: if amount < 0: raise ValueError("Invalid amount of time to wait for") logging.info("Wait for {0:.2f} hours...".format(amount / 3600)) time.sleep(amount) # ------------------------------------------------------------------------------------------------------------- # string to datetime -> calculate -> date string for d days ago # today is August 13, 10 days ago means August 3 def days_ago(d, start_date=None): if start_date==None: date = datetime.datetime.today() - datetime.timedelta(days=d) else: date = str_to_date(start_date) - datetime.timedelta(days=d) return date.strftime("%Y-%m-%d") def str_to_date(dt): year, month, day = (int(x) for x in dt.split('-')) return datetime.date(year, month, day) # transform to the valid data: # value "09/2007" to date 2007-09-01. # value "2006" to date 2016-01-01. def parse_thisdate(text: str) -> datetime.date: parts = text.split('/') if len(parts) == 2: return datetime.date(int(parts[1]), int(parts[0]), 1) elif len(parts) == 1: return datetime.date(int(parts[0]), 1, 1) else: assert False, 'Unknown date format' # creating datetime object from zip with zipfile.ZipFile(self.fname) as zf: with zf.open(zf.namelist()[0]) as infile: header = infile.readline() datestr, record_count = header.split(b':') self.month = int(datestr[2:4]) self.day = int(datestr[4:6]) self.year = int(datestr[6:10]) utc_base_time = datetime(self.year, self.month, self.day) self.base_time = timezone('US/Eastern').localize(utc_base_time).timestamp() # creating url which contains date date = pd.datetime.today() - pd.offsets.BDay(1) date=date.date() datestr = date.strftime('%Y%m%d') daystr=str(date.day) monthstr=str(date.month) yearstr=str(date.year) url='http://www.netfonds.no/quotes/exchange.php?' url=url+'exchange=%s' url=url+'&at_day=' + daystr url=url+'&at_month=' +monthstr url=url+'&at_year=' +yearstr url=url+'&format=csv' # date to string to date # date to string current_date = Date(2015, 7, 24) # create date object two_days_later = current_date + 2 # => Date(2015, 7, 26) str(two_days_later) # => 2015-07-26 current_date + '1M' # => Date(2015, 8, 24) current_date + Period('1M') # same with previous line # => Date(2015, 8, 24) current_date.strftime("%Y%m%d") # => '20150724' Date.strptime('20160115', '%Y%m%d') # => Date(2016, 1, 15) Date.strptime('2016-01-15', '%Y-%m-%d') # => Date(2016, 1, 15) Date.from_datetime(datetime.datetime(2015, 7, 24)) # => Date(2015, 7, 24) # string to date pd.to_datetime(pd.Series(["Jul 31, 2017","2010-10-01","2016/10/10","2014.06.10"])) pd.to_datetime(pd.Series(["11 Jul 2018","13.04.2015","30/12/2011"]),dayfirst=True) # providing a format could increase speed of conversion significantly pd.to_datetime(pd.Series(["12-11-2010 01:56","11-01-2012 22:10","28-02-2013 14:59"]), format='%d-%m-%Y %H:%M') import market_calendars as mcal cal_sse = mcal.get_calendar('China.SSE') # create chinese shanghai stock exchange calendar cal_sse.adjust_date('20130131') # => datetime.datetime(2013, 1, 31, 0, 0) cal_sse.adjust_date('20130131', return_string=True) # => '2013-01-31' cal_sse.adjust_date('2017/10/01') # => datetime.datetime(2017, 10, 9, 0, 0) cal_sse.adjust_date('2017/10/01', convention=2) # => datetime.datetime(2017, 9, 29, 0, 0) # reading time stamp def read_hhmmss(field: str) -> int: # """Read a HH:MM:SS field and return us since midnight."" if field != "": hour = int(field[0:2]) minute = int(field[3:5]) second = int(field[6:8]) return 1000000 * ((3600 * hour) + (60 * minute) + second) else: return 0 def read_hhmmssmil(field: str) -> int: """Read a HH:MM:SS:MILL field and return us since midnight.""" if field != "": hour = int(field[0:2]) minute = int(field[3:5]) second = int(field[6:8]) msecs = int(field[9:]) return ((1000000 * ((3600 * hour) + (60 * minute) + second)) + (1000 * msecs)) else: return 0 def read_mmddccyy(field: str) -> np.datetime64: """Read a MM-DD-CCYY field and return a np.datetime64('D') type.""" if field != "": month = int(field[0:2]) day = int(field[3:5]) year = int(field[6:10]) return np.datetime64( datetime.date(year=year, month=month, day=day), 'D') else: return np.datetime64(datetime.date(year=1, month=1, day=1), 'D') def read_ccyymmdd(field: str) -> np.datetime64: """Read a CCYYMMDD field and return a np.datetime64('D') type.""" if field != "": year = int(field[0:4]) month = int(field[4:6]) day = int(field[6:8]) return np.datetime64( datetime.date(year=year, month=month, day=day), 'D') else: return np.datetime64(datetime.date(year=1, month=1, day=1), 'D') def read_timestamp_msg(dt_tm: str) -> Tuple[np.datetime64, int]: """Read a CCYYMMDD HH:MM:SS field.""" if dt_tm != "": (date_str, time_str) = dt_tm.split(' ') dt = read_ccyymmdd(date_str) tm = read_hhmmss(time_str) return dt, tm else: return np.datetime64(datetime.date(year=1, month=1, day=1), 'D'), 0 def read_hist_news_timestamp(dt_tm: str) -> Tuple[np.datetime64, int]: """Read a news story time""" if dt_tm != "": date_str = dt_tm[0:8] time_str = dt_tm[8:14] dt = read_ccyymmdd(date_str) tm = read_hhmmss_no_colon(time_str) return dt, tm else: return np.datetime64(datetime.date(year=1, month=1, day=1), 'D'), 0 # named granularity into seconds def granularity_to_time(s): """convert a named granularity into seconds. get value in seconds for named granularities: M1, M5 ... H1 etc. >>> print(granularity_to_time("M5")) 300 """ mfact = { 'S': 1, 'M': 60, 'H': 3600, 'D': 86400, 'W': 604800, } try: f, n = re.match("(?P<f>[SMHDW])(?:(?P<n>\d+)|)", s).groups() n = n if n else 1 return mfact[f] * int(n) except Exception as e: raise ValueError(e) # ------------------------------------------------------------------------------------------------------------- # UTC convertion and timezone from pytz import timezone from pytz import utc # We're using NYSE and NASDAQ, which are both in the easters timezone. MARKET_TIMEZONE = timezone("US/Eastern") def utc_to_market_time(self, timestamp): """Converts a UTC timestamp to local market time.""" utc_time = utc.localize(timestamp) market_time = utc_time.astimezone(MARKET_TIMEZONE) return market_time def market_time_to_utc(self, timestamp): """Converts a timestamp in local market time to UTC.""" market_time = MARKET_TIMEZONE.localize(timestamp) utc_time = market_time.astimezone(utc) return utc_time def as_market_time(self, year, month, day, hour=0, minute=0, second=0): """Creates a timestamp in market time.""" market_time = datetime(year, month, day, hour, minute, second) return MARKET_TIMEZONE.localize(market_time) # Remove timezone information. def unlocalize(dateTime): return dateTime.replace(tzinfo=None) def localize(dateTime, timeZone): """Returns a datetime adjusted to a timezone: * If dateTime is a naive datetime (datetime with no timezone information), timezone information is added but date and time remains the same. * If dateTime is not a naive datetime, a datetime object with new tzinfo attribute is returned, adjusting the date and time data so the result is the same UTC time. """ if datetime_is_naive(dateTime): ret = timeZone.localize(dateTime) else: ret = dateTime.astimezone(timeZone) return ret def as_utc(dateTime): return localize(dateTime, pytz.utc) def datetime_to_timestamp(dateTime): """ Converts a datetime.datetime to a UTC timestamp.""" diff = as_utc(dateTime) - epoch_utc return diff.total_seconds() def timestamp_to_datetime(timeStamp, localized=True): """ Converts a UTC timestamp to a datetime.datetime.""" ret = datetime.datetime.utcfromtimestamp(timeStamp) if localized: ret = localize(ret, pytz.utc) return ret epoch_utc = as_utc(datetime.datetime(1970, 1, 1)) def utc_to_local(self, utc_dt): utc_dt = datetime.strptime(utc_dt, "%Y-%m-%d %H:%M:%S") local = utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None) return local.strftime("%Y-%m-%d %H:%M:%S") def utc_to_local(utc_dt): local = utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None) return local.strftime("%Y-%m-%d %H:%M:%S") utc_dt = datetime.strptime("2018-11-01 01:45:00", "%Y-%m-%d %H:%M:%S") print(utc_to_local(utc_dt)) # ------------------------------------------------------------------------------------------------------------- # Adjust dates in csv according to the time zone time_zone_difference = int(args[2]) input_filename = args[1] output_filename = 'OUT_' + input_filename with open(output_filename, 'w') as w: with open(input_filename, 'r') as r: reader = csv.reader(r, delimiter=';') for row in reader: print(row) new_row = list(row) ts = datetime.strptime(new_row[0], '%Y%m%d %H%M%S') ts += timedelta(hours=time_zone_difference) new_row[0] = ts.strftime('%Y%m%d %H%M%S') w.write(';'.join(new_row) + '\n')
def test_date_input_with_serial_number(self): serial_number = 45678 test_date = Date(serial_number=serial_number) self.assertEqual(test_date.serial_number, serial_number)