def __init__(self, connection, event_type: str, date_time: Union[str, datetime], exact_format: bool = True): """ Parameters ---------- connection: dxfeed.core.DXFeedPy.ConnectionClass Core class written in cython, that handle connection related details on the low level event_type: str One of possible event types: 'Trade', 'Quote', 'Summary', 'Profile', 'Order', 'TimeAndSale', 'Candle', 'TradeETH', 'SpreadOrder', 'Greeks', 'TheoPrice', 'Underlying', 'Series', 'Configuration' or '' date_time: str or datetime.datetime If present timed subscription will be created (conflated stream). For sting date format is following: %Y-%m-%d %H:%M:%S.%f. If None - stream subscription will be created (non-conflated). Default - None. exact_format: bool If False no warning will be thrown in case of incomplete date_time parameter. Default - True """ self.__event_type = event_type if date_time is None: self.__sub = dxp.dxf_create_subscription(cc=connection, event_type=event_type) else: date_time = cu.handle_datetime(date_time, fmt='%Y-%m-%d %H:%M:%S.%f', exact_format=exact_format) timestamp = int(date_time.timestamp() * 1000) self.__sub = dxp.dxf_create_subscription_timed( cc=connection, event_type=event_type, time=timestamp)
def _detach_listener(self): """ Removes listener so new events won't be received Returns ------- self: Subscription """ dxp.dxf_detach_listener(self.__sub) return self
def test_symbol_deletion(connection): symbols = ['AAPL', 'GOOG'] sub = dxc.dxf_create_subscription(cc=connection, event_type='Trade') dxc.dxf_add_symbols(sc=sub, symbols=symbols) dxc.dxf_remove_symbols(sc=sub, symbols=['AAPL']) actual_symbols = dxc.dxf_get_symbols(sc=sub) dxc.dxf_close_subscription(sub) assert ['GOOG'] == actual_symbols
def test_symbol_clearing(connection): symbols = ['AAPL', 'GOOG'] sub = dxc.dxf_create_subscription(cc=connection, event_type='Trade') dxc.dxf_add_symbols(sc=sub, symbols=symbols) dxc.dxf_clear_symbols(sc=sub) actual_symbols = dxc.dxf_get_symbols(sc=sub) dxc.dxf_close_subscription(sub) assert actual_symbols == []
def create_subscription(self, event_type: str, date_time: Union[str, datetime] = None): """ Method creates certain event type subscription and returns Subscription class Parameters ---------- event_type: str One of possible event types: 'Trade', 'Quote', 'Summary', 'Profile', 'Order', 'TimeAndSale', 'Candle', 'TradeETH', 'SpreadOrder', 'Greeks', 'TheoPrice', 'Underlying', 'Series', 'Configuration' or '' date_time: str or datetime.datetime If present timed subscription will be created (conflated stream). For sting date format is following: %Y-%m-%d %H:%M:%S.%f. If None - stream subscription will be created. Default - None. Note ---- Some event types (e.g. Candle) support only timed subscription. Returns ------- subscription: Subscription Subscription class related to current connection """ con_status = dxp.dxf_get_current_connection_status(self.__connection, return_str=False) if con_status == 0 or con_status == 2: raise ValueError('Connection is not established') subscription = Subscription(connection=self.__connection, event_type=event_type, date_time=date_time) return subscription
def _attach_default_listener(self): """ Method to attach default listener. If event handler was not previously set, DefaultHandler will be initialized. Returns ------- self: Subscription """ if not self.get_event_handler(): self.set_event_handler(DefaultHandler()) simplefilter(action='ignore', category=FutureWarning) dxp.dxf_attach_listener(self.__sub) simplefilter(action='default', category=FutureWarning) return self
def add_symbols(self, symbols: Union[str, Iterable[str]]): """ Method to add symbol. Supports addition of one symbol as a string as well as list of symbols. If no event handler was set, DefaultHandler will be initialized. Parameters ---------- symbols: str, Iterable Symbols to add. Previously added and remained symbols are ignored on C-API level Returns ------- self: Subscription """ self._attach_default_listener() dxp.dxf_add_symbols(sc=self.__sub, symbols=cu.to_iterable(symbols)) return self
def remove_symbols(self, symbols: Optional[Union[str, Iterable[str]]] = None): """ Method removes symbols from subscription. If no symbols provided removes all symbols Parameters ---------- symbols: str, Iterable One ticker or list of tickers to remove from subscription Returns ------- self: Subscription """ if symbols: dxp.dxf_remove_symbols(self.__sub, symbols=cu.to_iterable(symbols)) else: dxp.dxf_clear_symbols(self.__sub) return self
def test_wrong_symbol_types_ignored(connection): symbols = ['AAPL', 'GOOG'] sub = dxc.dxf_create_subscription(cc=connection, event_type='Trade') dxc.dxf_add_symbols(sc=sub, symbols=symbols + [1, 5.0, [], True, {}, ()]) actual_symbols = dxc.dxf_get_symbols(sc=sub) dxc.dxf_close_subscription(sub) assert set(symbols) == set(actual_symbols)
def connect(self, reconnect: bool = True): """ Creates connection. If connection status differs from "Not connected" and `reconnect` is False, does nothing Parameters ---------- reconnect: bool When True closes previous connection. Default - True Returns ------- self: Endpoint """ if reconnect: dxp.dxf_close_connection(self.__connection) con_status = dxp.dxf_get_current_connection_status(self.__connection, return_str=True) if con_status == 'Not connected': self.__connection = dxp.dxf_create_connection(self.address) return self
def test_double_event_handler_attachment(connection): handler1 = DefaultHandler() handler2 = DefaultHandler() sub = dxc.dxf_create_subscription(cc=connection, event_type='Trade') sub.set_event_handler(handler1) dxc.dxf_attach_listener(sub) symbols = ['AAPL', 'MSFT'] dxc.dxf_add_symbols(sub, symbols) sub.set_event_handler(handler2) assert sub.get_event_handler() is handler2 assert set(dxc.dxf_get_symbols(sub)) == set(symbols)
def __init__(self, connection_address: str = 'demo.dxfeed.com:7300', connect: bool = True): """ Parameters ---------- connection_address: str One of possible connection addresses: - the single address: `host:port` or just `host` - address with credentials: `host:port[username=xxx,password=yyy]` - multiple addresses: `(host1:port1)(host2)(host3:port3[username=xxx,password=yyy])` Default: demo.dxfeed.com:7300 connect: bool When True `connect` method is called during instance creation. Default - True """ self.__con_address = connection_address self.__connection = dxp.ConnectionClass() if connect: self.connect()
def symbols(self): return dxp.dxf_get_symbols(self.__sub)
def test_default_event_handler(connection, sub_type): sub = dxc.dxf_create_subscription(cc=connection, event_type=sub_type) sub.set_event_handler(DefaultHandler()) assert isinstance(sub.get_event_handler(), DefaultHandler)
def test_weakref(): con = dxc.ConnectionClass() sub = dxc.SubscriptionClass() con.add_weakref(sub) assert con.get_weakrefs()[0] is sub
def test_weakref_fail_on_incorrect_type(): con = dxc.ConnectionClass() obj = list() con.add_weakref(obj)
def close_subscription(self): """ Method to close subscription. All received data will remain in the object. """ dxp.dxf_close_subscription(sc=self.__sub)
def test_fail_create_subscription_with_no_connection(): dxc.dxf_create_subscription()
def connection_status(self): return dxp.dxf_get_current_connection_status(self.__connection, return_str=True)
def close_connection(self): """ Method to close connections and all related subscriptions. """ dxp.dxf_close_connection(self.__connection)
def test_connection_status(connection): exp_status = 'Connected' act_status = dxc.dxf_get_current_connection_status(connection) assert exp_status == act_status
def test_connection_address(connection): exp_address = ValueStorage.demo_address act_address = dxc.dxf_get_current_connected_address(connection) assert exp_address == act_address
def test_subscription_timed_on_correct_types(connection, sub_type): sub = dxc.dxf_create_subscription_timed(cc=connection, event_type=sub_type, time=0) act_sub_type = dxc.dxf_get_subscription_event_types(sc=sub) dxc.dxf_close_subscription(sub) assert act_sub_type == sub_type
def test_fail_to_use_subscription_without_connection(connection): sub = dxc.dxf_create_subscription(cc=connection, event_type='Trade') dxc.dxf_close_connection(connection) dxc.dxf_add_symbols(sc=sub, symbols=['AAPL'])
def connection(): # Setup con = dxc.dxf_create_connection(ValueStorage.demo_address) yield con # pass var to test and test itself # Teardown dxc.dxf_close_connection(con)
def test_subscription_fail_on_incorrect_type(connection): dxc.dxf_create_subscription_timed(cc=connection, event_type='TradeQuote', time=0)
def test_fail_connection_to_wrong_address(): dxc.dxf_create_connection(address='8.8.8.8')