def test_serialize_and_deserialize_market_order_initialized_events(self): # Arrange event = OrderInitialized( ClientOrderId("O-123456"), StrategyId("S-001"), AUDUSD_SIM.id, OrderSide.SELL, OrderType.MARKET, Quantity(100000, precision=0), TimeInForce.FOK, uuid4(), 0, options={}, ) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == event
def test_serialize_and_deserialize_amend_order_commands(self): # Arrange command = AmendOrder( self.venue, self.trader_id, self.account_id, ClientOrderId("O-123456"), Quantity(100000), Price("1.00001"), uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(command, deserialized) print(b64encode(serialized)) print(command)
def test_order_cancel_reject(self): # Arrange uuid = uuid4() event = OrderCancelReject( account_id=AccountId("SIM", "000"), cl_ord_id=ClientOrderId("O-2020872378423"), order_id=OrderId("123456"), rejected_time=UNIX_EPOCH, response_to="O-2020872378423", reason="ORDER_DOES_NOT_EXIST", event_id=uuid, event_timestamp=UNIX_EPOCH, ) # Act self.assertEqual(f"OrderCancelReject(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"response_to=O-2020872378423, reason='ORDER_DOES_NOT_EXIST', " f"event_id={uuid})", str(event)) self.assertEqual(f"OrderCancelReject(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"response_to=O-2020872378423, reason='ORDER_DOES_NOT_EXIST', " f"event_id={uuid})", repr(event))
def test_reset_order_factory(self): # Arrange self.order_factory.limit( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) # Act self.order_factory.reset() order2 = self.order_factory.limit( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) self.assertEqual(ClientOrderId("O-19700101-000000-000-001-1"), order2.cl_ord_id)
def test_handle_order_status_report(self): # Arrange order_report = OrderStatusReport( account_id=AccountId("SIM", "001"), instrument_id=AUDUSD_SIM.id, client_order_id=ClientOrderId("O-123456"), order_list_id=OrderListId("1"), venue_order_id=VenueOrderId("2"), order_side=OrderSide.SELL, order_type=OrderType.STOP_LIMIT, contingency_type=ContingencyType.OCO, time_in_force=TimeInForce.DAY, expire_time=None, order_status=OrderStatus.REJECTED, price=Price.from_str("0.90090"), trigger_price=Price.from_str("0.90100"), trigger_type=TriggerType.DEFAULT, limit_offset=None, trailing_offset=Decimal("0.00010"), offset_type=TrailingOffsetType.PRICE, quantity=Quantity.from_int(1_000_000), filled_qty=Quantity.from_int(0), display_qty=None, avg_px=None, post_only=True, reduce_only=False, cancel_reason="SOME_REASON", report_id=UUID4(), ts_accepted=1_000_000, ts_triggered=1_500_000, ts_last=2_000_000, ts_init=3_000_000, ) # Act self.exec_engine.reconcile_report(order_report) # Assert assert self.exec_engine.report_count == 1
def test_serialize_and_deserialize_amend_order_commands(self): # Arrange command = UpdateOrder( self.trader_id, StrategyId("SCALPER-001"), AUDUSD_SIM.id, ClientOrderId("O-123456"), VenueOrderId("001"), Quantity(100000, precision=0), Price(1.00001, precision=5), uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command print(b64encode(serialized)) print(command)
def parse_order_report_http( account_id: AccountId, instrument_id: InstrumentId, data: BinanceFuturesOrder, report_id: UUID4, ts_init: int, ) -> OrderStatusReport: price = Decimal(data.price) trigger_price = Decimal(data.stopPrice) avg_px = Decimal(data.avgPrice) time_in_force = BinanceFuturesTimeInForce(data.timeInForce.upper()) return OrderStatusReport( account_id=account_id, instrument_id=instrument_id, client_order_id=ClientOrderId(data.clientOrderId) if data.clientOrderId != "" else None, venue_order_id=VenueOrderId(str(data.orderId)), order_side=OrderSide[data.side.upper()], order_type=parse_order_type(data.type), time_in_force=parse_time_in_force(time_in_force), order_status=parse_order_status(data.status), price=Price.from_str(data.price) if price is not None else None, quantity=Quantity.from_str(data.origQty), filled_qty=Quantity.from_str(data.executedQty), avg_px=avg_px if avg_px > 0 else None, post_only=time_in_force == BinanceFuturesTimeInForce.GTX, reduce_only=data.reduceOnly, report_id=report_id, ts_accepted=millis_to_nanos(data.time), ts_last=millis_to_nanos(data.updateTime), ts_init=ts_init, trigger_price=Price.from_str(str(trigger_price)) if trigger_price > 0 else None, trigger_type=parse_trigger_type(data.workingType), trailing_offset=Decimal(data.priceRate) * 100 if data.priceRate is not None else None, offset_type=TrailingOffsetType.BASIS_POINTS if data.priceRate is not None else TrailingOffsetType.NONE, )
def test_order_accepted(self, order_id=None): if order_id is None: order_id = OrderId("123456") # Arrange uuid = uuid4() event = OrderAccepted( account_id=AccountId("SIM", "000"), cl_ord_id=ClientOrderId("O-2020872378423"), order_id=order_id, accepted_time=UNIX_EPOCH, event_id=uuid, event_timestamp=UNIX_EPOCH, ) # Act self.assertEqual( f"OrderAccepted(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"order_id={123456}, id={uuid})", str(event)) # noqa self.assertEqual( f"OrderAccepted(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"order_id={123456}, id={uuid})", repr(event)) # noqa
def test_serialize_and_deserialize_amend_order_commands(self): # Arrange command = UpdateOrder( AUDUSD_SIM.id.venue.client_id, self.trader_id, self.account_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), Quantity(100000), Price("1.00001"), uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command print(b64encode(serialized)) print(command)
def submit_order_command(): return SubmitOrder( instrument_id=BetfairTestStubs.instrument_id(), trader_id=BetfairTestStubs.trader_id(), account_id=BetfairTestStubs.account_id(), strategy_id=BetfairTestStubs.strategy_id(), position_id=BetfairTestStubs.position_id(), order=LimitOrder( client_order_id=ClientOrderId("1"), strategy_id=BetfairTestStubs.strategy_id(), instrument_id=BetfairTestStubs.instrument_id(), order_side=OrderSide.BUY, quantity=Quantity(10), price=Price(0.33, 5), time_in_force=TimeInForce.GTC, expire_time=None, init_id=BetfairTestStubs.uuid(), timestamp_ns=BetfairTestStubs.clock().timestamp_ns(), ), command_id=BetfairTestStubs.uuid(), timestamp_ns=BetfairTestStubs.clock().timestamp_ns(), )
def test_add_order_state_report(self): # Arrange report = ExecutionMassStatus( client="IB", account_id=TestStubs.account_id(), timestamp_ns=0, ) venue_order_id = VenueOrderId("1") order_report = OrderStatusReport( client_order_id=ClientOrderId("O-123456"), venue_order_id=venue_order_id, order_state=OrderState.REJECTED, filled_qty=Quantity(0), timestamp_ns=0, ) # Act report.add_order_report(order_report) # Assert assert report.order_reports()[venue_order_id] == order_report
def test_order_filled(self): # Arrange uuid = uuid4() event = OrderFilled( account_id=AccountId("SIM", "000"), client_order_id=ClientOrderId("O-2020872378423"), venue_order_id=VenueOrderId("123456"), execution_id=ExecutionId("1"), position_id=PositionId("2"), strategy_id=StrategyId("SCALPER", "001"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), order_side=OrderSide.BUY, last_qty=Quantity("0.561000"), last_px=Price("15600.12445"), cum_qty=Quantity("0.561000"), leaves_qty=Quantity(0), currency=USDT, is_inverse=False, commission=Money("12.20000000", USDT), liquidity_side=LiquiditySide.MAKER, execution_ns=0, event_id=uuid, timestamp_ns=0, ) print(event) # Act assert ( f"OrderFilled(account_id=SIM-000, client_order_id=O-2020872378423, " f"venue_order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"instrument_id=BTC/USDT.BINANCE, side=BUY-MAKER, last_qty=0.561000, " f"last_px=15600.12445 USDT, cum_qty=0.561000, leaves_qty=0, " f"commission=12.20000000 USDT, event_id={uuid})" == str(event)) assert ( f"OrderFilled(account_id=SIM-000, client_order_id=O-2020872378423, " f"venue_order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"instrument_id=BTC/USDT.BINANCE, side=BUY-MAKER, last_qty=0.561000, " f"last_px=15600.12445 USDT, cum_qty=0.561000, leaves_qty=0, " f"commission=12.20000000 USDT, event_id={uuid})" == repr(event))
def test_pack_and_unpack_limit_orders_with_expiration(self): # Arrange order = LimitOrder( self.trader_id, self.strategy_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), OrderSide.BUY, Quantity(100000, precision=0), price=Price(1.00000, precision=5), time_in_force=TimeInForce.GTD, expire_time=UNIX_EPOCH + timedelta(minutes=1), init_id=UUID4(), ts_init=0, ) # Act packed = OrderInitialized.to_dict(order.last_event) unpacked = self.unpacker.unpack(packed) # Assert assert unpacked == order
def submit_order_command(): return SubmitOrder( trader_id=BetfairTestStubs.trader_id(), strategy_id=BetfairTestStubs.strategy_id(), position_id=BetfairTestStubs.position_id(), order=LimitOrder( client_order_id=ClientOrderId( f"O-20210410-022422-001-001-{BetfairTestStubs.strategy_id().value}" ), strategy_id=BetfairTestStubs.strategy_id(), instrument_id=BetfairTestStubs.instrument_id(), order_side=OrderSide.BUY, quantity=Quantity.from_int(10), price=Price(0.33, precision=5), time_in_force=TimeInForce.GTC, expire_time=None, init_id=BetfairTestStubs.uuid(), timestamp_ns=BetfairTestStubs.clock().timestamp_ns(), ), command_id=BetfairTestStubs.uuid(), timestamp_ns=BetfairTestStubs.clock().timestamp_ns(), )
def test_pack_and_unpack_stop_limit_orders_with_expire_time(self): # Arrange order = StopLimitOrder( ClientOrderId("O-123456"), StrategyId("S-001"), AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000, precision=0), price=Price(1.00000, precision=5), trigger=Price(1.00010, precision=5), time_in_force=TimeInForce.GTD, expire_time=UNIX_EPOCH, init_id=uuid4(), timestamp_ns=0, ) # Act packed = OrderInitialized.to_dict(order.last_event) unpacked = self.unpacker.unpack(packed) # Assert assert unpacked == order
def test_serialize_and_deserialize_stop_limit_order_initialized_events( self): # Arrange options = { "ExpireTime": None, "Price": "1.0005", "Trigger": "1.0010", "PostOnly": True, "Hidden": False, } event = OrderInitialized( self.trader_id, self.strategy_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), OrderSide.SELL, OrderType.STOP_LIMIT, Quantity(100000, precision=0), TimeInForce.DAY, reduce_only=True, options=options, order_list_id=OrderListId("1"), parent_order_id=ClientOrderId("O-123455"), child_order_ids=[ ClientOrderId("O-123457"), ClientOrderId("O-123458") ], contingency=ContingencyType.OTO, contingency_ids=[ ClientOrderId("O-123457"), ClientOrderId("O-123458") ], tags="entry,bulk", event_id=UUID4(), ts_init=0, ) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == event assert deserialized.options == options assert deserialized.tags == "entry,bulk"
def test_order_filled(self): # Arrange uuid = uuid4() event = OrderFilled( account_id=AccountId("SIM", "000"), cl_ord_id=ClientOrderId("O-2020872378423"), order_id=OrderId("123456"), execution_id=ExecutionId("1"), position_id=PositionId("2"), strategy_id=StrategyId("SCALPER", "001"), symbol=Symbol("BTC/USDT", Exchange("BINANCE")), order_side=OrderSide.BUY, fill_qty=Quantity("0.561000"), cum_qty=Quantity("0.561000"), leaves_qty=Quantity(0), fill_price=Price("15600.12445"), currency=USDT, is_inverse=False, commission=Money("12.20000000", USDT), liquidity_side=LiquiditySide.MAKER, execution_time=UNIX_EPOCH, event_id=uuid, event_timestamp=UNIX_EPOCH, ) # Act self.assertEqual( f"OrderFilled(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"symbol=BTC/USDT.BINANCE, side=BUY-MAKER, fill_qty=0.561000, " f"fill_price=15600.12445 USDT, cum_qty=0.561000, leaves_qty=0, " f"commission=12.20000000 USDT, id={uuid})", str(event)) # noqa self.assertEqual( f"OrderFilled(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"symbol=BTC/USDT.BINANCE, side=BUY-MAKER, fill_qty=0.561000, " f"fill_price=15600.12445 USDT, cum_qty=0.561000, leaves_qty=0, " f"commission=12.20000000 USDT, id={uuid})", repr(event)) # noqa
def test_order_initialized(self): # Arrange uuid = uuid4() event = OrderInitialized(cl_ord_id=ClientOrderId("O-2020872378423"), strategy_id=StrategyId("SCALPER", "001"), symbol=Symbol("BTC/USDT", Exchange("BINANCE")), order_side=OrderSide.BUY, order_type=OrderType.LIMIT, quantity=Quantity("0.561000"), time_in_force=TimeInForce.DAY, event_id=uuid, event_timestamp=UNIX_EPOCH, options={"Price": "15200.10"}) # Act # Assert self.assertEqual( f"OrderInitialized(cl_ord_id=O-2020872378423, id={uuid})", str(event)) self.assertEqual( f"OrderInitialized(cl_ord_id=O-2020872378423, id={uuid})", repr(event))
def test_order_amended(self): # Arrange uuid = uuid4() event = OrderUpdated( account_id=AccountId("SIM", "000"), client_order_id=ClientOrderId("O-2020872378423"), venue_order_id=VenueOrderId("123456"), quantity=Quantity(500000), price=Price("1.95000"), updated_ns=0, event_id=uuid, timestamp_ns=0, ) # Act assert ( f"OrderUpdated(account_id=SIM-000, cl_order_id=O-2020872378423, " f"venue_order_id=123456, qty=500,000, price=1.95000, event_id={uuid})" == str(event)) assert ( f"OrderUpdated(account_id=SIM-000, cl_order_id=O-2020872378423, " f"venue_order_id=123456, qty=500,000, price=1.95000, event_id={uuid})" == repr(event))
def test_order_denied_event_to_from_dict_and_str_repr(self): # Arrange uuid = UUID4() event = OrderDenied( trader_id=TraderId("TRADER-001"), strategy_id=StrategyId("SCALPER-001"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), client_order_id=ClientOrderId("O-2020872378423"), reason="Exceeded MAX_ORDER_RATE", event_id=uuid, ts_init=0, ) # Act, Assert assert OrderDenied.from_dict(OrderDenied.to_dict(event)) == event assert ( str(event) == "OrderDenied(instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, reason=Exceeded MAX_ORDER_RATE)" # noqa ) assert ( repr(event) == f"OrderDenied(trader_id=TRADER-001, strategy_id=SCALPER-001, instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, reason=Exceeded MAX_ORDER_RATE, event_id={uuid}, ts_init=0)" # noqa )
def test_pack_and_unpack_market_if_touched_orders(self): # Arrange order = MarketIfTouchedOrder( self.trader_id, self.strategy_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), OrderSide.BUY, Quantity(100000, precision=0), trigger_price=Price(1.00000, precision=5), trigger_type=TriggerType.DEFAULT, time_in_force=TimeInForce.GTD, expire_time=UNIX_EPOCH + timedelta(minutes=1), init_id=UUID4(), ts_init=0, ) # Act packed = OrderInitialized.to_dict(order.last_event) unpacked = self.unpacker.unpack(packed) # Assert assert unpacked == order
def test_serialize_and_deserialize_order_modify_events(self): # Arrange event = OrderUpdated( self.trader_id, self.strategy_id, self.account_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), VenueOrderId("1"), Quantity(100000, precision=0), Price(0.80010, precision=5), Price(0.80050, precision=5), UUID4(), 0, 0, ) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == event
def test_pack_and_unpack_stop_limit_orders(self): # Arrange order = StopLimitOrder( self.trader_id, self.strategy_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), OrderSide.BUY, Quantity(100000, precision=0), price=Price(1.00000, precision=5), trigger=Price(1.00010, precision=5), time_in_force=TimeInForce.GTC, expire_time=None, init_id=UUID4(), ts_init=0, ) # Act packed = OrderInitialized.to_dict(order.last_event) unpacked = self.unpacker.unpack(packed) # Assert assert unpacked == order
def test_order_cancel_reject(self): # Arrange uuid = uuid4() event = OrderCancelRejected( account_id=AccountId("SIM", "000"), client_order_id=ClientOrderId("O-2020872378423"), venue_order_id=VenueOrderId("123456"), rejected_ns=0, response_to="O-2020872378423", reason="ORDER_DOES_NOT_EXIST", event_id=uuid, timestamp_ns=0, ) # Act assert ( f"OrderCancelRejected(account_id=SIM-000, client_order_id=O-2020872378423, " f"response_to=O-2020872378423, reason='ORDER_DOES_NOT_EXIST', " f"event_id={uuid})" == str(event)) assert ( f"OrderCancelRejected(account_id=SIM-000, client_order_id=O-2020872378423, " f"response_to=O-2020872378423, reason='ORDER_DOES_NOT_EXIST', " f"event_id={uuid})" == repr(event))
def test_serialize_and_deserialize_stop_orders_with_expire_time(self): # Arrange order = StopMarketOrder( ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), price=Price("1.00000"), time_in_force=TimeInForce.GTD, expire_time=UNIX_EPOCH, init_id=uuid4(), timestamp=UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(order) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(order, deserialized) print(b64encode(serialized)) print(order)
def test_order_amended(self): # Arrange uuid = uuid4() event = OrderAmended( account_id=AccountId("SIM", "000"), cl_ord_id=ClientOrderId("O-2020872378423"), order_id=OrderId("123456"), quantity=Quantity(500000), price=Price('1.95000'), amended_time=UNIX_EPOCH, event_id=uuid, event_timestamp=UNIX_EPOCH, ) # Act assert ( f"OrderAmended(account_id=SIM-000, cl_order_id=O-2020872378423, " f"order_id=123456, qty=500,000, price=1.95000, event_id={uuid})" == str(event)) assert ( f"OrderAmended(account_id=SIM-000, cl_order_id=O-2020872378423, " f"order_id=123456, qty=500,000, price=1.95000, event_id={uuid})" == repr(event))
def test_serialize_and_deserialize_limit_orders_with_expire_time(self): # Arrange order = LimitOrder( ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), price=Price("1.00000"), time_in_force=TimeInForce.GTD, expire_time=UNIX_EPOCH, init_id=uuid4(), timestamp_ns=0, ) # Act serialized = self.serializer.serialize(order) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == order print(b64encode(serialized)) print(order)
async def test_order_stream_filled_multiple_prices(self): # Arrange await self._setup_account() update1 = BetfairStreaming.generate_order_update( price="1.50", size=20, side="B", status="E", sm=10, avp="1.60", ) self._setup_exec_client_and_cache(update1) await self.client._handle_order_stream_update(update=update1) await asyncio.sleep(0) order = self.cache.order(client_order_id=ClientOrderId("0")) event = self.messages[-1] order.apply(event) # Act update2 = BetfairStreaming.generate_order_update( price="1.50", size=20, side="B", status="EC", sm=20, avp="1.55", ) self._setup_exec_client_and_cache(update2) await self.client._handle_order_stream_update(update=update2) await asyncio.sleep(0) # Assert assert len(self.messages) == 3 assert isinstance(self.messages[1], OrderFilled) assert isinstance(self.messages[2], OrderFilled) assert self.messages[1].last_px == price_to_probability("1.60") assert self.messages[2].last_px == price_to_probability("1.50")
def parse_order_report_http( account_id: AccountId, instrument_id: InstrumentId, data: Dict[str, Any], report_id: UUID4, ts_init: int, ) -> OrderStatusReport: client_id_str = data.get("clientOrderId") order_type = data["type"].upper() price = data.get("price") trigger_price = Decimal(data["stopPrice"]) avg_px = Decimal(data["price"]) return OrderStatusReport( account_id=account_id, instrument_id=instrument_id, client_order_id=ClientOrderId(client_id_str) if client_id_str is not None else None, venue_order_id=VenueOrderId(str(data["orderId"])), order_side=OrderSide[data["side"].upper()], order_type=parse_order_type(order_type), time_in_force=parse_time_in_force(data["timeInForce"].upper()), order_status=TimeInForce(data["status"].upper()), price=Price.from_str(price) if price is not None else None, quantity=Quantity.from_str(data["origQty"]), filled_qty=Quantity.from_str(data["executedQty"]), avg_px=avg_px if avg_px > 0 else None, post_only=order_type == "LIMIT_MAKER", reduce_only=False, report_id=report_id, ts_accepted=millis_to_nanos(data["time"]), ts_last=millis_to_nanos(data["updateTime"]), ts_init=ts_init, trigger_price=Price.from_str(str(trigger_price)) if trigger_price > 0 else None, trigger_type=TriggerType.LAST if trigger_price > 0 else TriggerType.NONE, )
def test_order_initialized(self): # Arrange uuid = uuid4() event = OrderInitialized( client_order_id=ClientOrderId("O-2020872378423"), strategy_id=StrategyId("SCALPER", "001"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), order_side=OrderSide.BUY, order_type=OrderType.LIMIT, quantity=Quantity("0.561000"), time_in_force=TimeInForce.DAY, event_id=uuid, timestamp_ns=0, options={"Price": "15200.10"}, ) # Act # Assert assert ( f"OrderInitialized(client_order_id=O-2020872378423, strategy_id=SCALPER-001, event_id={uuid})" == str(event)) assert ( f"OrderInitialized(client_order_id=O-2020872378423, strategy_id=SCALPER-001, event_id={uuid})" == repr(event))