Beispiel #1
0
    def mk_message_read(the_type, *raw):
        mock_protocol = mock.MagicMock(version=110)

        msg = IncomingMessage(["2", "10"] + list(raw), mock_protocol)
        result = msg.read(the_type)
        assert msg.is_eof
        return result
Beispiel #2
0
def test_message_invoke_handler():
    result = []
    received_message = None

    def handler(arg1: int, arg2: str, arg3: typing.Dict[int, int],
                msg: IncomingMessage):
        nonlocal received_message
        result.extend([arg1, arg2, arg3])
        received_message = msg

    msg = IncomingMessage(["2", "10", '42', 'foo', '1', '13', '17'],
                          protocol_version=ProtocolVersion(110))
    msg.invoke_handler(handler)
    assert msg == received_message
    assert result == [42, 'foo', {13: 17}]
Beispiel #3
0
 def deserialize(self, message: protocol.IncomingMessage):
     self.time = message.read(int)
     self.open = message.read(float)
     self.high = message.read(float)
     self.low = message.read(float)
     self.close = message.read(float)
     self.volume = message.read(int)
     self.average = message.read(float)
     if message.message_type == protocol.Incoming.HISTORICAL_DATA:
         self.has_gaps = message.read(
             str, max_version=protocol.ProtocolVersion.SYNT_REALTIME_BARS)
     self.count = message.read(int)
Beispiel #4
0
 def deserialize(self, message: protocol.IncomingMessage):
     self.execution_id = message.read(str)
     self.commission = message.read(float)
     self.currency = message.read(str)
     self.realized_pnl = message.read(float)
     self.income = message.read(float)
     self.yield_redemption_date = message.read(float)
Beispiel #5
0
 def deserialize(self,
                 message: protocol.IncomingMessage,
                 *,
                 deserializing_historic=False):
     self.time = message.read(int)
     self.open = message.read(float)
     self.high = message.read(float)
     self.low = message.read(float)
     self.close = message.read(float)
     self.volume = message.read(int)
     self.average = message.read(float)
     if deserializing_historic:
         self.has_gaps = message.read(
             str, max_version=protocol.ProtocolVersion.SYNT_REALTIME_BARS)
     self.count = message.read(int)
Beispiel #6
0
    def _handle_tick_by_tick(self, request_id: RequestId, tick_type: int,
                             time: int, message: IncomingMessage):
        entry = self.__instruments.get(request_id)
        if not entry:
            return

        instrument = entry[1]

        if tick_type in (1, 2):
            price = message.read(float)
            size = message.read(int)
            attributes = message.read(int)
            past_limit = bool(attributes & 0x01)
            unreported = bool(attributes & 0x02)

            exchange = message.read(str)
            special_conditions = message.read(str)

            tick = LastTick(time, price, size, past_limit, unreported,
                            exchange, special_conditions)
            if tick_type == 1:
                instrument.on_tick_by_tick_last(tick)
            else:
                instrument.on_tick_by_tick_all(tick)
        elif tick_type == 3:
            bid_price = message.read(float)
            ask_price = message.read(float)
            bid_size = message.read(int)
            ask_size = message.read(int)
            attributes = message.read(int)

            bid_past_low = bool(attributes & 0x01)
            ask_past_high = bool(attributes & 0x02)

            bidask_tick = BidAskTick(time, bid_price, ask_price, bid_size,
                                     ask_size, bid_past_low, ask_past_high)
            instrument.on_tick_by_tick_bidask(bidask_tick)
        else:
            assert tick_type == 4
            mid_point = message.read(float)
            instrument.on_tick_by_tick_midpoint(MidpointTick(time, mid_point))
Beispiel #7
0
    def get_instance_from(cls, msg: protocol.IncomingMessage):
        try:
            registry = msg.source.__instruments  # type: ignore
        except AttributeError:
            registry = msg.source.__instruments = weakref.WeakValueDictionary(
            )  # type: ignore

        contract_id = msg.peek(int)
        try:
            return registry[contract_id]
        except KeyError:
            pass

        result = cls(parent=msg.source)
        result.contract_id = contract_id
        return result
    def _handle_symbol_samples(self, request_id: RequestId, num_contracts: int, message: IncomingMessage):
        result = []
        for _ in range(num_contracts):
            contract = Instrument(self)

            contract.contract_id = message.read(int)
            contract.symbol = message.read(str)
            contract.security_type = SecurityType(message.read(str))
            contract.primary_exchange = message.read(str)
            contract.currency = message.read(str)

            message.read(typing.List[str])  # derivative_security_types

            result.append(contract)

        self.resolve_future(request_id, result)
Beispiel #9
0
    def _handle_execution_data(self, request_id: RequestId, order_id: int, message: IncomingMessage):
        if message.message_version <= 10:
            raise UnsupportedFeature("execution details before version v10")

        execution = Execution(self, message.read(Instrument))
        execution.order_id = order_id
        execution.execution_id = message.read()
        execution.time = message.read(datetime.datetime)
        execution.account_number = message.read()
        execution.exchange = message.read()
        execution.side = message.read()
        execution.share = message.read(float)
        execution.price = message.read(float)
        execution.perm_id = message.read(int)
        execution.client_id = message.read(int)
        execution.liquidation = message.read(int)
        execution.cumulative_quantity = message.read(float)
        execution.average_price = message.read(float)
        execution.order_ref = message.read()
        execution.ev_rule = message.read()
        execution.ev_multiplier = message.read(float)
        execution.model_code = message.read(min_version=ProtocolVersion.MODELS_SUPPORT)
        execution.last_liquidity = message.read(int, min_version=ProtocolVersion.LAST_LIQUIDITY)

        execs = self.__pending_execs.get(request_id)
        if execs is not None:
            execs.append(execution)

        self.on_execution(execution)

        execution.instrument.on_execution(execution)
        if execution.order:
            execution.order.on_execution(execution)
Beispiel #10
0
    def _handle_open_order(
            self, order_id: int, instrument: Instrument, action: Action,
            total_quantity: float, order_type: OrderType, limit_price: float,
            aux_price: float, time_in_force: TimeInForce, oca_group: str,
            account: str, open_close: str, origin: OrderOrigin, order_ref: str,
            client_id: int, perm_id: int, outside_regular_trading_hours: bool,
            hidden: bool, discretionary_amount: float, good_after_time: str,
            _deprecated_shares_allocation: str, fa_group: str, fa_method: str,
            fa_percentage: str, fa_profile: str, message: IncomingMessage):
        order = self.__orders.get(order_id)
        if not order:
            order = self.__orders[order_id] = Order(self)
            order.order_id = order_id

        order.order_id = order_id
        order.perm_id = perm_id
        order.instrument = instrument
        order.action = action
        order.total_quantity = total_quantity
        order.order_type = order_type
        order.limit_price = limit_price
        order.aux_price = aux_price
        order.time_in_force = time_in_force
        order.oca_group = oca_group
        order.account = account
        order.open_close = open_close
        order.origin = origin
        order.order_ref = order_ref
        order.client_id = client_id
        order.outside_regular_trading_hours = outside_regular_trading_hours
        order.hidden = hidden
        order.discretionary_amount = discretionary_amount
        order.good_after_time = good_after_time
        order.fa_group = fa_group
        order.fa_method = fa_method
        order.fa_percentage = fa_percentage
        order.fa_profile = fa_profile

        order.model_code = message.read(
            min_version=ProtocolVersion.MODELS_SUPPORT)
        order.good_till_date = message.read(datetime.datetime)
        order.rule80a = message.read()
        order.percent_offset = message.read(float)
        order.settling_firm = message.read()
        order.short_sale_slot = message.read(int)
        order.designated_location = message.read()
        order.exempt_code = message.read(int)
        order.auction_strategy = message.read()
        order.starting_price = message.read(float)
        order.stock_ref_price = message.read(float)
        order.delta = message.read(float)
        order.stock_range_lower = message.read(float)
        order.stock_range_upper = message.read(float)
        order.display_size = message.read(float)

        order.block_order = message.read(bool)
        order.sweep_to_fill = message.read(bool)
        order.all_or_none = message.read(bool)
        order.min_quantity = message.read(float)
        order.oca_type = message.read(int)
        order.etrade_only = message.read(bool)
        order.firm_quote_only = message.read(bool)
        order.nbbo_price_cap = message.read(float)
        order.parent_id = message.read(int)
        order.trigger_method = message.read(int)
        order.volatility = message.read(float)
        order.volatility_type = message.read(int)
        order.delta_neutral_order_type = message.read()
        order.delta_neutral_aux_price = message.read(float)

        if order.delta_neutral_order_type:  # pragma: no cover  (I don't have actual examples of these)
            order.delta_neutral_contract_id = message.read(int)
            order.delta_neutral_settling_firm = message.read()
            order.delta_neutral_clearing_account = message.read()
            order.delta_neutral_clearing_intent = message.read()
            order.delta_neutral_open_close = message.read()
            order.delta_neutral_short_sale = message.read(bool)
            order.delta_neutral_short_sale_slot = message.read(int)
            order.delta_neutral_designated_location = message.read()

        order.continuous_update = message.read(bool)
        order.reference_price_type = message.read(int)
        order.trail_stop_price = message.read(float)
        order.trailing_percent = message.read(float)
        order.basis_points = message.read(float)
        order.basis_points_type = message.read(int)
        order.combo_legs_description = message.read(str)

        if message.read(int):  # pragma: no cover  (Not implemented)
            raise UnsupportedFeature("combo legs")

        if message.read(int):  # pragma: no cover  (Not implemented)
            raise UnsupportedFeature("order combo legs")

        order.smart_combo_routing_params = message.read(typing.Dict[str, str])
        order.scale_init_level_size = message.read(int)
        order.scale_subs_level_size = message.read(int)
        order.scale_price_increment = message.read(float)

        if order.scale_price_increment:  # pragma: no cover  (I don't have actual examples of these)
            order.scale_price_adjust_value = message.read(
                float, min_message_version=28)
            order.scale_price_adjust_interval = message.read(
                int, min_message_version=28)
            order.scale_profit_offset = message.read(float,
                                                     min_message_version=28)
            order.scale_auto_reset = message.read(bool, min_message_version=28)
            order.scale_init_position = message.read(int,
                                                     min_message_version=28)
            order.scale_init_fill_quantity = message.read(
                int, min_message_version=28)
            order.scale_random_percent = message.read(float,
                                                      min_message_version=28)

        order.hedge_type = message.read(str, min_message_version=24)
        if order.hedge_type:  # pragma: no cover  (I don't have actual examples of these)
            order.hedge_param = message.read(str)

        order.opt_out_smart_routing = message.read(bool,
                                                   min_message_version=25)

        order.clearing_account = message.read(str)
        order.clearing_intent = message.read(str)

        order.not_held = message.read(bool, min_message_version=22)

        if message.read(
                bool, min_message_version=20
        ):  # pragma: no cover  (I don't have actual examples of these)
            order.instrument.underlying_component = message.read(
                UnderlyingComponent)

        order.algo_strategy = message.read(str, min_message_version=21)
        if order.algo_strategy:  # pragma: no cover  (I don't have actual examples of these)
            order.algo_parameters = message.read(dict)

        order.solicited = message.read(bool, min_message_version=33)

        order.what_if = message.read(bool)

        order.status = message.read()
        order.inital_margin = message.read()
        order.maintenance_margin = message.read()
        order.equity_with_loan = message.read()
        order.commission = message.read(float)
        order.min_commission = message.read(float)
        order.max_commission = message.read(float)
        order.commission_currency = message.read()
        order.warning_text = message.read()

        order.randomize_size = message.read(bool, min_message_version=34)
        order.randomize_price = message.read(bool, min_message_version=34)

        if order.order_type == "PEG BENCH":  # pragma: no cover  (I don't have actual examples of these)
            order.reference_contract_id = message.read(
                int, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
            order.is_pegged_change_amount_decrease = message.read(
                bool, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
            order.pegged_change_amount = message.read(
                float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
            order.reference_change_amount = message.read(
                float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
            order.reference_exchange_id = message.read(
                min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)

        if message.read(int, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK
                        ):  # pragma: no cover  (not implemented)
            raise UnsupportedFeature("order conditions")

        order.adjusted_order_type = message.read(
            min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
        order.trigger_price = message.read(
            float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
        order.trail_stop_price = message.read(
            float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
        order.limit_price_offset = message.read(
            float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
        order.adjusted_stop_price = message.read(
            float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
        order.adjusted_stop_limit_price = message.read(
            float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
        order.adjusted_trailing_amount = message.read(
            float, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)
        order.adjustable_trailing_unit = message.read(
            int, min_version=ProtocolVersion.PEGGED_TO_BENCHMARK)

        order.soft_dollar_tier_name = message.read(
            min_version=ProtocolVersion.SOFT_DOLLAR_TIER)
        order.soft_dollar_tier_value = message.read(
            min_version=ProtocolVersion.SOFT_DOLLAR_TIER)
        order.soft_dollar_tier_display_name = message.read(
            min_version=ProtocolVersion.SOFT_DOLLAR_TIER)

        order.cash_quantity = message.read(
            float, min_version=ProtocolVersion.CASH_QTY)

        submitted_fut = self.__submitted_future.pop(order_id, None)
        if submitted_fut:
            submitted_fut.set_result(order)

        order.updated(None)
Beispiel #11
0
def test_message_versioned():
    msg = IncomingMessage(["2", 2, "test"],
                          protocol_version=ProtocolVersion(112))

    msg.reset()
    assert msg.read(str) == "test"

    msg.reset()
    assert msg.read(str, min_message_version=2) == "test"
    msg.reset()
    assert msg.read(str, min_message_version=3) is None
    msg.reset()
    assert msg.read(str, max_message_version=3) == "test"
    msg.reset()
    assert msg.read(str, max_message_version=2) is None

    msg.reset()
    assert msg.read(str, min_version=ProtocolVersion(112)) == "test"
    msg.reset()
    assert msg.read(str, min_version=ProtocolVersion(113)) is None
    msg.reset()
    assert msg.read(str, max_version=ProtocolVersion(113)) == "test"
    msg.reset()
    assert msg.read(str, max_version=ProtocolVersion(112)) is None
Beispiel #12
0
def test_message_version():
    mock_protocol = mock.MagicMock(version=110)

    msg = IncomingMessage(["2", "10"], mock_protocol)
    assert msg.message_type == Incoming.TICK_SIZE
    assert msg.message_version == 10
Beispiel #13
0
 def deserialize(self, message: IncomingMessage):
     self.vals = message.read(int), message.read(str)
Beispiel #14
0
 def mk_message_read(the_type, *raw):
     msg = IncomingMessage(["2", "10"] + list(raw),
                           protocol_version=ProtocolVersion.MIN_CLIENT)
     result = msg.read(the_type)
     assert msg.is_eof
     return result
Beispiel #15
0
    def _handle_position_data(self, account_id: str, message: IncomingMessage):
        instrument = Instrument.get_instance_from(message)

        instrument.contract_id = message.read(int)
        instrument.symbol = message.read(str)
        instrument.security_type = message.read(str)
        instrument.last_trade_date = instrument.contract_month = message.read(
            datetime.date)
        instrument.strike = message.read(float)
        instrument.right = message.read(str)
        instrument.multiplier = message.read(int)
        instrument.exchange = message.read(str)
        instrument.currency = message.read(str)
        instrument.local_symbol = message.read(str)
        if message.message_version >= 2:
            instrument.trading_class = message.read(str)

        try:
            account = self.accounts[account_id]
        except KeyError:
            account = self.accounts[account_id] = Account(account_id)

        size = account.positions[instrument] = message.read(float)
        if message.message_version >= 3:
            average_cost = account.avg_position_cost[
                instrument] = message.read(float)
        else:
            average_cost = None

        self.on_position(PositionEvent(account, instrument, size,
                                       average_cost))
Beispiel #16
0
 def deserialize(self, message: protocol.IncomingMessage):
     self.contract_id = message.read(int)
     self.delta = message.read(float)
     self.price = message.read(float)
Beispiel #17
0
    def _handle_contract_data(self, request_id: RequestId, message: IncomingMessage):
        contract = self._pending_contract_updates.get(request_id)
        if not contract:
            contract = self._pending_contract_updates[request_id] = Instrument(self)

        contract.symbol = message.read(str)
        contract.security_type = message.read(SecurityType)
        contract.last_trade_date = message.read(str)
        contract.strike = message.read(float)
        contract.right = message.read(str)
        contract.exchange = message.read(str)
        contract.currency = message.read(str)
        contract.local_symbol = message.read(str)
        contract.market_name = message.read(str)
        contract.trading_class = message.read(str)
        contract.contract_id = message.read(int)
        contract.minimum_tick = message.read(float)

        contract.market_data_size_multiplier = message.read(str, min_version=ProtocolVersion.MD_SIZE_MULTIPLIER)

        contract.multiplier = message.read(str)
        contract.order_types = message.read(str).split(',')
        contract.valid_exchanges = message.read(str).split(',')
        contract.price_magnifier = message.read(int)
        contract.underlying_contract_id = message.read(int)
        contract.long_name = message.read(str)
        contract.primary_exchange = message.read(str)
        contract.contract_month = message.read(str)
        contract.industry = message.read(str)
        contract.category = message.read(str)
        contract.subcategory = message.read(str)
        contract.time_zone = message.read(str)
        contract.trading_hours = message.read(str)
        contract.liquid_hours = message.read(str)
        contract.ev_rule = message.read(str)
        contract.ev_multiplier = message.read(str)
        contract.security_ids = message.read(typing.Dict[SecurityIdentifierType, str])

        contract.aggregated_group = message.read(str, min_version=ProtocolVersion.AGG_GROUP)

        contract.underlying_symbol = message.read(str, min_version=ProtocolVersion.UNDERLYING_INFO)
        contract.underlying_security_type = message.read(SecurityType, min_version=ProtocolVersion.UNDERLYING_INFO)

        contract.market_rule_ids = message.read(str, min_version=ProtocolVersion.MARKET_RULES)
        contract.real_expiration_date = message.read(str, min_version=ProtocolVersion.REAL_EXPIRATION_DATE)
Beispiel #18
0
 def deserialize(self, message: protocol.IncomingMessage):
     # This is the most common (but not the only) way to serialize instruments.
     self.contract_id = message.read(int)
     self.symbol = message.read(str)
     self.security_type = message.read(str)
     self.last_trade_date = self.contract_month = message.read(str)
     self.strike = message.read(float)
     self.right = message.read(str)
     self.multiplier = message.read(int)
     self.exchange = message.read(str)
     if message.message_type not in (Incoming.OPEN_ORDER,
                                     Incoming.CONTRACT_DATA,
                                     Incoming.EXECUTION_DATA):
         self.primary_exchange = message.read(str)
     self.currency = message.read(str)
     self.local_symbol = message.read(str)
     self.trading_class = message.read(str)
Beispiel #19
0
def test_message_no_version():
    msg = IncomingMessage(["77", "1"],
                          protocol_version=ProtocolVersion.MIN_CLIENT)
    assert msg.message_type == Incoming.SOFT_DOLLAR_TIERS
    assert msg.message_version == 0
Beispiel #20
0
    def _handle_contract_data(self, request_id: RequestId,
                              message: IncomingMessage):
        # fast forward to instrument id position, so that we avoid making new contracts when existing ones can be
        # reused. This is required for proper event routing elsewhere

        instrument = self._pending_instrument_updates.get(request_id)

        if not instrument:
            message.idx += 10
            instrument = Instrument.get_instance_from(message)
            self._pending_instrument_updates[request_id] = instrument
            message.idx -= 10

        instrument.symbol = message.read(str)
        instrument.security_type = message.read(SecurityType)
        instrument.last_trade_date = message.read(datetime.datetime)
        instrument.strike = message.read(float)
        instrument.right = message.read(str)
        instrument.exchange = message.read(str)
        instrument.currency = message.read(str)
        instrument.local_symbol = message.read(str)
        instrument.market_name = message.read(str)
        instrument.trading_class = message.read(str)
        instrument.contract_id = message.read(int)
        instrument.minimum_tick = message.read(float)

        instrument.market_data_size_multiplier = message.read(
            str, min_version=ProtocolVersion.MD_SIZE_MULTIPLIER)

        instrument.multiplier = message.read(str)
        instrument.order_types = message.read(str).split(',')
        instrument.valid_exchanges = message.read(str).split(',')
        instrument.price_magnifier = message.read(int)
        instrument.underlying_contract_id = message.read(int)
        instrument.long_name = message.read(str)
        instrument.primary_exchange = message.read(str)
        instrument.contract_month = message.read(str)
        instrument.industry = message.read(str)
        instrument.category = message.read(str)
        instrument.subcategory = message.read(str)
        instrument.time_zone = message.read(str)
        instrument.trading_hours = message.read(str)
        instrument.liquid_hours = message.read(str)
        instrument.ev_rule = message.read(str)
        instrument.ev_multiplier = message.read(str)
        instrument.security_ids = message.read(
            typing.Dict[SecurityIdentifierType, str])

        instrument.aggregated_group = message.read(
            str, min_version=ProtocolVersion.AGG_GROUP)

        instrument.underlying_symbol = message.read(
            str, min_version=ProtocolVersion.UNDERLYING_INFO)
        instrument.underlying_security_type = message.read(
            SecurityType, min_version=ProtocolVersion.UNDERLYING_INFO)

        instrument.market_rule_ids = message.read(
            str, min_version=ProtocolVersion.MARKET_RULES)
        instrument.real_expiration_date = message.read(
            datetime.datetime,
            min_version=ProtocolVersion.REAL_EXPIRATION_DATE)

        self.resolve_future(request_id, instrument)
Beispiel #21
0
def test_message_version():
    msg = IncomingMessage(["2", "10"],
                          protocol_version=ProtocolVersion.MIN_CLIENT)
    assert msg.message_type == Incoming.TICK_SIZE
    assert msg.message_version == 10