def test_serialize_and_deserialize_stop_market_order_initialized_events(self): # Arrange options = { "trigger_price": "1.0005", } event = OrderInitialized( self.trader_id, self.strategy_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), OrderSide.SELL, OrderType.STOP_MARKET, Quantity(100000, precision=0), TimeInForce.DAY, post_only=False, reduce_only=True, options=options, order_list_id=OrderListId("1"), contingency_type=ContingencyType.OTO, linked_order_ids=[ClientOrderId("O-123457"), ClientOrderId("O-123458")], parent_order_id=ClientOrderId("O-123455"), tags=None, 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
def test_serialize_and_deserialize_market_order_initialized_events(self): # Arrange event = OrderInitialized( self.trader_id, self.strategy_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), OrderSide.SELL, OrderType.MARKET, Quantity(100000, precision=0), TimeInForce.FOK, reduce_only=True, 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", event_id=UUID4(), ts_init=0, ) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == event
def test_order_initialized_event_to_from_dict_and_str_repr(self): # Arrange uuid = UUID4() event = OrderInitialized( trader_id=TraderId("TRADER-001"), strategy_id=StrategyId("SCALPER-001"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), client_order_id=ClientOrderId("O-2020872378423"), order_side=OrderSide.BUY, order_type=OrderType.LIMIT, quantity=Quantity.from_str("0.561000"), time_in_force=TimeInForce.DAY, reduce_only=True, options={"price": "15200.10"}, order_list_id=OrderListId("1"), parent_order_id=None, child_order_ids=[ClientOrderId("O-2020872378424")], contingency=ContingencyType.OTO, contingency_ids=[ClientOrderId("O-2020872378424")], tags="ENTRY", event_id=uuid, ts_init=0, ) # Act, Assert assert OrderInitialized.from_dict( OrderInitialized.to_dict(event)) == event assert ( str(event) == f"OrderInitialized(instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, side=BUY, type=LIMIT, quantity=0.561000, time_in_force=DAY, reduce_only=True, options={{'price': '15200.10'}}, order_list_id=1, parent_order_id=None, child_order_ids=['O-2020872378424'], contingency=OTO, contingency_ids=['O-2020872378424'], tags=ENTRY)" # noqa ) assert ( repr(event) == f"OrderInitialized(trader_id=TRADER-001, strategy_id=SCALPER-001, instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, side=BUY, type=LIMIT, quantity=0.561000, time_in_force=DAY, reduce_only=True, options={{'price': '15200.10'}}, order_list_id=1, parent_order_id=None, child_order_ids=['O-2020872378424'], contingency=OTO, contingency_ids=['O-2020872378424'], tags=ENTRY, event_id={uuid}, ts_init=0)" # noqa )
def test_add_order_status_reports(self): # Arrange report_id1 = UUID4() mass_status = ExecutionMassStatus( client_id=ClientId("IB"), account_id=AccountId("IB", "U123456789"), venue=Venue("IDEALPRO"), report_id=report_id1, ts_init=0, ) venue_order_id = VenueOrderId("2") report_id2 = UUID4() report = OrderStatusReport( account_id=AccountId("IB", "U123456789"), instrument_id=AUDUSD_IDEALPRO, client_order_id=ClientOrderId("O-123456"), order_list_id=OrderListId("1"), venue_order_id=venue_order_id, 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=report_id2, ts_accepted=1_000_000, ts_triggered=0, ts_last=2_000_000, ts_init=3_000_000, ) # Act mass_status.add_order_reports([report]) # Assert assert mass_status.order_reports()[venue_order_id] == report assert ( repr(mass_status) == f"ExecutionMassStatus(client_id=IB, account_id=IB-U123456789, venue=IDEALPRO, order_reports={{VenueOrderId('2'): OrderStatusReport(account_id=IB-U123456789, instrument_id=AUD/USD.IDEALPRO, client_order_id=O-123456, order_list_id=1, venue_order_id=2, order_side=SELL, order_type=STOP_LIMIT, contingency_type=OCO, time_in_force=DAY, expire_time=None, order_status=REJECTED, price=0.90090, trigger_price=0.90100, trigger_type=DEFAULT, limit_offset=None, trailing_offset=0.00010, offset_type=PRICE, quantity=1_000_000, filled_qty=0, leaves_qty=1_000_000, display_qty=None, avg_px=None, post_only=True, reduce_only=False, cancel_reason=SOME_REASON, report_id={report_id2}, ts_accepted=1000000, ts_triggered=0, ts_last=2000000, ts_init=3000000)}}, trade_reports={{}}, position_reports={{}}, report_id={report_id1}, ts_init=0)" # noqa ) assert ( repr(report) == f"OrderStatusReport(account_id=IB-U123456789, instrument_id=AUD/USD.IDEALPRO, client_order_id=O-123456, order_list_id=1, venue_order_id=2, order_side=SELL, order_type=STOP_LIMIT, contingency_type=OCO, time_in_force=DAY, expire_time=None, order_status=REJECTED, price=0.90090, trigger_price=0.90100, trigger_type=DEFAULT, limit_offset=None, trailing_offset=0.00010, offset_type=PRICE, quantity=1_000_000, filled_qty=0, leaves_qty=1_000_000, display_qty=None, avg_px=None, post_only=True, reduce_only=False, cancel_reason=SOME_REASON, report_id={report_id2}, ts_accepted=1000000, ts_triggered=0, ts_last=2000000, ts_init=3000000)" # noqa )
def test_submit_order_list_when_trading_halted_then_denies_orders(self): # Arrange self.exec_engine.start() strategy = TradingStrategy() strategy.register( trader_id=self.trader_id, portfolio=self.portfolio, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) entry = strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) stop_loss = strategy.order_factory.stop_market( # <-- duplicate AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), Price.from_str("1.00000"), ) take_profit = strategy.order_factory.limit( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), Price.from_str("1.10000"), ) bracket = OrderList( list_id=OrderListId("1"), orders=[entry, stop_loss, take_profit], ) submit_bracket = SubmitOrderList( self.trader_id, strategy.id, bracket, self.uuid_factory.generate(), self.clock.timestamp_ns(), ) # Halt trading self.risk_engine.set_trading_state(TradingState.HALTED) # Act self.risk_engine.execute(submit_bracket) # Assert assert self.risk_engine.command_count == 1 # <-- command never reaches engine
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_instantiate_order_status_report(self): # Arrange, Act report_id = UUID4() report = OrderStatusReport( account_id=AccountId("SIM", "001"), instrument_id=AUDUSD_IDEALPRO, 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=report_id, ts_accepted=1_000_000, ts_triggered=1_500_000, ts_last=2_000_000, ts_init=3_000_000, ) # Assert assert ( str(report) == f"OrderStatusReport(account_id=SIM-001, instrument_id=AUD/USD.IDEALPRO, client_order_id=O-123456, order_list_id=1, venue_order_id=2, order_side=SELL, order_type=STOP_LIMIT, contingency_type=OCO, time_in_force=DAY, expire_time=None, order_status=REJECTED, price=0.90090, trigger_price=0.90100, trigger_type=DEFAULT, limit_offset=None, trailing_offset=0.00010, offset_type=PRICE, quantity=1_000_000, filled_qty=0, leaves_qty=1_000_000, display_qty=None, avg_px=None, post_only=True, reduce_only=False, cancel_reason=SOME_REASON, report_id={report_id}, ts_accepted=1000000, ts_triggered=1500000, ts_last=2000000, ts_init=3000000)" # noqa ) assert ( repr(report) == f"OrderStatusReport(account_id=SIM-001, instrument_id=AUD/USD.IDEALPRO, client_order_id=O-123456, order_list_id=1, venue_order_id=2, order_side=SELL, order_type=STOP_LIMIT, contingency_type=OCO, time_in_force=DAY, expire_time=None, order_status=REJECTED, price=0.90090, trigger_price=0.90100, trigger_type=DEFAULT, limit_offset=None, trailing_offset=0.00010, offset_type=PRICE, quantity=1_000_000, filled_qty=0, leaves_qty=1_000_000, display_qty=None, avg_px=None, post_only=True, reduce_only=False, cancel_reason=SOME_REASON, report_id={report_id}, ts_accepted=1000000, ts_triggered=1500000, ts_last=2000000, ts_init=3000000)" # noqa )
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_bracket_limit_order_list(self): # Arrange, Act bracket = self.order_factory.bracket_limit( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), Price.from_str("1.00000"), Price.from_str("0.99990"), Price.from_str("1.00010"), TimeInForce.GTC, ) # Assert assert bracket.id == OrderListId("1") assert bracket.instrument_id == AUDUSD_SIM.id assert len(bracket.orders) == 3 assert bracket.orders[0].type == OrderType.LIMIT assert bracket.orders[1].type == OrderType.STOP_MARKET assert bracket.orders[2].type == OrderType.LIMIT assert bracket.orders[0].instrument_id == AUDUSD_SIM.id assert bracket.orders[1].instrument_id == AUDUSD_SIM.id assert bracket.orders[2].instrument_id == AUDUSD_SIM.id assert bracket.orders[0].client_order_id == ClientOrderId( "O-19700101-000000-000-001-1") assert bracket.orders[1].client_order_id == ClientOrderId( "O-19700101-000000-000-001-2") assert bracket.orders[2].client_order_id == ClientOrderId( "O-19700101-000000-000-001-3") assert bracket.orders[0].side == OrderSide.BUY assert bracket.orders[1].side == OrderSide.SELL assert bracket.orders[2].side == OrderSide.SELL assert bracket.orders[0].quantity == Quantity.from_int(100000) assert bracket.orders[1].quantity == Quantity.from_int(100000) assert bracket.orders[2].quantity == Quantity.from_int(100000) assert bracket.orders[1].price == Price.from_str("0.99990") assert bracket.orders[2].price == Price.from_str("1.00010") assert bracket.orders[1].time_in_force == TimeInForce.GTC assert bracket.orders[2].time_in_force == TimeInForce.GTC assert bracket.orders[1].expire_time is None assert bracket.orders[2].expire_time is None assert bracket.orders[0].contingency == ContingencyType.OTO assert bracket.orders[1].contingency == ContingencyType.OCO assert bracket.orders[2].contingency == ContingencyType.OCO assert bracket.orders[0].contingency_ids == [ ClientOrderId("O-19700101-000000-000-001-2"), ClientOrderId("O-19700101-000000-000-001-3"), ] assert bracket.orders[1].contingency_ids == [ ClientOrderId("O-19700101-000000-000-001-3") ] assert bracket.orders[2].contingency_ids == [ ClientOrderId("O-19700101-000000-000-001-2") ] assert bracket.orders[0].child_order_ids == [ ClientOrderId("O-19700101-000000-000-001-2"), ClientOrderId("O-19700101-000000-000-001-3"), ] assert bracket.orders[1].parent_order_id == ClientOrderId( "O-19700101-000000-000-001-1") assert bracket.orders[2].parent_order_id == ClientOrderId( "O-19700101-000000-000-001-1") assert bracket.ts_init == 0
"price": "1.0010", } event = OrderInitialized( self.trader_id, self.strategy_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), OrderSide.SELL, OrderType.LIMIT, Quantity(100000, precision=0), TimeInForce.DAY, post_only=True, reduce_only=False, options=options, order_list_id=OrderListId("1"), contingency_type=ContingencyType.OTO, linked_order_ids=[ClientOrderId("O-123457"), ClientOrderId("O-123458")], parent_order_id=ClientOrderId("O-123455"), tags=None, 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