def test_submit_order_with_valid_order_successfully_submits(self):
        # Arrange
        strategy = TradingStrategy()
        strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        order = strategy.order_factory.market(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        # Act
        strategy.submit_order(order)
        self.exchange.process(0)

        # Assert
        assert order in strategy.cache.orders()
        assert strategy.cache.orders()[0].status == OrderStatus.FILLED
        assert order.client_order_id not in strategy.cache.orders_working()
        assert not strategy.cache.is_order_working(order.client_order_id)
        assert strategy.cache.is_order_completed(order.client_order_id)
    def test_cancel_order_when_completed_does_not_submit_command(self):
        # Arrange
        strategy = TradingStrategy()
        strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        order = strategy.order_factory.stop_market(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("90.006"),
        )

        strategy.submit_order(order)
        self.exchange.process(0)
        self.exec_engine.process(TestStubs.event_order_expired(order))

        # Act
        strategy.cancel_order(order)
        self.exchange.process(0)

        # Assert
        assert strategy.cache.orders()[0].status == OrderStatus.EXPIRED
        assert order not in strategy.cache.orders_working()
        assert strategy.cache.order_exists(order.client_order_id)
        assert not strategy.cache.is_order_working(order.client_order_id)
        assert strategy.cache.is_order_completed(order.client_order_id)
Beispiel #3
0
    def test_can_flatten_all_positions(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag='001')
        self.exec_engine.register_strategy(strategy)

        order1 = strategy.order_factory.market(USDJPY_FXCM, OrderSide.BUY,
                                               Quantity(100000))

        order2 = strategy.order_factory.market(USDJPY_FXCM, OrderSide.BUY,
                                               Quantity(100000))

        position_id1 = strategy.position_id_generator.generate()
        position_id2 = strategy.position_id_generator.generate()

        strategy.submit_order(order1, position_id1)
        strategy.submit_order(order2, position_id2)

        # Act
        strategy.flatten_all_positions()

        # Assert
        self.assertEqual(order1, strategy.orders()[order1.id])
        self.assertEqual(order2, strategy.orders()[order2.id])
        self.assertEqual(OrderState.FILLED, strategy.orders()[order1.id].state)
        self.assertEqual(OrderState.FILLED, strategy.orders()[order2.id].state)
        self.assertEqual(MarketPosition.FLAT,
                         strategy.positions()[position_id1].market_position)
        self.assertEqual(MarketPosition.FLAT,
                         strategy.positions()[position_id2].market_position)
        self.assertTrue(strategy.positions()[position_id1].is_closed)
        self.assertTrue(strategy.positions()[position_id2].is_closed)
        self.assertTrue(position_id1 in strategy.positions_closed())
        self.assertTrue(position_id2 in strategy.positions_closed())
        self.assertTrue(strategy.is_flat())
    def test_flatten_position(self):
        # Arrange
        strategy = TradingStrategy()
        strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        order = strategy.order_factory.market(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        strategy.submit_order(order)
        self.exchange.process(0)

        position = self.cache.positions_open()[0]

        # Act
        strategy.flatten_position(position)
        self.exchange.process(0)

        # Assert
        assert order.status == OrderStatus.FILLED
        assert strategy.portfolio.is_completely_flat()
    def test_cancel_order(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag="001")
        strategy.register_trader(
            TraderId("TESTER", "000"),
            clock=self.clock,
            uuid_factory=self.uuid_factory,
            logger=self.logger,
        )
        self.exec_engine.register_strategy(strategy)

        order = strategy.order_factory.stop(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
            Price("90.005"),
        )

        strategy.submit_order(order)

        # Act
        strategy.cancel_order(order)

        # Assert
        self.assertTrue(order in strategy.execution.orders())
        self.assertEqual(OrderState.CANCELLED, strategy.execution.orders()[0].state())
        self.assertEqual(order.cl_ord_id, strategy.execution.orders_completed()[0].cl_ord_id)
        self.assertTrue(order.cl_ord_id not in strategy.execution.orders_working())
        self.assertTrue(strategy.execution.order_exists(order.cl_ord_id))
        self.assertFalse(strategy.execution.is_order_working(order.cl_ord_id))
        self.assertTrue(strategy.execution.is_order_completed(order.cl_ord_id))
Beispiel #6
0
    def test_can_cancel_all_orders(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag='001')
        self.exec_engine.register_strategy(strategy)

        order1 = strategy.order_factory.stop(USDJPY_FXCM, OrderSide.BUY,
                                             Quantity(100000),
                                             Price(90.003, 3))

        order2 = strategy.order_factory.stop(USDJPY_FXCM, OrderSide.BUY,
                                             Quantity(100000),
                                             Price(90.005, 3))

        position_id = strategy.position_id_generator.generate()

        strategy.submit_order(order1, position_id)
        strategy.submit_order(order2, position_id)

        # Act
        strategy.cancel_all_orders()

        # Assert
        self.assertEqual(order1, strategy.orders()[order1.id])
        self.assertEqual(order2, strategy.orders()[order2.id])
        self.assertEqual(OrderState.CANCELLED,
                         strategy.orders()[order1.id].state)
        self.assertEqual(OrderState.CANCELLED,
                         strategy.orders()[order2.id].state)
        self.assertTrue(order1.id in strategy.orders_completed())
        self.assertTrue(order2.id in strategy.orders_completed())
    def test_modify_order(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag="001")
        strategy.register_trader(
            TraderId("TESTER", "000"),
            clock=self.clock,
            uuid_factory=self.uuid_factory,
            logger=self.logger)
        self.exec_engine.register_strategy(strategy)

        order = strategy.order_factory.limit(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
            Price("90.001"),
        )

        strategy.submit_order(order)

        # Act
        strategy.modify_order(order, Quantity(110000), Price("90.002"))

        # Assert
        self.assertEqual(order, strategy.execution.orders()[0])
        self.assertEqual(OrderState.WORKING, strategy.execution.orders()[0].state())
        self.assertEqual(Quantity(110000), strategy.execution.orders()[0].quantity)
        self.assertEqual(Price("90.002"), strategy.execution.orders()[0].price)
        self.assertTrue(strategy.execution.is_flat())
        self.assertTrue(strategy.execution.order_exists(order.cl_ord_id))
        self.assertTrue(strategy.execution.is_order_working(order.cl_ord_id))
        self.assertFalse(strategy.execution.is_order_completed(order.cl_ord_id))
    def test_modify_order_when_no_changes_does_not_submit_command(self):
        # Arrange
        strategy = TradingStrategy()
        strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        order = strategy.order_factory.limit(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("90.001"),
        )

        strategy.submit_order(order)

        # Act
        strategy.modify_order(
            order=order,
            quantity=Quantity.from_int(100000),
            price=Price.from_str("90.001"),
        )

        # Assert
        assert self.exec_engine.command_count == 1
    def test_flatten_all_positions(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag="001")
        strategy.register_trader(
            TraderId("TESTER", "000"),
            clock=self.clock,
            uuid_factory=self.uuid_factory,
            logger=self.logger,
        )
        self.exec_engine.register_strategy(strategy)

        order1 = strategy.order_factory.market(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
        )

        order2 = strategy.order_factory.market(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
        )

        strategy.submit_order(order1)
        strategy.submit_order(order2)

        filled1 = TestStubs.event_order_filled(
            order1,
            position_id=PositionId("B-USD/JPY-1"),
            strategy_id=strategy.id,
        )

        filled2 = TestStubs.event_order_filled(
            order2,
            position_id=PositionId("B-USD/JPY-2"),
            strategy_id=strategy.id,
        )

        position1 = Position(filled1)
        position2 = Position(filled2)

        # Act
        strategy.flatten_all_positions(USDJPY_FXCM)

        # Assert
        self.assertTrue(order1 in strategy.execution.orders())
        self.assertTrue(order2 in strategy.execution.orders())
        self.assertEqual(OrderState.FILLED, strategy.execution.orders()[0].state())
        self.assertEqual(OrderState.FILLED, strategy.execution.orders()[1].state())
        self.assertEqual(PositionSide.FLAT, strategy.execution.positions()[0].side)
        self.assertEqual(PositionSide.FLAT, strategy.execution.positions()[1].side)
        self.assertTrue(position1.id in strategy.execution.position_closed_ids())
        self.assertTrue(position2.id in strategy.execution.position_closed_ids())
        self.assertTrue(strategy.execution.is_completely_flat())
Beispiel #10
0
    def test_can_get_order(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag='001')
        self.exec_engine.register_strategy(strategy)

        order = strategy.order_factory.market(USDJPY_FXCM, OrderSide.BUY,
                                              Quantity(100000))

        strategy.submit_order(order, strategy.position_id_generator.generate())

        # Act
        result = strategy.order(order.id)

        # Assert
        self.assertTrue(strategy.order_exists(order.id))
        self.assertEqual(order, result)
Beispiel #11
0
    def test_strategy_can_submit_order(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag='001')
        self.exec_engine.register_strategy(strategy)

        order = strategy.order_factory.market(USDJPY_FXCM, OrderSide.BUY,
                                              Quantity(100000))

        # Act
        strategy.submit_order(order, strategy.position_id_generator.generate())

        # Assert
        self.assertEqual(order, strategy.orders()[order.id])
        self.assertEqual(OrderState.FILLED, strategy.orders()[order.id].state)
        self.assertTrue(order.id not in strategy.orders_working())
        self.assertTrue(order.id in strategy.orders_completed())
        self.assertTrue(strategy.order_exists(order.id))
        self.assertFalse(strategy.is_order_working(order.id))
        self.assertTrue(strategy.is_order_completed(order.id))
    def test_cancel_all_orders(self):
        # Arrange
        strategy = TradingStrategy()
        strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        order1 = strategy.order_factory.stop_market(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("90.007"),
        )

        order2 = strategy.order_factory.stop_market(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("90.006"),
        )

        strategy.submit_order(order1)
        self.exchange.process(0)
        strategy.submit_order(order2)
        self.exchange.process(0)

        # Act
        strategy.cancel_all_orders(USDJPY_SIM.id)
        self.exchange.process(0)

        # Assert
        assert order1 in self.cache.orders()
        assert order2 in self.cache.orders()
        assert self.cache.orders()[0].status == OrderStatus.CANCELED
        assert self.cache.orders()[1].status == OrderStatus.CANCELED
        assert order1 in self.cache.orders_completed()
        assert order2 in strategy.cache.orders_completed()
    def test_modify_order(self):
        # Arrange
        strategy = TradingStrategy()
        strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        order = strategy.order_factory.limit(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("90.000"),
        )

        strategy.submit_order(order)
        self.exchange.process(0)

        # Act
        strategy.modify_order(
            order=order,
            quantity=Quantity.from_int(110000),
            price=Price.from_str("90.001"),
        )
        self.exchange.process(0)

        # Assert
        assert strategy.cache.orders()[0] == order
        assert strategy.cache.orders()[0].status == OrderStatus.ACCEPTED
        assert strategy.cache.orders()[0].quantity == Quantity.from_int(110000)
        assert strategy.cache.orders()[0].price == Price.from_str("90.001")
        assert strategy.cache.order_exists(order.client_order_id)
        assert strategy.cache.is_order_working(order.client_order_id)
        assert not strategy.cache.is_order_completed(order.client_order_id)
        assert strategy.portfolio.is_flat(order.instrument_id)
    def test_flatten_position_when_position_already_flat_does_nothing(self):
        # Arrange
        strategy = TradingStrategy()
        strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        order1 = strategy.order_factory.market(
            USDJPY_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order2 = strategy.order_factory.market(
            USDJPY_SIM.id,
            OrderSide.SELL,
            Quantity.from_int(100000),
        )

        strategy.submit_order(order1)
        self.exchange.process(0)
        strategy.submit_order(order2,
                              PositionId("1-001"))  # Generated by exchange
        self.exchange.process(0)

        position = strategy.cache.positions_closed()[0]

        # Act
        strategy.flatten_position(position)
        self.exchange.process(0)

        # Assert
        assert strategy.portfolio.is_completely_flat()
    def test_cancel_all_orders(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag="001")
        strategy.register_trader(
            TraderId("TESTER", "000"),
            clock=self.clock,
            uuid_factory=self.uuid_factory,
            logger=self.logger)
        self.exec_engine.register_strategy(strategy)

        order1 = strategy.order_factory.stop(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
            Price("90.003"),
        )

        order2 = strategy.order_factory.stop(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
            Price("90.005"),
        )

        strategy.submit_order(order1)
        strategy.submit_order(order2)

        # Act
        strategy.cancel_all_orders(USDJPY_FXCM)

        # Assert
        self.assertTrue(order1 in strategy.execution.orders())
        self.assertTrue(order2 in strategy.execution.orders())
        self.assertEqual(OrderState.CANCELLED, strategy.execution.orders()[0].state())
        self.assertEqual(OrderState.CANCELLED, strategy.execution.orders()[1].state())
        self.assertTrue(order1 in strategy.execution.orders_completed())
        self.assertTrue(order2 in strategy.execution.orders_completed())
Beispiel #16
0
    def test_can_modify_order(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag='001')
        self.exec_engine.register_strategy(strategy)

        order = strategy.order_factory.limit(USDJPY_FXCM, OrderSide.BUY,
                                             Quantity(100000),
                                             Price(90.001, 3))

        strategy.submit_order(order, strategy.position_id_generator.generate())

        # Act
        strategy.modify_order(order, Quantity(110000), Price(90.002, 3))

        # Assert
        self.assertEqual(order, strategy.orders()[order.id])
        self.assertEqual(OrderState.WORKING, strategy.orders()[order.id].state)
        self.assertEqual(Quantity(110000),
                         strategy.orders()[order.id].quantity)
        self.assertEqual(Price(90.002, 3), strategy.orders()[order.id].price)
        self.assertTrue(strategy.is_flat())
        self.assertTrue(strategy.order_exists(order.id))
        self.assertTrue(strategy.is_order_working(order.id))
        self.assertFalse(strategy.is_order_completed(order.id))
class TestLiveExecutionPerformance(PerformanceHarness):
    def setup(self):
        # Fixture Setup
        self.clock = LiveClock()
        self.uuid_factory = UUIDFactory()
        self.trader_id = TraderId("TESTER", "000")
        self.logger = Logger(self.clock, bypass_logging=True)

        self.account_id = AccountId("BINANCE", "001")

        self.portfolio = Portfolio(
            clock=self.clock,
            logger=self.logger,
        )
        self.portfolio.register_cache(DataCache(self.logger))

        self.analyzer = PerformanceAnalyzer()

        # Fresh isolated loop testing pattern
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        database = BypassExecutionDatabase(trader_id=self.trader_id, logger=self.logger)
        self.exec_engine = LiveExecutionEngine(
            loop=self.loop,
            database=database,
            portfolio=self.portfolio,
            clock=self.clock,
            logger=self.logger,
        )

        exec_client = MockExecutionClient(
            client_id=ClientId("BINANCE"),
            account_id=self.account_id,
            engine=self.exec_engine,
            clock=self.clock,
            logger=self.logger,
        )

        self.exec_engine.register_client(exec_client)
        self.exec_engine.process(TestStubs.event_account_state(self.account_id))

        self.strategy = TradingStrategy(order_id_tag="001")
        self.strategy.register_trader(
            TraderId("TESTER", "000"),
            self.clock,
            self.logger,
        )

        self.exec_engine.register_strategy(self.strategy)

    @pytest.fixture(autouse=True)
    @pytest.mark.benchmark(disable_gc=True, warmup=True)
    def setup_benchmark(self, benchmark):
        self.benchmark = benchmark

    def submit_order(self):
        order = self.strategy.order_factory.market(
            BTCUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity("1.00000000"),
        )

        self.strategy.submit_order(order)

    def test_execute_command(self):
        order = self.strategy.order_factory.market(
            BTCUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity("1.00000000"),
        )

        command = SubmitOrder(
            order.instrument_id.venue.client_id,
            self.trader_id,
            self.account_id,
            self.strategy.id,
            PositionId.null(),
            order,
            self.uuid_factory.generate(),
            self.clock.timestamp_ns(),
        )

        def execute_command():
            self.exec_engine.execute(command)

        self.benchmark.pedantic(execute_command, iterations=10_000, rounds=1)
        # ~0.0ms / ~0.2μs / 218ns minimum of 10,000 runs @ 1 iteration each run.

    def test_submit_order(self):
        self.exec_engine.start()
        time.sleep(0.1)

        async def run_test():
            def submit_order():
                order = self.strategy.order_factory.market(
                    BTCUSDT_BINANCE.id,
                    OrderSide.BUY,
                    Quantity("1.00000000"),
                )

                self.strategy.submit_order(order)

            self.benchmark.pedantic(submit_order, iterations=10_000, rounds=1)

        self.loop.run_until_complete(run_test())
        # ~0.0ms / ~25.3μs / 25326ns minimum of 10,000 runs @ 1 iteration each run.

    def test_submit_order_end_to_end(self):
        self.exec_engine.start()
        time.sleep(0.1)

        async def run_test():
            for _ in range(10000):
                order = self.strategy.order_factory.market(
                    BTCUSDT_BINANCE.id,
                    OrderSide.BUY,
                    Quantity("1.00000000"),
                )

                self.strategy.submit_order(order)

        stats_file = "perf_live_execution.prof"
        cProfile.runctx(
            "self.loop.run_until_complete(run_test())", globals(), locals(), stats_file
        )
        s = pstats.Stats(stats_file)
        s.strip_dirs().sort_stats("time").print_stats()
Beispiel #18
0
class LiveExecutionPerformanceTests(unittest.TestCase):

    def setUp(self):
        # Fixture Setup
        self.clock = LiveClock()
        self.uuid_factory = UUIDFactory()
        self.logger = TestLogger(self.clock, bypass_logging=True)

        self.trader_id = TraderId("TESTER", "000")
        self.account_id = AccountId("BINANCE", "001")

        self.portfolio = Portfolio(
            clock=self.clock,
            logger=self.logger,
        )
        self.portfolio.register_cache(DataCache(self.logger))

        self.analyzer = PerformanceAnalyzer()

        # Fresh isolated loop testing pattern
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        database = BypassExecutionDatabase(trader_id=self.trader_id, logger=self.logger)
        self.exec_engine = LiveExecutionEngine(
            loop=self.loop,
            database=database,
            portfolio=self.portfolio,
            clock=self.clock,
            logger=self.logger,
        )

        exec_client = MockExecutionClient(
            venue=Venue("BINANCE"),
            account_id=self.account_id,
            exec_engine=self.exec_engine,
            clock=self.clock,
            logger=self.logger,
        )

        self.exec_engine.register_client(exec_client)
        self.exec_engine.process(TestStubs.event_account_state(self.account_id))

        self.strategy = TradingStrategy(order_id_tag="001")
        self.strategy.register_trader(
            TraderId("TESTER", "000"),
            self.clock,
            self.logger,
        )

        self.exec_engine.register_strategy(self.strategy)

    def submit_order(self):
        order = self.strategy.order_factory.market(
            BTCUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity("1.00000000"),
        )

        self.strategy.submit_order(order)

    def test_execute_command(self):
        order = self.strategy.order_factory.market(
            BTCUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity("1.00000000"),
        )

        command = SubmitOrder(
            order.symbol.venue,
            self.trader_id,
            self.account_id,
            self.strategy.id,
            PositionId.null(),
            order,
            self.uuid_factory.generate(),
            self.clock.utc_now(),
        )

        def execute_command():
            self.exec_engine.execute(command)

        PerformanceHarness.profile_function(execute_command, 10000, 1)
        # ~0.0ms / ~0.3μs / 253ns minimum of 10,000 runs @ 1 iteration each run.

    def test_submit_order(self):
        self.exec_engine.start()
        time.sleep(0.1)

        async def run_test():
            def submit_order():
                order = self.strategy.order_factory.market(
                    BTCUSDT_BINANCE.symbol,
                    OrderSide.BUY,
                    Quantity("1.00000000"),
                )

                self.strategy.submit_order(order)

            PerformanceHarness.profile_function(submit_order, 10000, 1)
        self.loop.run_until_complete(run_test())
        # ~0.0ms / ~24.5μs / 24455ns minimum of 10,000 runs @ 1 iteration each run.

    def test_submit_order_end_to_end(self):
        self.exec_engine.start()
        time.sleep(0.1)

        async def run_test():
            for _ in range(10000):
                order = self.strategy.order_factory.market(
                    BTCUSDT_BINANCE.symbol,
                    OrderSide.BUY,
                    Quantity("1.00000000"),
                )

                self.strategy.submit_order(order)

        stats_file = "perf_live_execution.prof"
        cProfile.runctx("self.loop.run_until_complete(run_test())", globals(), locals(), stats_file)
        s = pstats.Stats(stats_file)
        s.strip_dirs().sort_stats("time").print_stats()
Beispiel #19
0
class TestLiveExecutionPerformance(PerformanceHarness):
    def setup(self):
        # Fixture Setup
        self.loop = asyncio.get_event_loop()
        self.loop.set_debug(True)

        self.clock = LiveClock()
        self.uuid_factory = UUIDFactory()
        self.logger = Logger(self.clock, bypass=True)

        self.trader_id = TestIdStubs.trader_id()
        self.account_id = AccountId(BINANCE.value, "001")

        self.msgbus = MessageBus(
            trader_id=self.trader_id,
            clock=self.clock,
            logger=self.logger,
        )

        self.cache = TestComponentStubs.cache()

        self.portfolio = Portfolio(
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        self.data_engine = LiveDataEngine(
            loop=self.loop,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        self.exec_engine = LiveExecutionEngine(
            loop=self.loop,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        self.risk_engine = LiveRiskEngine(
            loop=self.loop,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

        self.exec_client = MockExecutionClient(
            client_id=ClientId("BINANCE"),
            venue=BINANCE,
            account_type=AccountType.CASH,
            base_currency=None,  # Multi-currency account
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )
        self.portfolio.update_account(TestEventStubs.margin_account_state())
        self.exec_engine.register_client(self.exec_client)

        self.strategy = TradingStrategy()
        self.strategy.register(
            trader_id=self.trader_id,
            portfolio=self.portfolio,
            msgbus=self.msgbus,
            cache=self.cache,
            clock=self.clock,
            logger=self.logger,
        )

    @pytest.fixture(autouse=True)
    @pytest.mark.benchmark(disable_gc=True, warmup=True)
    def setup_benchmark(self, benchmark):
        self.benchmark = benchmark

    def submit_order(self):
        order = self.strategy.order_factory.market(
            BTCUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_str("1.00000000"),
        )

        self.strategy.submit_order(order)

    @pytest.mark.skip(reason="For development only, event loop issue")
    def test_execute_command(self):
        order = self.strategy.order_factory.market(
            BTCUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_str("1.00000000"),
        )

        command = SubmitOrder(
            None,
            self.trader_id,
            self.strategy.id,
            None,
            order,
            self.uuid_factory.generate(),
            self.clock.timestamp_ns(),
        )

        def execute_command():
            self.exec_engine.execute(command)

        self.benchmark.pedantic(execute_command, iterations=100, rounds=100, warmup_rounds=5)
        # ~0.0ms / ~0.2μs / 218ns minimum of 10,000 runs @ 1 iteration each run.

    @pytest.mark.asyncio
    async def test_submit_order(self):
        self.exec_engine.start()
        await asyncio.sleep(1)

        def submit_order():
            order = self.strategy.order_factory.market(
                BTCUSDT_BINANCE.id,
                OrderSide.BUY,
                Quantity.from_str("1.00000000"),
            )

            self.strategy.submit_order(order)

        self.benchmark.pedantic(submit_order, iterations=100, rounds=100, warmup_rounds=5)
        # ~0.0ms / ~25.3μs / 25326ns minimum of 10,000 runs @ 1 iteration each run.

    @pytest.mark.asyncio
    async def test_submit_order_end_to_end(self):
        self.exec_engine.start()
        await asyncio.sleep(1)

        def run():
            for _ in range(1000):
                order = self.strategy.order_factory.market(
                    BTCUSDT_BINANCE.id,
                    OrderSide.BUY,
                    Quantity.from_str("1.00000000"),
                )

                self.strategy.submit_order(order)

        self.benchmark.pedantic(run, rounds=10, warmup_rounds=5)