def construct_all_calendars(): dispatcher = ExchangeCalendarDispatcher( calendars={}, calendar_factories=_default_calendar_factories, aliases=_default_calendar_aliases, ) calendar_names = itertools.chain(_default_calendar_aliases, _default_calendar_factories) for name in calendar_names: assert dispatcher.get_calendar(name) is not None dispatcher.deregister_calendar(name)
def test_default_calendars(self): dispatcher = ExchangeCalendarDispatcher( calendars={}, calendar_factories=_default_calendar_factories, aliases=_default_calendar_aliases, ) # These are ordered aliases first, so that we can deregister the # canonical factories when we're done with them, and we'll be done with # them after they've been used by all aliases and by canonical name. for name in concat([_default_calendar_aliases, _default_calendar_factories]): self.assertIsNotNone( dispatcher.get_calendar(name), "get_calendar(%r) returned None" % name ) dispatcher.deregister_calendar(name)
def setup_method(self, method): self.dispatcher = ExchangeCalendarDispatcher( # Make copies here so that tests that mutate the dispatcher dicts # are isolated from one another. **{k: v.copy() for k, v in self.dispatcher_kwargs.items()})
class CalendarAliasTestCase(TestCase): @classmethod def setup_class(cls): # Make a calendar once so that we don't spend time in every test # instantiating calendars. cls.dispatcher_kwargs = dict( calendars={"IEPA": IEPAExchangeCalendar()}, calendar_factories={}, aliases={ "IEPA_ALIAS": "IEPA", "IEPA_ALIAS_ALIAS": "IEPA_ALIAS", }, ) def setup_method(self, method): self.dispatcher = ExchangeCalendarDispatcher( # Make copies here so that tests that mutate the dispatcher dicts # are isolated from one another. **{k: v.copy() for k, v in self.dispatcher_kwargs.items()}) def teardown_method(self, method): self.dispatcher = None @classmethod def teardown_class(cls): cls.dispatcher_kwargs = None def test_follow_alias_chain(self): self.assertIs( self.dispatcher.get_calendar("IEPA_ALIAS"), self.dispatcher.get_calendar("IEPA"), ) self.assertIs( self.dispatcher.get_calendar("IEPA_ALIAS_ALIAS"), self.dispatcher.get_calendar("IEPA"), ) def test_add_new_aliases(self): with self.assertRaises(InvalidCalendarName): self.dispatcher.get_calendar("NOT_IEPA") self.dispatcher.register_calendar_alias("NOT_IEPA", "IEPA") self.assertIs( self.dispatcher.get_calendar("NOT_IEPA"), self.dispatcher.get_calendar("IEPA"), ) self.dispatcher.register_calendar_alias("IEPA_ALIAS_ALIAS_ALIAS", "IEPA_ALIAS_ALIAS") self.assertIs( self.dispatcher.get_calendar("IEPA_ALIAS_ALIAS_ALIAS"), self.dispatcher.get_calendar("IEPA"), ) def test_remove_aliases(self): self.dispatcher.deregister_calendar("IEPA_ALIAS_ALIAS") with self.assertRaises(InvalidCalendarName): self.dispatcher.get_calendar("IEPA_ALIAS_ALIAS") def test_reject_alias_that_already_exists(self): with self.assertRaises(CalendarNameCollision): self.dispatcher.register_calendar_alias("IEPA", "NOT_IEPA") with self.assertRaises(CalendarNameCollision): self.dispatcher.register_calendar_alias("IEPA_ALIAS", "NOT_IEPA") def test_allow_alias_override_with_force(self): self.dispatcher.register_calendar_alias("IEPA", "NOT_IEPA", force=True) with self.assertRaises(InvalidCalendarName): self.dispatcher.get_calendar("IEPA") def test_reject_cyclic_aliases(self): add_alias = self.dispatcher.register_calendar_alias add_alias("A", "B") add_alias("B", "C") with self.assertRaises(CyclicCalendarAlias) as e: add_alias("C", "A") expected = "Cycle in calendar aliases: ['C' -> 'A' -> 'B' -> 'C']" self.assertEqual(str(e.exception), expected) def test_get_calendar_names(self): self.assertEqual( sorted(self.dispatcher.get_calendar_names()), ["IEPA", "IEPA_ALIAS", "IEPA_ALIAS_ALIAS"], )
tz=UTC)) # kwargs["start"] = pd.Timestamp("1990-01-01", tz="UTC") if name not in ["us_futures", "24/7", "24/5", "CMES"]: # Zipline had default open time of t+1min factory.open_times = [(d, t.replace(minute=t.minute + 1)) for d, t in factory.open_times] calendar = factory(**kwargs) self._factory_output_cache[name] = (calendar, kwargs) return calendar # Yay! Monkey patching ExchangeCalendarDispatcher._fabricate = _fabricate global_calendar_dispatcher = ExchangeCalendarDispatcher( calendars={}, calendar_factories=_default_calendar_factories, aliases=_default_calendar_aliases, ) get_calendar = global_calendar_dispatcher.get_calendar get_calendar_names = global_calendar_dispatcher.get_calendar_names clear_calendars = global_calendar_dispatcher.clear_calendars deregister_calendar = global_calendar_dispatcher.deregister_calendar register_calendar = global_calendar_dispatcher.register_calendar register_calendar_type = global_calendar_dispatcher.register_calendar_type register_calendar_alias = global_calendar_dispatcher.register_calendar_alias resolve_alias = global_calendar_dispatcher.resolve_alias aliases_to_names = global_calendar_dispatcher.aliases_to_names names_to_aliases = global_calendar_dispatcher.names_to_aliases except ImportError:
def setup_method(self, method): self.dummy_cal_type = FakeCalendar self.dispatcher = ExchangeCalendarDispatcher({}, {}, {})
class CalendarRegistrationTestCase(TestCase): def setup_method(self, method): self.dummy_cal_type = FakeCalendar self.dispatcher = ExchangeCalendarDispatcher({}, {}, {}) def teardown_method(self, method): self.dispatcher.clear_calendars() def test_register_calendar(self): # Build a fake calendar dummy_cal = self.dummy_cal_type() # Try to register and retrieve the calendar self.dispatcher.register_calendar("DMY", dummy_cal) retr_cal = self.dispatcher.get_calendar("DMY") self.assertEqual(dummy_cal, retr_cal) # Try to register again, expecting a name collision with self.assertRaises(CalendarNameCollision): self.dispatcher.register_calendar("DMY", dummy_cal) # Deregister the calendar and ensure that it is removed self.dispatcher.deregister_calendar("DMY") with self.assertRaises(InvalidCalendarName): self.dispatcher.get_calendar("DMY") def test_register_calendar_type(self): self.dispatcher.register_calendar_type("DMY", self.dummy_cal_type) retr_cal = self.dispatcher.get_calendar("DMY") self.assertEqual(self.dummy_cal_type, type(retr_cal)) def test_both_places_are_checked(self): dummy_cal = self.dummy_cal_type() # if instance is registered, can't register type with same name self.dispatcher.register_calendar("DMY", dummy_cal) with self.assertRaises(CalendarNameCollision): self.dispatcher.register_calendar_type("DMY", type(dummy_cal)) self.dispatcher.deregister_calendar("DMY") # if type is registered, can't register instance with same name self.dispatcher.register_calendar_type("DMY", type(dummy_cal)) with self.assertRaises(CalendarNameCollision): self.dispatcher.register_calendar("DMY", dummy_cal) def test_force_registration(self): self.dispatcher.register_calendar("DMY", self.dummy_cal_type()) first_dummy = self.dispatcher.get_calendar("DMY") # force-register a new instance self.dispatcher.register_calendar("DMY", self.dummy_cal_type(), force=True) second_dummy = self.dispatcher.get_calendar("DMY") self.assertNotEqual(first_dummy, second_dummy)
class CalendarDispatcherTestCase(TestCase): @classmethod def setup_class(cls): cls.dispatcher_kwargs = dict( calendars={}, calendar_factories={"IEPA": IEPAExchangeCalendar}, aliases={ "IEPA_ALIAS": "IEPA", "IEPA_ALIAS_ALIAS": "IEPA_ALIAS", }, ) def setup_method(self, method): self.dispatcher = ExchangeCalendarDispatcher( # Make copies here so that tests that mutate the dispatcher dicts # are isolated from one another. **{k: v.copy() for k, v in self.dispatcher_kwargs.items()}) def teardown_method(self, method): self.dispatcher = None @classmethod def teardown_class(cls): cls.dispatcher_kwargs = None def test_follow_alias_chain(self): self.assertIs( self.dispatcher.get_calendar("IEPA_ALIAS"), self.dispatcher.get_calendar("IEPA"), ) self.assertIs( self.dispatcher.get_calendar("IEPA_ALIAS_ALIAS"), self.dispatcher.get_calendar("IEPA"), ) def test_add_new_aliases(self): with self.assertRaises(InvalidCalendarName): self.dispatcher.get_calendar("NOT_IEPA") self.dispatcher.register_calendar_alias("NOT_IEPA", "IEPA") self.assertIs( self.dispatcher.get_calendar("NOT_IEPA"), self.dispatcher.get_calendar("IEPA"), ) self.dispatcher.register_calendar_alias("IEPA_ALIAS_ALIAS_ALIAS", "IEPA_ALIAS_ALIAS") self.assertIs( self.dispatcher.get_calendar("IEPA_ALIAS_ALIAS_ALIAS"), self.dispatcher.get_calendar("IEPA"), ) def test_remove_aliases(self): self.dispatcher.deregister_calendar("IEPA_ALIAS_ALIAS") with self.assertRaises(InvalidCalendarName): self.dispatcher.get_calendar("IEPA_ALIAS_ALIAS") def test_reject_alias_that_already_exists(self): with self.assertRaises(CalendarNameCollision): self.dispatcher.register_calendar_alias("IEPA", "NOT_IEPA") with self.assertRaises(CalendarNameCollision): self.dispatcher.register_calendar_alias("IEPA_ALIAS", "NOT_IEPA") def test_allow_alias_override_with_force(self): self.dispatcher.register_calendar_alias("IEPA", "NOT_IEPA", force=True) with self.assertRaises(InvalidCalendarName): self.dispatcher.get_calendar("IEPA") def test_reject_cyclic_aliases(self): add_alias = self.dispatcher.register_calendar_alias add_alias("A", "B") add_alias("B", "C") with self.assertRaises(CyclicCalendarAlias) as e: add_alias("C", "A") expected = "Cycle in calendar aliases: ['C' -> 'A' -> 'B' -> 'C']" self.assertEqual(str(e.exception), expected) def test_get_calendar_names(self): self.assertEqual( sorted(self.dispatcher.get_calendar_names()), ["IEPA", "IEPA_ALIAS", "IEPA_ALIAS_ALIAS"], ) self.assertEqual( self.dispatcher.get_calendar_names(include_aliases=False), ["IEPA"], ) def test_aliases_to_names(self): self.assertDictEqual( self.dispatcher.aliases_to_names(), { "IEPA_ALIAS": "IEPA", "IEPA_ALIAS_ALIAS": "IEPA", }, ) def test_names_to_aliases(self): self.assertDictEqual( self.dispatcher.names_to_aliases(), {"IEPA": ["IEPA_ALIAS", "IEPA_ALIAS_ALIAS"]}, ) def test_get_calendar(self): cal = self.dispatcher.get_calendar("IEPA") self.assertIsInstance(cal, ExchangeCalendar) def test_get_calendar_kwargs(self): start = pd.Timestamp("2020-01-02", tz="UTC") end = pd.Timestamp("2020-01-31", tz="UTC") cal = self.dispatcher.get_calendar("IEPA", start=start, end=end) self.assertEqual(cal.first_session, start) self.assertEqual(cal.last_session, end) self.dispatcher.register_calendar("iepa_instance", cal) error_msg = ( f"Receieved constructor arguments `start` and/or `end`" f" although calendar iepa_instance is registered as a specific" f" instance of class {cal.__class__}, not as a calendar factory.") with pytest.raises(ValueError, match=re.escape(error_msg)): # Can only pass kwargs to registered factories (not calendar instances) self.dispatcher.get_calendar("iepa_instance", start=start) def test_get_calendar_cache(self): start = pd.Timestamp("2020-01-02", tz="UTC") end = pd.Timestamp("2020-01-31", tz="UTC") cal = self.dispatcher.get_calendar("IEPA", start=start, end=end) cal2 = self.dispatcher.get_calendar("IEPA", start=start, end=end) self.assertIs(cal, cal2) start += pd.DateOffset(days=1) cal3 = self.dispatcher.get_calendar("IEPA", start=start, end=end) self.assertIsNot(cal, cal3)