def test_iso8601_to_unix_nanos_given_iso8601_datetime_string(
            self, value, expected):
        # Arrange, Act
        result = dt_to_unix_nanos(value)

        # Assert
        assert result == pytest.approx(expected, 100)  # 100 nanoseconds
    def test_dt_to_unix_nanos(self, value, expected):
        # Arrange
        # Act
        result = dt_to_unix_nanos(value)

        # Assert
        assert result == expected
Beispiel #3
0
 def _on_new_order(self, trade: IBTrade):
     self._log.debug(f"new_order: {IBTrade}")
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[trade.contract.conId]
     client_order_id = self._venue_order_id_to_client_order_id[trade.order.orderId]
     strategy_id = self._client_order_id_to_strategy_id[client_order_id]
     assert trade.log
     self.generate_order_submitted(
         strategy_id=strategy_id,
         instrument_id=instrument_id,
         client_order_id=client_order_id,
         ts_event=dt_to_unix_nanos(trade.log[-1].time),
     )
Beispiel #4
0
 def _on_open_order(self, trade: IBTrade):
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[trade.contract.conId]
     client_order_id = self._venue_order_id_to_client_order_id[trade.order.orderId]
     strategy_id = self._client_order_id_to_strategy_id[client_order_id]
     venue_order_id = VenueOrderId(str(trade.orderStatus.permId))
     self.generate_order_accepted(
         strategy_id=strategy_id,
         instrument_id=instrument_id,
         client_order_id=client_order_id,
         venue_order_id=venue_order_id,
         ts_event=dt_to_unix_nanos(trade.log[-1].time),
     )
     # We can remove the local `_venue_order_id_to_client_order_id` now, we have a permId
     self._venue_order_id_to_client_order_id.pop(trade.order.orderId)
Beispiel #5
0
 def _on_top_level_snapshot(self, ticker: Ticker):
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[
         ticker.contract.conId]
     ts_event = dt_to_unix_nanos(ticker.time)
     ts_init = self._clock.timestamp_ns()
     snapshot = OrderBookSnapshot(
         book_type=BookType.L1_TBBO,
         instrument_id=instrument_id,
         bids=[(ticker.bid, ticker.bidSize)],
         asks=[(ticker.ask, ticker.askSize)],
         ts_event=ts_event,
         ts_init=ts_init,
     )
     self._handle_data(snapshot)
def parse_historic_quote_ticks(historic_ticks: List[HistoricalTickBidAsk],
                               instrument_id: InstrumentId) -> List[QuoteTick]:
    trades = []
    for tick in historic_ticks:
        ts_init = dt_to_unix_nanos(tick.time)
        quote_tick = QuoteTick(
            instrument_id=instrument_id,
            bid=Price.from_str(str(tick.priceBid)),
            bid_size=Quantity.from_str(str(tick.sizeBid)),
            ask=Price.from_str(str(tick.priceAsk)),
            ask_size=Quantity.from_str(str(tick.sizeAsk)),
            ts_init=ts_init,
            ts_event=ts_init,
        )
        trades.append(quote_tick)

    return trades
Beispiel #7
0
 def _on_order_modify(self, trade: IBTrade):
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[trade.contract.conId]
     instrument: Instrument = self._cache.instrument(instrument_id)
     client_order_id = self._venue_order_id_to_client_order_id[trade.order.orderId]
     strategy_id = self._client_order_id_to_strategy_id[client_order_id]
     venue_order_id = VenueOrderId(str(trade.orderStatus.permId))
     self.generate_order_updated(
         strategy_id=strategy_id,
         instrument_id=instrument_id,
         client_order_id=client_order_id,
         venue_order_id=venue_order_id,
         quantity=Quantity(trade.order.totalQuantity, precision=instrument.size_precision),
         price=Price(trade.order.lmtPrice, precision=instrument.price_precision),
         trigger_price=None,
         ts_event=dt_to_unix_nanos(trade.log[-1].time),
         venue_order_id_modified=False,  # TODO - does this happen?
     )
Beispiel #8
0
 def _on_quote_tick_update(self, tick: Ticker, contract: Contract):
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[
         contract.conId]
     ts_event = dt_to_unix_nanos(tick.time)
     ts_init = self._clock.timestamp_ns()
     quote_tick = QuoteTick(
         instrument_id=instrument_id,
         bid=Price.from_str(str(tick.bid)) if tick.bid else None,
         bid_size=Quantity.from_str(str(tick.bidSize))
         if tick.bidSize else None,
         ask=Price.from_str(str(tick.ask)) if tick.ask else None,
         ask_size=Quantity.from_str(str(tick.askSize))
         if tick.askSize else None,
         ts_event=ts_event,
         ts_init=ts_init,
     )
     self._handle_data(quote_tick)
Beispiel #9
0
 def _on_order_book_snapshot(self,
                             ticker: Ticker,
                             book_type: BookType = BookType.L2_MBP):
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[
         ticker.contract.conId]
     ts_event = dt_to_unix_nanos(ticker.time)
     ts_init = self._clock.timestamp_ns()
     if not (ticker.domBids or ticker.domAsks):
         return
     snapshot = OrderBookSnapshot(
         book_type=book_type,
         instrument_id=instrument_id,
         bids=[(level.price, level.size) for level in ticker.domBids],
         asks=[(level.price, level.size) for level in ticker.domAsks],
         ts_event=ts_event,
         ts_init=ts_init,
     )
     self._handle_data(snapshot)
Beispiel #10
0
 def _on_trade_ticker_update(self, ticker: Ticker):
     instrument_id = self._instrument_provider.contract_id_to_instrument_id[
         ticker.contract.conId]
     for tick in ticker.ticks:
         price = str(tick.price)
         size = str(tick.size)
         ts_event = dt_to_unix_nanos(tick.time)
         update = TradeTick(
             instrument_id=instrument_id,
             price=Price.from_str(price),
             size=Quantity.from_str(size),
             aggressor_side=AggressorSide.UNKNOWN,
             trade_id=generate_trade_id(symbol=instrument_id.value,
                                        ts_event=ts_event,
                                        price=price,
                                        size=size),
             ts_event=ts_event,
             ts_init=self._clock.timestamp_ns(),
         )
         self._handle_data(update)
def parse_historic_trade_ticks(historic_ticks: List[HistoricalTickLast],
                               instrument_id: InstrumentId) -> List[TradeTick]:
    trades = []
    for tick in historic_ticks:
        ts_init = dt_to_unix_nanos(tick.time)
        trade_tick = TradeTick(
            instrument_id=instrument_id,
            price=Price.from_str(str(tick.price)),
            size=Quantity.from_str(str(tick.size)),
            aggressor_side=AggressorSide.UNKNOWN,
            trade_id=generate_trade_id(
                symbol=instrument_id.symbol.value,
                ts_event=ts_init,
                price=tick.price,
                size=tick.size,
            ),
            ts_init=ts_init,
            ts_event=ts_init,
        )
        trades.append(trade_tick)

    return trades
Beispiel #12
0
class TestTimeBarAggregator:
    def test_instantiate_given_invalid_bar_spec_raises_value_error(self):
        # Arrange
        clock = TestClock()
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument = AUDUSD_SIM
        bar_spec = BarSpecification(100, BarAggregation.TICK, PriceType.MID)
        bar_type = BarType(instrument.id, bar_spec)

        # Act
        # Assert
        with pytest.raises(ValueError):
            TimeBarAggregator(
                instrument,
                bar_type,
                handler,
                True,
                clock,
                Logger(clock),
            )

    @pytest.mark.parametrize(
        "bar_spec, expected",
        [
            [
                BarSpecification(10, BarAggregation.SECOND, PriceType.MID),
                dt_to_unix_nanos(
                    datetime(1970, 1, 1, 0, 0, 10, tzinfo=pytz.utc)),
            ],
            [
                BarSpecification(1, BarAggregation.MINUTE, PriceType.MID),
                dt_to_unix_nanos(datetime(1970, 1, 1, 0, 1, tzinfo=pytz.utc)),
            ],
            [
                BarSpecification(1, BarAggregation.HOUR, PriceType.MID),
                dt_to_unix_nanos(datetime(1970, 1, 1, 1, 0, tzinfo=pytz.utc)),
            ],
            [
                BarSpecification(1, BarAggregation.DAY, PriceType.MID),
                dt_to_unix_nanos(datetime(1970, 1, 2, 0, 0, tzinfo=pytz.utc)),
            ],
        ],
    )
    def test_instantiate_with_various_bar_specs(self, bar_spec, expected):
        # Arrange
        clock = TestClock()
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestStubs.audusd_id()
        bar_type = BarType(instrument_id, bar_spec)

        # Act
        aggregator = TimeBarAggregator(
            AUDUSD_SIM,
            bar_type,
            handler,
            True,
            clock,
            Logger(clock),
        )

        # Assert
        assert aggregator.next_close_ns == expected

    def test_update_timed_with_test_clock_sends_single_bar_to_handler(self):
        # Arrange
        clock = TestClock()
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestStubs.audusd_id()
        bar_spec = BarSpecification(1, BarAggregation.MINUTE, PriceType.MID)
        bar_type = BarType(instrument_id, bar_spec)
        aggregator = TimeBarAggregator(
            AUDUSD_SIM,
            bar_type,
            handler,
            True,
            TestClock(),
            Logger(clock),
        )

        tick1 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00001"),
            ask=Price.from_str("1.00004"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event_ns=0,
            ts_recv_ns=0,
        )

        tick2 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00002"),
            ask=Price.from_str("1.00005"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event_ns=0,
            ts_recv_ns=0,
        )

        tick3 = QuoteTick(
            instrument_id=AUDUSD_SIM.id,
            bid=Price.from_str("1.00000"),
            ask=Price.from_str("1.00003"),
            bid_size=Quantity.from_int(1),
            ask_size=Quantity.from_int(1),
            ts_event_ns=2 * 60 * 1_000_000_000,  # 2 minutes in nanoseconds
            ts_recv_ns=2 * 60 * 1_000_000_000,  # 2 minutes in nanoseconds
        )

        # Act
        aggregator.handle_quote_tick(tick1)
        aggregator.handle_quote_tick(tick2)
        aggregator.handle_quote_tick(tick3)

        # Assert
        assert len(bar_store.get_store()) == 1
        assert Price.from_str("1.000025") == bar_store.get_store()[0].open
        assert Price.from_str("1.000035") == bar_store.get_store()[0].high
        assert Price.from_str("1.000025") == bar_store.get_store()[0].low
        assert Price.from_str("1.000035") == bar_store.get_store()[0].close
        assert Quantity.from_int(2) == bar_store.get_store()[0].volume
        assert 60_000_000_000 == bar_store.get_store()[0].ts_recv_ns