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, level=BookLevel.L2, delta_type=DeltaType.ADD, order=order1, ts_event_ns=0, ts_recv_ns=0, ) order2 = Order(price=10, size=15, side=OrderSide.BUY, id="2") delta2 = OrderBookDelta( instrument_id=AUDUSD, level=BookLevel.L2, delta_type=DeltaType.ADD, order=order2, ts_event_ns=0, ts_recv_ns=0, ) deltas = OrderBookDeltas( instrument_id=AUDUSD, level=BookLevel.L2, deltas=[delta1, delta2], ts_event_ns=0, ts_recv_ns=0, ) # Act result = OrderBookDeltas.from_dict(OrderBookDeltas.to_dict(deltas)) # Assert assert result == deltas
def _handle_book_updates(runner, instrument, ts_event_ns, ts_recv_ns): 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 deltas.append( OrderBookDelta( instrument_id=instrument.id, level=BookLevel.L2, delta_type=DeltaType.DELETE if volume == 0 else DeltaType.UPDATE, order=Order( price=price_to_probability( price, side=B2N_MARKET_STREAM_SIDE[side]), size=Quantity(volume, precision=8), side=B2N_MARKET_STREAM_SIDE[side], ), ts_event_ns=ts_event_ns, ts_recv_ns=ts_recv_ns, )) if deltas: ob_update = OrderBookDeltas( level=BookLevel.L2, instrument_id=instrument.id, deltas=deltas, ts_event_ns=ts_event_ns, ts_recv_ns=ts_recv_ns, ) return [ob_update] else: return []
def _handle_book_updates(runner, instrument, timestamp_ns): deltas = [] for side in B_SIDE_KINDS: for upd in runner.get(side, []): # TODO - Fix this crap if len(upd) == 3: _, price, volume = upd else: price, volume = upd deltas.append( OrderBookDelta( delta_type=OrderBookDeltaType.DELETE if volume == 0 else OrderBookDeltaType.UPDATE, order=Order( price=price_to_probability( price, side=B2N_MARKET_STREAM_SIDE[side]), volume=volume, side=B2N_MARKET_STREAM_SIDE[side], ), instrument_id=instrument.id, timestamp_ns=timestamp_ns, )) if deltas: ob_update = OrderBookDeltas( level=OrderBookLevel.L2, instrument_id=instrument.id, deltas=deltas, timestamp_ns=timestamp_ns, ) return [ob_update] else: return []
def _build_order_book_deltas(values): return OrderBookDeltas( instrument_id=InstrumentId.from_str(values[0]["instrument_id"]), level=BookLevelParser.from_str_py(values[0]["level"]), deltas=[OrderBookDelta.from_dict(v) for v in values], ts_event_ns=data[0]["ts_event_ns"], ts_recv_ns=data[0]["ts_recv_ns"], )
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, level=BookLevel.L2, delta_type=DeltaType.ADD, order=order1, ts_event_ns=0, ts_recv_ns=0, ) order2 = Order(price=10, size=15, side=OrderSide.BUY, id="2") delta2 = OrderBookDelta( instrument_id=AUDUSD, level=BookLevel.L2, delta_type=DeltaType.ADD, order=order2, ts_event_ns=0, ts_recv_ns=0, ) deltas = OrderBookDeltas( instrument_id=AUDUSD, level=BookLevel.L2, deltas=[delta1, delta2], ts_event_ns=0, ts_recv_ns=0, ) # Act result = OrderBookDeltas.to_dict(deltas) # Assert assert result == { "type": "OrderBookDeltas", "instrument_id": "AUD/USD.SIM", "level": "L2", "deltas": '[{"type": "OrderBookDelta", "instrument_id": "AUD/USD.SIM", "level": "L2", "delta_type": "ADD", "order_price": 10.0, "order_size": 5.0, "order_side": "BUY", "order_id": "1", "ts_event_ns": 0, "ts_recv_ns": 0}, {"type": "OrderBookDelta", "instrument_id": "AUD/USD.SIM", "level": "L2", "delta_type": "ADD", "order_price": 10.0, "order_size": 15.0, "order_side": "BUY", "order_id": "2", "ts_event_ns": 0, "ts_recv_ns": 0}]', # noqa "ts_event_ns": 0, "ts_recv_ns": 0, }
def test_handle_order_book_operations_sends_to_data_engine(self): # Arrange deltas = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=[], timestamp_ns=0, ) # Act self.client._handle_data_py(deltas) # Assert self.assertEqual(1, self.data_engine.data_count)
def _merge_order_book_deltas(all_deltas: List[OrderBookDeltas]): per_instrument_deltas = defaultdict(list) level = one(set(deltas.level for deltas in all_deltas)) timestamp_ns = one(set(deltas.timestamp_ns for deltas in all_deltas)) for deltas in all_deltas: per_instrument_deltas[deltas.instrument_id].extend(deltas.deltas) return [ OrderBookDeltas( instrument_id=instrument_id, deltas=deltas, level=level, timestamp_ns=timestamp_ns, ) for instrument_id, deltas in per_instrument_deltas.items() ]
def test_orderbook_operations(empty_book): delta = OrderBookDelta( delta_type=OrderBookDeltaType.UPDATE, order=Order( 0.5814, 672.45, OrderSide.SELL, "4a25c3f6-76e7-7584-c5a3-4ec84808e240" ), instrument_id=TestStubs.audusd_id(), timestamp_ns=pd.Timestamp.utcnow().timestamp() * 1e9, ) deltas = OrderBookDeltas( instrument_id=TestStubs.audusd_id(), level=OrderBookLevel.L2, deltas=[delta], timestamp_ns=pd.Timestamp.utcnow().timestamp() * 1e9, ) empty_book.apply_deltas(deltas) assert empty_book.best_ask_price() == 0.5814
def test_process_order_book_ops_then_sends_to_registered_handler(self): # Arrange self.data_engine.register_client(self.binance_client) self.binance_client.connect() self.data_engine.process( ETHUSDT_BINANCE ) # <-- add necessary instrument for test handler = [] subscribe = Subscribe( client_id=ClientId(BINANCE.value), data_type=DataType( OrderBook, { "InstrumentId": ETHUSDT_BINANCE.id, "Level": OrderBookLevel.L2, "Depth": 25, "Interval": 0, # Streaming }, ), handler=handler.append, command_id=self.uuid_factory.generate(), timestamp_ns=self.clock.timestamp_ns(), ) self.data_engine.execute(subscribe) deltas = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=[], timestamp_origin_ns=0, timestamp_ns=0, ) # Act self.data_engine.process(deltas) # Assert assert self.data_engine.subscribed_order_books == [ETHUSDT_BINANCE.id] assert handler[0].instrument_id == ETHUSDT_BINANCE.id assert type(handler[0]) == L2OrderBook
def test_hash_str_and_repr(self): # Arrange order1 = Order(price=10, size=5, side=OrderSide.BUY, id="1") delta1 = OrderBookDelta( instrument_id=AUDUSD, level=BookLevel.L2, delta_type=DeltaType.ADD, order=order1, ts_event_ns=0, ts_recv_ns=0, ) order2 = Order(price=10, size=15, side=OrderSide.BUY, id="2") delta2 = OrderBookDelta( instrument_id=AUDUSD, level=BookLevel.L2, delta_type=DeltaType.ADD, order=order2, ts_event_ns=0, ts_recv_ns=0, ) deltas = OrderBookDeltas( instrument_id=AUDUSD, level=BookLevel.L2, deltas=[delta1, delta2], ts_event_ns=0, ts_recv_ns=0, ) # Act, Assert assert isinstance(hash(deltas), int) assert ( str(deltas) == "OrderBookDeltas('AUD/USD.SIM', level=L2, [OrderBookDelta('AUD/USD.SIM', level=L2, delta_type=ADD, order=Order(10.0, 5.0, BUY, 1), ts_recv_ns=0), OrderBookDelta('AUD/USD.SIM', level=L2, delta_type=ADD, order=Order(10.0, 15.0, BUY, 2), ts_recv_ns=0)], ts_recv_ns=0)" # noqa ) assert ( repr(deltas) == "OrderBookDeltas('AUD/USD.SIM', level=L2, [OrderBookDelta('AUD/USD.SIM', level=L2, delta_type=ADD, order=Order(10.0, 5.0, BUY, 1), ts_recv_ns=0), OrderBookDelta('AUD/USD.SIM', level=L2, delta_type=ADD, order=Order(10.0, 15.0, BUY, 2), ts_recv_ns=0)], ts_recv_ns=0)" # noqa )
def test_serialize_and_deserialize_order_book_deltas(self): kw = { "instrument_id": "AUD/USD.SIM", "ts_event_ns": 0, "ts_recv_ns": 0, "level": "L2", } deltas = OrderBookDeltas( instrument_id=TestStubs.audusd_id(), level=BookLevel.L2, deltas=[ OrderBookDelta.from_dict({ "delta_type": "ADD", "order_side": "BUY", "order_price": 8.0, "order_size": 30.0, "order_id": "e0364f94-8fcb-0262-cbb3-075c51ee4917", **kw, }), OrderBookDelta.from_dict({ "delta_type": "ADD", "order_side": "SELL", "order_price": 15.0, "order_size": 10.0, "order_id": "cabec174-acc6-9204-9ebf-809da3896daf", **kw, }), ], ts_event_ns=0, ts_recv_ns=0, ) serialized = to_parquet(buff=self.buffer, objects=[deltas]) deserialized = from_parquet(serialized) # Assert assert deserialized == [deltas]
def test_add_order_book_operations_adds_to_container(self): # Arrange engine = BacktestEngine() engine.add_instrument(AUDUSD_SIM) engine.add_instrument(ETHUSDT_BINANCE) deltas = [ OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order( price=Price.from_str("13.0"), volume=Quantity.from_str("40"), side=OrderSide.SELL, ), timestamp_origin_ns=0, timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order( price=Price.from_str("12.0"), volume=Quantity.from_str("30"), side=OrderSide.SELL, ), timestamp_origin_ns=0, timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order( price=Price.from_str("11.0"), volume=Quantity.from_str("20"), side=OrderSide.SELL, ), timestamp_origin_ns=0, timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order( price=Price.from_str("10.0"), volume=Quantity.from_str("20"), side=OrderSide.BUY, ), timestamp_origin_ns=0, timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order( price=Price.from_str("9.0"), volume=Quantity.from_str("30"), side=OrderSide.BUY, ), timestamp_origin_ns=0, timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order( price=Price.from_str("0.0"), volume=Quantity.from_str("40"), side=OrderSide.BUY, ), timestamp_origin_ns=0, timestamp_ns=0, ), ] operations1 = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=deltas, timestamp_origin_ns=0, timestamp_ns=0, ) operations2 = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=deltas, timestamp_origin_ns=1000, timestamp_ns=1000, ) # Act engine.add_order_book_data([operations2, operations1]) # <-- not sorted
def test_add_order_book_operations_adds_to_container(self): # Arrange data = BacktestDataContainer() deltas = [ OrderBookDelta( OrderBookDeltaType.ADD, Order(13.0, 40, OrderSide.SELL), instrument_id=AUDUSD_SIM.id, timestamp_ns=0, ), OrderBookDelta( OrderBookDeltaType.ADD, Order(12.0, 30, OrderSide.SELL), instrument_id=AUDUSD_SIM.id, timestamp_ns=0, ), OrderBookDelta( OrderBookDeltaType.ADD, Order(11.0, 20, OrderSide.SELL), instrument_id=AUDUSD_SIM.id, timestamp_ns=0, ), OrderBookDelta( OrderBookDeltaType.ADD, Order(10.0, 20, OrderSide.BUY), instrument_id=AUDUSD_SIM.id, timestamp_ns=0, ), OrderBookDelta( OrderBookDeltaType.ADD, Order(9.0, 30, OrderSide.BUY), instrument_id=AUDUSD_SIM.id, timestamp_ns=0, ), OrderBookDelta( OrderBookDeltaType.ADD, Order(0.0, 40, OrderSide.BUY), instrument_id=AUDUSD_SIM.id, timestamp_ns=0, ), ] operations1 = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=deltas, timestamp_ns=0, ) operations2 = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=deltas, timestamp_ns=1000, ) # Act data.add_order_book_data([operations2, operations1]) # <-- not sorted # Assert assert ClientId("BINANCE") in data.clients assert ETHUSDT_BINANCE.id in data.books assert data.order_book_data == [operations1, operations2] # <-- sorted
def test_add_order_book_operations_adds_to_container(self): # Arrange data = BacktestDataContainer() deltas = [ OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order(price=Price("13.0"), volume=Quantity("40"), side=OrderSide.SELL), timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order(price=Price("12.0"), volume=Quantity("30"), side=OrderSide.SELL), timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order(price=Price("11.0"), volume=Quantity("20"), side=OrderSide.SELL), timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order(price=Price("10.0"), volume=Quantity("20"), side=OrderSide.BUY), timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order(price=Price("9.0"), volume=Quantity("30"), side=OrderSide.BUY), timestamp_ns=0, ), OrderBookDelta( instrument_id=AUDUSD_SIM.id, level=OrderBookLevel.L2, delta_type=OrderBookDeltaType.ADD, order=Order(price=Price("0.0"), volume=Quantity("40"), side=OrderSide.BUY), timestamp_ns=0, ), ] operations1 = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=deltas, timestamp_ns=0, ) operations2 = OrderBookDeltas( instrument_id=ETHUSDT_BINANCE.id, level=OrderBookLevel.L2, deltas=deltas, timestamp_ns=1000, ) # Act data.add_order_book_data([operations2, operations1]) # <-- not sorted # Assert assert ClientId("BINANCE") in data.clients assert ETHUSDT_BINANCE.id in data.books assert data.order_book_data == [operations1, operations2] # <-- sorted