コード例 #1
0
    def test_to_dict_returns_expected_dict(self):
        # Arrange
        order = Order(price=10, size=5, side=OrderSide.BUY, id="1")
        delta = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order,
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = OrderBookDelta.to_dict(delta)

        # Assert
        assert result == {
            "type": "OrderBookDelta",
            "instrument_id": "AUD/USD.SIM",
            "book_type": "L2_MBP",
            "action": "ADD",
            "order_id": "1",
            "order_price": 10.0,
            "order_side": "BUY",
            "order_size": 5.0,
            "update_id": 0,
            "ts_event": 0,
            "ts_init": 0,
        }
コード例 #2
0
    def test_from_dict_returns_expected_tick(self):
        # Arrange
        order1 = Order(price=10, size=5, side=OrderSide.BUY, id="1")
        delta1 = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order1,
            ts_event=0,
            ts_init=0,
        )

        order2 = Order(price=10, size=15, side=OrderSide.BUY, id="2")
        delta2 = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order2,
            ts_event=0,
            ts_init=0,
        )

        deltas = OrderBookDeltas(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            deltas=[delta1, delta2],
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = OrderBookDeltas.from_dict(OrderBookDeltas.to_dict(deltas))

        # Assert
        assert result == deltas
コード例 #3
0
def test_apply(empty_l2_book, clock):
    snapshot = OrderBookSnapshot(
        instrument_id=empty_l2_book.instrument_id,
        book_type=BookType.L2_MBP,
        bids=[[150.0, 0.51]],
        asks=[[160.0, 1.51]],
        ts_event=0,
        ts_init=0,
    )
    empty_l2_book.apply_snapshot(snapshot)
    assert empty_l2_book.best_ask_price() == 160
    delta = OrderBookDelta(
        instrument_id=TestStubs.audusd_id(),
        book_type=BookType.L2_MBP,
        action=BookAction.ADD,
        order=Order(
            155.0,
            672.45,
            OrderSide.SELL,
            "4a25c3f6-76e7-7584-c5a3-4ec84808e240",
        ),
        ts_event=clock.timestamp(),
        ts_init=clock.timestamp(),
    )
    empty_l2_book.apply(delta)
    assert empty_l2_book.best_ask_price() == 155
コード例 #4
0
def parse_book_delta_ws(
    instrument_id: InstrumentId,
    side: OrderSide,
    delta: Tuple[str, str],
    ts_event: int,
    ts_init: int,
    update_id: int,
) -> OrderBookDelta:
    price = float(delta[0])
    size = float(delta[1])

    order = Order(
        price=price,
        size=size,
        side=side,
    )

    return OrderBookDelta(
        instrument_id=instrument_id,
        book_type=BookType.L2_MBP,
        action=BookAction.UPDATE if size > 0.0 else BookAction.DELETE,
        order=order,
        ts_event=ts_event,
        ts_init=ts_init,
        update_id=update_id,
    )
コード例 #5
0
    def test_from_dict_returns_expected_clear(self):
        # Arrange
        delta = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.CLEAR,
            order=None,
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = OrderBookDelta.from_dict(OrderBookDelta.to_dict(delta))

        # Assert
        assert result == delta
コード例 #6
0
    def test_from_dict_returns_expected_delta(self):
        # Arrange
        order = Order(price=10, size=5, side=OrderSide.BUY)
        delta = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order,
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = OrderBookDelta.from_dict(OrderBookDelta.to_dict(delta))

        # Assert
        assert result == delta
コード例 #7
0
def _build_order_book_deltas(values):
    return OrderBookDeltas(
        instrument_id=InstrumentId.from_str(values[0]["instrument_id"]),
        book_type=BookTypeParser.from_str_py(values[0]["book_type"]),
        deltas=[OrderBookDelta.from_dict(v) for v in values],
        ts_event=values[0]["ts_event"],
        ts_init=values[0]["ts_init"],
    )
コード例 #8
0
 def order_book_delta(order=None):
     return OrderBookDelta(
         instrument_id=TestIdStubs.audusd_id(),
         book_type=BookType.L2_MBP,
         action=BookAction.ADD,
         order=order or TestDataStubs.order(),
         ts_event=0,
         ts_init=0,
     )
コード例 #9
0
    def test_to_dict_returns_expected_dict(self):
        # Arrange
        order1 = Order(price=10, size=5, side=OrderSide.BUY, id="1")
        delta1 = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order1,
            ts_event=0,
            ts_init=0,
        )

        order2 = Order(price=10, size=15, side=OrderSide.BUY, id="2")
        delta2 = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order2,
            ts_event=0,
            ts_init=0,
        )

        deltas = OrderBookDeltas(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            deltas=[delta1, delta2],
            ts_event=0,
            ts_init=0,
        )

        # Act
        result = OrderBookDeltas.to_dict(deltas)

        # Assert
        assert result == {
            "type": "OrderBookDeltas",
            "instrument_id": "AUD/USD.SIM",
            "book_type": "L2_MBP",
            "deltas":
            b'[{"type":"OrderBookDelta","instrument_id":"AUD/USD.SIM","book_type":"L2_MBP","action":"ADD","order_price":10.0,"order_size":5.0,"order_side":"BUY","order_id":"1","update_id":0,"ts_event":0,"ts_init":0},{"type":"OrderBookDelta","instrument_id":"AUD/USD.SIM","book_type":"L2_MBP","action":"ADD","order_price":10.0,"order_size":15.0,"order_side":"BUY","order_id":"2","update_id":0,"ts_event":0,"ts_init":0}]',  # noqa
            "update_id": 0,
            "ts_event": 0,
            "ts_init": 0,
        }
コード例 #10
0
def serialize(data: OrderBookData):
    if isinstance(data, OrderBookDelta):
        result = [_parse_delta(delta=data, cls=OrderBookDelta)]
    elif isinstance(data, OrderBookDeltas):
        result = [_parse_delta(delta=delta, cls=OrderBookDeltas) for delta in data.deltas]
    elif isinstance(data, OrderBookSnapshot):
        # For a snapshot, we store the individual deltas required to rebuild, namely a CLEAR, followed by ADDs
        result = [
            _parse_delta(
                OrderBookDelta(
                    instrument_id=data.instrument_id,
                    book_type=data.book_type,
                    order=None,
                    action=BookAction.CLEAR,
                    ts_event=data.ts_event,
                    ts_init=data.ts_init,
                ),
                cls=OrderBookSnapshot,
            )
        ]
        orders = list(zip(repeat(OrderSide.BUY), data.bids)) + list(
            zip(repeat(OrderSide.SELL), data.asks)
        )
        result.extend(
            [
                _parse_delta(
                    OrderBookDelta(
                        instrument_id=data.instrument_id,
                        book_type=data.book_type,
                        ts_event=data.ts_event,
                        ts_init=data.ts_init,
                        order=Order(price=price, size=volume, side=side),
                        action=BookAction.ADD,
                    ),
                    cls=OrderBookSnapshot,
                )
                for side, (price, volume) in orders
            ]
        )
    else:  # pragma: no cover (design-time error)
        raise TypeError(f"invalid OrderBookData type, was {type(data)}")
    # Add a "last" message to let downstream consumers know the end of this group of messages
    result[-1]["_last"] = True
    return result
コード例 #11
0
    def test_hash_str_and_repr(self):
        # Arrange
        order1 = Order(price=10, size=5, side=OrderSide.BUY, id="1")
        delta1 = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order1,
            ts_event=0,
            ts_init=0,
        )

        order2 = Order(price=10, size=15, side=OrderSide.BUY, id="2")
        delta2 = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order2,
            ts_event=0,
            ts_init=0,
        )

        deltas = OrderBookDeltas(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            deltas=[delta1, delta2],
            ts_event=0,
            ts_init=0,
        )

        # Act, Assert
        assert isinstance(hash(deltas), int)
        assert (
            str(deltas) ==
            "OrderBookDeltas('AUD/USD.SIM', book_type=L2_MBP, [OrderBookDelta('AUD/USD.SIM', book_type=L2_MBP, action=ADD, order=Order(10.0, 5.0, BUY, 1), update_id=0, ts_event=0, ts_init=0), OrderBookDelta('AUD/USD.SIM', book_type=L2_MBP, action=ADD, order=Order(10.0, 15.0, BUY, 2), update_id=0, ts_event=0, ts_init=0)], update_id=0, ts_event=0, ts_init=0)"  # noqa
        )
        assert (
            repr(deltas) ==
            "OrderBookDeltas('AUD/USD.SIM', book_type=L2_MBP, [OrderBookDelta('AUD/USD.SIM', book_type=L2_MBP, action=ADD, order=Order(10.0, 5.0, BUY, 1), update_id=0, ts_event=0, ts_init=0), OrderBookDelta('AUD/USD.SIM', book_type=L2_MBP, action=ADD, order=Order(10.0, 15.0, BUY, 2), update_id=0, ts_event=0, ts_init=0)], update_id=0, ts_event=0, ts_init=0)"  # noqa
        )
コード例 #12
0
    def test_serialize_and_deserialize_order_book_deltas(self):
        kw = {
            "instrument_id": "AUD/USD.SIM",
            "ts_event": 0,
            "ts_init": 0,
            "book_type": "L2_MBP",
        }
        deltas = OrderBookDeltas(
            instrument_id=TestStubs.audusd_id(),
            book_type=BookType.L2_MBP,
            deltas=[
                OrderBookDelta.from_dict({
                    "action": "ADD",
                    "order_side": "BUY",
                    "order_price": 8.0,
                    "order_size": 30.0,
                    "order_id": "e0364f94-8fcb-0262-cbb3-075c51ee4917",
                    **kw,
                }),
                OrderBookDelta.from_dict({
                    "action": "ADD",
                    "order_side": "SELL",
                    "order_price": 15.0,
                    "order_size": 10.0,
                    "order_id": "cabec174-acc6-9204-9ebf-809da3896daf",
                    **kw,
                }),
            ],
            ts_event=0,
            ts_init=0,
        )

        serialized = ParquetSerializer.serialize(deltas)
        deserialized = ParquetSerializer.deserialize(cls=OrderBookDeltas,
                                                     chunk=serialized)

        # Assert
        assert deserialized == [deltas]
        write_objects(catalog=self.catalog, chunk=[deltas])
コード例 #13
0
def test_timestamp_ns(empty_l2_book, clock):
    delta = OrderBookDelta(
        instrument_id=TestStubs.audusd_id(),
        book_type=BookType.L2_MBP,
        action=BookAction.ADD,
        order=Order(
            0.5900,
            672.45,
            OrderSide.SELL,
            "4a25c3f6-76e7-7584-c5a3-4ec84808e240",
        ),
        ts_event=clock.timestamp(),
        ts_init=clock.timestamp(),
    )
    empty_l2_book.apply_delta(delta)
    assert empty_l2_book.ts_last == delta.ts_init
コード例 #14
0
def test_orderbook_operation_update(empty_l2_book, clock):
    delta = OrderBookDelta(
        instrument_id=TestStubs.audusd_id(),
        book_type=BookType.L2_MBP,
        action=BookAction.UPDATE,
        order=Order(
            0.5814,
            672.45,
            OrderSide.SELL,
            "4a25c3f6-76e7-7584-c5a3-4ec84808e240",
        ),
        ts_event=clock.timestamp(),
        ts_init=clock.timestamp(),
    )
    empty_l2_book.apply_delta(delta)
    assert empty_l2_book.best_ask_price() == 0.5814
コード例 #15
0
def test_orderbook_operations(empty_l2_book):
    delta = OrderBookDelta(
        instrument_id=TestStubs.audusd_id(),
        book_type=BookType.L2_MBP,
        action=BookAction.UPDATE,
        order=Order(
            0.5814,
            672.45,
            OrderSide.SELL,
            "4a25c3f6-76e7-7584-c5a3-4ec84808e240",
        ),
        ts_event=pd.Timestamp.utcnow().timestamp() * 1e9,
        ts_init=pd.Timestamp.utcnow().timestamp() * 1e9,
    )
    deltas = OrderBookDeltas(
        instrument_id=TestStubs.audusd_id(),
        book_type=BookType.L2_MBP,
        deltas=[delta],
        ts_event=pd.Timestamp.utcnow().timestamp() * 1e9,
        ts_init=pd.Timestamp.utcnow().timestamp() * 1e9,
    )
    empty_l2_book.apply_deltas(deltas)
    assert empty_l2_book.best_ask_price() == 0.5814
コード例 #16
0
    def test_hash_str_and_repr(self):
        # Arrange
        order = Order(price=10, size=5, side=OrderSide.BUY)
        delta = OrderBookDelta(
            instrument_id=AUDUSD,
            book_type=BookType.L2_MBP,
            action=BookAction.ADD,
            order=order,
            update_id=123456789,
            ts_event=0,
            ts_init=1_000_000_000,
        )

        # Act, Assert
        assert isinstance(hash(delta), int)
        assert (
            str(delta) ==
            f"OrderBookDelta('AUD/USD.SIM', book_type=L2_MBP, action=ADD, order=Order(10.0, 5.0, BUY, {order.id}), update_id=123456789, ts_event=0, ts_init=1000000000)"  # noqa
        )
        assert (
            repr(delta) ==
            f"OrderBookDelta('AUD/USD.SIM', book_type=L2_MBP, action=ADD, order=Order(10.0, 5.0, BUY, {order.id}), update_id=123456789, ts_event=0, ts_init=1000000000)"  # noqa
        )
コード例 #17
0
def _handle_book_updates(runner, instrument, ts_event, ts_init):
    deltas = []
    for side in B_SIDE_KINDS:
        for upd in runner.get(side, []):
            # TODO(bm): Clean this up
            if len(upd) == 3:
                _, price, volume = upd
            else:
                price, volume = upd
            if price == 0.0:
                continue
            deltas.append(
                OrderBookDelta(
                    instrument_id=instrument.id,
                    book_type=BookType.L2_MBP,
                    action=BookAction.DELETE
                    if volume == 0 else BookAction.UPDATE,
                    order=Order(
                        price=price_to_probability(str(price)),
                        size=Quantity(volume, precision=8),
                        side=B2N_MARKET_STREAM_SIDE[side],
                    ),
                    ts_event=ts_event,
                    ts_init=ts_init,
                ))
    if deltas:
        ob_update = OrderBookDeltas(
            book_type=BookType.L2_MBP,
            instrument_id=instrument.id,
            deltas=deltas,
            ts_event=ts_event,
            ts_init=ts_init,
        )
        return [ob_update]
    else:
        return []
コード例 #18
0
    def test_serialize_and_deserialize_order_book_delta(self):
        delta = OrderBookDelta(
            instrument_id=TestStubs.audusd_id(),
            book_type=BookType.L2_MBP,
            action=BookAction.CLEAR,
            order=None,
            ts_event=0,
            ts_init=0,
        )

        serialized = ParquetSerializer.serialize(delta)
        [deserialized] = ParquetSerializer.deserialize(cls=OrderBookDelta,
                                                       chunk=serialized)

        # Assert
        expected = OrderBookDeltas(
            instrument_id=TestStubs.audusd_id(),
            book_type=BookType.L2_MBP,
            deltas=[delta],
            ts_event=0,
            ts_init=0,
        )
        assert deserialized == expected
        write_objects(catalog=self.catalog, chunk=[delta])
コード例 #19
0
    def test_add_order_book_deltas_adds_to_engine(self, capsys):
        # Arrange
        engine = BacktestEngine()
        engine.add_instrument(AUDUSD_SIM)
        engine.add_instrument(ETHUSDT_BINANCE)

        deltas = [
            OrderBookDelta(
                instrument_id=AUDUSD_SIM.id,
                book_type=BookType.L2_MBP,
                action=BookAction.ADD,
                order=Order(
                    price=Price.from_str("13.0"),
                    size=Quantity.from_str("40"),
                    side=OrderSide.SELL,
                ),
                ts_event=0,
                ts_init=0,
            ),
            OrderBookDelta(
                instrument_id=AUDUSD_SIM.id,
                book_type=BookType.L2_MBP,
                action=BookAction.ADD,
                order=Order(
                    price=Price.from_str("12.0"),
                    size=Quantity.from_str("30"),
                    side=OrderSide.SELL,
                ),
                ts_event=0,
                ts_init=0,
            ),
            OrderBookDelta(
                instrument_id=AUDUSD_SIM.id,
                book_type=BookType.L2_MBP,
                action=BookAction.ADD,
                order=Order(
                    price=Price.from_str("11.0"),
                    size=Quantity.from_str("20"),
                    side=OrderSide.SELL,
                ),
                ts_event=0,
                ts_init=0,
            ),
            OrderBookDelta(
                instrument_id=AUDUSD_SIM.id,
                book_type=BookType.L2_MBP,
                action=BookAction.ADD,
                order=Order(
                    price=Price.from_str("10.0"),
                    size=Quantity.from_str("20"),
                    side=OrderSide.BUY,
                ),
                ts_event=0,
                ts_init=0,
            ),
            OrderBookDelta(
                instrument_id=AUDUSD_SIM.id,
                book_type=BookType.L2_MBP,
                action=BookAction.ADD,
                order=Order(
                    price=Price.from_str("9.0"),
                    size=Quantity.from_str("30"),
                    side=OrderSide.BUY,
                ),
                ts_event=0,
                ts_init=0,
            ),
            OrderBookDelta(
                instrument_id=AUDUSD_SIM.id,
                book_type=BookType.L2_MBP,
                action=BookAction.ADD,
                order=Order(
                    price=Price.from_str("0.0"),
                    size=Quantity.from_str("40"),
                    side=OrderSide.BUY,
                ),
                ts_event=0,
                ts_init=0,
            ),
        ]

        operations1 = OrderBookDeltas(
            instrument_id=ETHUSDT_BINANCE.id,
            book_type=BookType.L2_MBP,
            deltas=deltas,
            ts_event=0,
            ts_init=0,
        )

        operations2 = OrderBookDeltas(
            instrument_id=ETHUSDT_BINANCE.id,
            book_type=BookType.L2_MBP,
            deltas=deltas,
            ts_event=1000,
            ts_init=1000,
        )

        # Act
        engine.add_order_book_data([operations2,
                                    operations1])  # <-- not sorted

        # Assert
        log = "".join(capsys.readouterr())
        assert "Added 2 ETHUSDT.BINANCE OrderBookData elements." in log
コード例 #20
0
    def test_serialize_and_deserialize_order_book_deltas_grouped(self):
        kw = {
            "instrument_id": "AUD/USD.SIM",
            "ts_event": 0,
            "ts_init": 0,
            "book_type": "L2_MBP",
        }
        deltas = [
            {
                "action": "ADD",
                "order_side": "SELL",
                "order_price": 0.9901,
                "order_size": 327.25,
                "order_id": "1",
            },
            {
                "action": "CLEAR",
                "order_side": None,
                "order_price": None,
                "order_size": None,
                "order_id": None,
            },
            {
                "action": "ADD",
                "order_side": "SELL",
                "order_price": 0.98039,
                "order_size": 27.91,
                "order_id": "2",
            },
            {
                "action": "ADD",
                "order_side": "SELL",
                "order_price": 0.97087,
                "order_size": 14.43,
                "order_id": "3",
            },
        ]
        deltas = OrderBookDeltas(
            instrument_id=TestStubs.audusd_id(),
            book_type=BookType.L2_MBP,
            deltas=[OrderBookDelta.from_dict({
                **kw,
                **d
            }) for d in deltas],
            ts_event=0,
            ts_init=0,
        )

        serialized = ParquetSerializer.serialize(deltas)
        [deserialized] = ParquetSerializer.deserialize(cls=OrderBookDeltas,
                                                       chunk=serialized)

        # Assert
        assert deserialized == deltas
        write_objects(catalog=self.catalog, chunk=[deserialized])
        assert [d.action for d in deserialized.deltas] == [
            BookAction.ADD,
            BookAction.CLEAR,
            BookAction.ADD,
            BookAction.ADD,
        ]
コード例 #21
0
def _parse_delta(delta: OrderBookDelta, cls):
    return dict(**OrderBookDelta.to_dict(delta), _type=cls.__name__)
コード例 #22
0
 def to_dict(obj) -> Dict:
     values = OrderBookDelta.to_dict(obj)
     values["type"] = obj.__class__.__name__
     return values
コード例 #23
0
 def test_fully_qualified_name(self):
     # Arrange, Act, Assert
     assert (OrderBookDelta.fully_qualified_name() ==
             "nautilus_trader.model.orderbook.data.OrderBookDelta")