Ejemplo n.º 1
0
class TestOrders:
    def setup(self):
        # Fixture Setup
        self.trader_id = TestStubs.trader_id()
        self.strategy_id = TestStubs.strategy_id()
        self.account_id = TestStubs.account_id()

        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=self.strategy_id,
            clock=TestClock(),
        )

    def test_opposite_side_given_invalid_value_raises_value_error(self):
        # Arrange, Act, Assert
        with pytest.raises(ValueError):
            Order.opposite_side(0)  # <-- invalid value

    def test_flatten_side_given_invalid_value_or_flat_raises_value_error(self):
        # Arrange, Act
        with pytest.raises(ValueError):
            Order.flatten_side(0)  # <-- invalid value

        with pytest.raises(ValueError):
            Order.flatten_side(PositionSide.FLAT)

    @pytest.mark.parametrize(
        "side, expected",
        [
            [OrderSide.BUY, OrderSide.SELL],
            [OrderSide.SELL, OrderSide.BUY],
        ],
    )
    def test_opposite_side_returns_expected_sides(self, side, expected):
        # Arrange, Act
        result = Order.opposite_side(side)

        # Assert
        assert result == expected

    @pytest.mark.parametrize(
        "side, expected",
        [
            [PositionSide.LONG, OrderSide.SELL],
            [PositionSide.SHORT, OrderSide.BUY],
        ],
    )
    def test_flatten_side_returns_expected_sides(self, side, expected):
        # Arrange, Act
        result = Order.flatten_side(side)

        # Assert
        assert result == expected

    def test_market_order_with_quantity_zero_raises_value_error(self):
        # Arrange, Act, Assert
        with pytest.raises(ValueError):
            MarketOrder(
                self.trader_id,
                self.strategy_id,
                AUDUSD_SIM.id,
                ClientOrderId("O-123456"),
                OrderSide.BUY,
                Quantity.zero(),
                TimeInForce.DAY,
                UUID4(),
                0,
            )

    def test_market_order_with_invalid_tif_raises_value_error(self):
        # Arrange, Act, Assert
        with pytest.raises(ValueError):
            MarketOrder(
                self.trader_id,
                self.strategy_id,
                AUDUSD_SIM.id,
                ClientOrderId("O-123456"),
                OrderSide.BUY,
                Quantity.zero(),
                TimeInForce.GTD,  # <-- invalid
                UUID4(),
                0,
            )

    def test_stop_market_order_with_gtd_and_expire_time_none_raises_type_error(
            self):
        # Arrange, Act, Assert
        with pytest.raises(TypeError):
            StopMarketOrder(
                self.trader_id,
                self.strategy_id,
                AUDUSD_SIM.id,
                ClientOrderId("O-123456"),
                OrderSide.BUY,
                Quantity.from_int(100000),
                price=Price.from_str("1.00000"),
                init_id=UUID4(),
                ts_init=0,
                time_in_force=TimeInForce.GTD,
                expire_time=None,
            )

    def test_stop_limit_buy_order_with_gtd_and_expire_time_none_raises_type_error(
            self):
        # Arrange, Act, Assert
        with pytest.raises(TypeError):
            StopLimitOrder(
                self.trader_id,
                self.strategy_id,
                AUDUSD_SIM.id,
                ClientOrderId("O-123456"),
                OrderSide.BUY,
                Quantity.from_int(100000),
                price=Price.from_str("1.00001"),
                trigger=Price.from_str("1.00000"),
                init_id=UUID4(),
                ts_init=0,
                time_in_force=TimeInForce.GTD,
                expire_time=None,
            )

    def test_overfill_limit_buy_order_raises_value_error(self):
        # Arrange, Act, Assert
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))
        over_fill = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            last_qty=Quantity.from_int(110000)  # <-- overfill
        )

        # Assert
        with pytest.raises(ValueError):
            order.apply(over_fill)

    def test_reset_order_factory(self):
        # Arrange
        self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        # Act
        self.order_factory.reset()

        order2 = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        assert order2.client_order_id.value == "O-19700101-000000-000-001-1"

    def test_initialize_buy_market_order(self):
        # Arrange, Act
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        # Assert
        assert order.symbol == AUDUSD_SIM.id.symbol
        assert order.venue == AUDUSD_SIM.id.venue
        assert order.type == OrderType.MARKET
        assert order.status == OrderStatus.INITIALIZED
        assert order.event_count == 1
        assert isinstance(order.last_event, OrderInitialized)
        assert order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert not order.is_completed
        assert order.is_buy
        assert order.is_aggressive
        assert not order.is_sell
        assert not order.is_contingency
        assert not order.is_passive
        assert not order.is_parent_order
        assert not order.is_child_order
        assert order.ts_last == 0
        assert order.last_event.ts_init == 0
        assert isinstance(order.init_event, OrderInitialized)

    def test_initialize_sell_market_order(self):
        # Arrange, Act
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.SELL,
            Quantity.from_int(100000),
        )

        # Assert
        assert order.type == OrderType.MARKET
        assert order.status == OrderStatus.INITIALIZED
        assert order.event_count == 1
        assert isinstance(order.last_event, OrderInitialized)
        assert len(order.events) == 1
        assert order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert not order.is_completed
        assert not order.is_buy
        assert order.is_sell
        assert order.ts_last == 0
        assert isinstance(order.init_event, OrderInitialized)

    def test_order_equality(self):
        # Arrange, Act
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        # Assert
        assert order == order

    def test_order_hash_str_and_repr(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            tags="ENTRY",
        )

        # Act, Assert
        assert isinstance(hash(order), int)
        assert (
            str(order) ==
            "MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=ENTRY)"  # noqa
        )
        assert (
            repr(order) ==
            "MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=ENTRY)"  # noqa
        )

    def test_market_order_to_dict(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        # Act
        result = order.to_dict()

        # Assert
        assert result == {
            "trader_id": "TESTER-000",
            "strategy_id": "S-001",
            "instrument_id": "AUD/USD.SIM",
            "client_order_id": "O-19700101-000000-000-001-1",
            "venue_order_id": None,
            "position_id": None,
            "account_id": None,
            "execution_id": None,
            "type": "MARKET",
            "side": "BUY",
            "quantity": "100000",
            "time_in_force": "GTC",
            "reduce_only": False,
            "filled_qty": "0",
            "avg_px": None,
            "slippage": "0",
            "status": "INITIALIZED",
            "order_list_id": None,
            "parent_order_id": None,
            "child_order_ids": None,
            "contingency": "NONE",
            "contingency_ids": None,
            "tags": None,
            "ts_last": 0,
            "ts_init": 0,
        }

    def test_initialize_limit_order(self):
        # Arrange, Act
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        # Assert
        assert order.type == OrderType.LIMIT
        assert order.status == OrderStatus.INITIALIZED
        assert order.time_in_force == TimeInForce.GTC
        assert order.is_passive
        assert order.is_active
        assert not order.is_aggressive
        assert not order.is_completed
        assert isinstance(order.init_event, OrderInitialized)
        assert (
            str(order) ==
            "LimitOrder(BUY 100_000 AUD/USD.SIM LIMIT @ 1.00000 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=None)"  # noqa
        )
        assert (
            repr(order) ==
            "LimitOrder(BUY 100_000 AUD/USD.SIM LIMIT @ 1.00000 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=None)"  # noqa
        )

    def test_limit_order_to_dict(self):
        # Arrange
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
            display_qty=Quantity.from_int(20000),
        )

        # Act
        result = order.to_dict()

        # Assert
        assert result == {
            "trader_id": "TESTER-000",
            "strategy_id": "S-001",
            "instrument_id": "AUD/USD.SIM",
            "client_order_id": "O-19700101-000000-000-001-1",
            "venue_order_id": None,
            "position_id": None,
            "account_id": None,
            "execution_id": None,
            "type": "LIMIT",
            "side": "BUY",
            "quantity": "100000",
            "price": "1.00000",
            "liquidity_side": "NONE",
            "expire_time_ns": 0,
            "time_in_force": "GTC",
            "filled_qty": "0",
            "avg_px": None,
            "slippage": "0",
            "status": "INITIALIZED",
            "is_post_only": False,
            "is_reduce_only": False,
            "display_qty": "20000",
            "order_list_id": None,
            "parent_order_id": None,
            "child_order_ids": None,
            "contingency": "NONE",
            "contingency_ids": None,
            "tags": None,
            "ts_last": 0,
            "ts_init": 0,
        }

    def test_initialize_limit_order_with_expire_time(self):
        # Arrange, Act
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
            TimeInForce.GTD,
            expire_time=UNIX_EPOCH,
        )

        # Assert
        assert order.instrument_id == AUDUSD_SIM.id
        assert order.type == OrderType.LIMIT
        assert order.price == Price.from_str("1.00000")
        assert order.status == OrderStatus.INITIALIZED
        assert order.time_in_force == TimeInForce.GTD
        assert order.expire_time == UNIX_EPOCH
        assert not order.is_completed
        assert isinstance(order.init_event, OrderInitialized)

    def test_initialize_stop_market_order(self):
        # Arrange, Act
        order = self.order_factory.stop_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        # Assert
        assert order.type == OrderType.STOP_MARKET
        assert order.status == OrderStatus.INITIALIZED
        assert order.time_in_force == TimeInForce.GTC
        assert order.is_passive
        assert not order.is_aggressive
        assert order.is_active
        assert not order.is_completed
        assert isinstance(order.init_event, OrderInitialized)
        assert (
            str(order) ==
            "StopMarketOrder(BUY 100_000 AUD/USD.SIM STOP_MARKET @ 1.00000 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=None)"  # noqa
        )
        assert (
            repr(order) ==
            "StopMarketOrder(BUY 100_000 AUD/USD.SIM STOP_MARKET @ 1.00000 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=None)"  # noqa
        )

    def test_stop_market_order_to_dict(self):
        # Arrange
        order = self.order_factory.stop_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        # Act
        result = order.to_dict()

        # Assert
        assert result == {
            "trader_id": "TESTER-000",
            "strategy_id": "S-001",
            "instrument_id": "AUD/USD.SIM",
            "client_order_id": "O-19700101-000000-000-001-1",
            "venue_order_id": None,
            "position_id": None,
            "account_id": None,
            "execution_id": None,
            "type": "STOP_MARKET",
            "side": "BUY",
            "quantity": "100000",
            "price": "1.00000",
            "liquidity_side": "NONE",
            "expire_time_ns": 0,
            "time_in_force": "GTC",
            "filled_qty": "0",
            "avg_px": None,
            "slippage": "0",
            "status": "INITIALIZED",
            "is_reduce_only": False,
            "order_list_id": None,
            "parent_order_id": None,
            "child_order_ids": None,
            "contingency": "NONE",
            "contingency_ids": None,
            "tags": None,
            "ts_last": 0,
            "ts_init": 0,
        }

    def test_initialize_stop_limit_order(self):
        # Arrange, Act
        order = self.order_factory.stop_limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
            Price.from_str("1.10010"),
            tags="ENTRY",
        )

        # Assert
        assert order.type == OrderType.STOP_LIMIT
        assert order.status == OrderStatus.INITIALIZED
        assert order.time_in_force == TimeInForce.GTC
        assert order.is_passive
        assert not order.is_aggressive
        assert not order.is_completed
        assert isinstance(order.init_event, OrderInitialized)
        assert (
            str(order) ==
            "StopLimitOrder(BUY 100_000 AUD/USD.SIM STOP_LIMIT @ 1.00000 GTC, trigger=1.10010, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1)"  # noqa
        )
        assert (
            repr(order) ==
            "StopLimitOrder(BUY 100_000 AUD/USD.SIM STOP_LIMIT @ 1.00000 GTC, trigger=1.10010, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1)"  # noqa
        )

    def test_stop_limit_order_to_dict(self):
        # Arrange
        order = self.order_factory.stop_limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
            Price.from_str("1.10010"),
            tags="STOP_LOSS",
        )

        # Act
        result = order.to_dict()

        # Assert
        assert result == {
            "trader_id": "TESTER-000",
            "strategy_id": "S-001",
            "instrument_id": "AUD/USD.SIM",
            "client_order_id": "O-19700101-000000-000-001-1",
            "venue_order_id": None,
            "position_id": None,
            "account_id": None,
            "execution_id": None,
            "type": "STOP_LIMIT",
            "side": "BUY",
            "quantity": "100000",
            "trigger": "1.10010",
            "price": "1.00000",
            "liquidity_side": "NONE",
            "expire_time_ns": 0,
            "time_in_force": "GTC",
            "filled_qty": "0",
            "avg_px": None,
            "slippage": "0",
            "status": "INITIALIZED",
            "is_post_only": False,
            "is_reduce_only": False,
            "display_qty": None,
            "order_list_id": None,
            "parent_order_id": None,
            "child_order_ids": None,
            "contingency": "NONE",
            "contingency_ids": None,
            "tags": "STOP_LOSS",
            "ts_last": 0,
            "ts_init": 0,
        }

    def test_order_list_equality(self):
        # Arrange
        bracket1 = self.order_factory.bracket_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
            Price.from_str("1.00010"),
        )
        bracket2 = self.order_factory.bracket_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
            Price.from_str("1.00010"),
        )

        # Act, Assert
        assert bracket1 == bracket1
        assert bracket1 != bracket2

    def test_bracket_market_order_list(self):
        # Arrange, Act
        bracket = self.order_factory.bracket_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            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.MARKET
        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

    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

    def test_order_list_str_and_repr(self):
        # Arrange, Act
        bracket = self.order_factory.bracket_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("0.99990"),
            Price.from_str("1.00010"),
        )

        # Assert
        assert str(bracket) == (
            "OrderList(id=1, instrument_id=AUD/USD.SIM, orders=[MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=ENTRY), StopMarketOrder(SELL 100_000 AUD/USD.SIM STOP_MARKET @ 0.99990 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-2, venue_order_id=None, tags=STOP_LOSS), LimitOrder(SELL 100_000 AUD/USD.SIM LIMIT @ 1.00010 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-3, venue_order_id=None, tags=TAKE_PROFIT)])"  # noqa
        )
        assert repr(bracket) == (
            "OrderList(id=1, instrument_id=AUD/USD.SIM, orders=[MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=ENTRY), StopMarketOrder(SELL 100_000 AUD/USD.SIM STOP_MARKET @ 0.99990 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-2, venue_order_id=None, tags=STOP_LOSS), LimitOrder(SELL 100_000 AUD/USD.SIM LIMIT @ 1.00010 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-3, venue_order_id=None, tags=TAKE_PROFIT)])"  # noqa
        )

    def test_apply_order_denied_event(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        denied = OrderDenied(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            order.client_order_id,
            "SOME_REASON",
            UUID4(),
            0,
        )

        # Act
        order.apply(denied)

        # Assert
        assert order.status == OrderStatus.DENIED
        assert order.event_count == 2
        assert order.last_event == denied
        assert not order.is_active
        assert order.is_completed

    def test_apply_order_submitted_event(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        submitted = TestStubs.event_order_submitted(order)

        # Act
        order.apply(submitted)

        # Assert
        assert order.status == OrderStatus.SUBMITTED
        assert order.event_count == 2
        assert order.last_event == submitted
        assert order.is_active
        assert order.is_inflight
        assert not order.is_working
        assert not order.is_completed
        assert not order.is_pending_update
        assert not order.is_pending_cancel

    def test_apply_order_accepted_event(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))

        # Act
        order.apply(TestStubs.event_order_accepted(order))

        # Assert
        assert order.status == OrderStatus.ACCEPTED
        assert order.is_active
        assert not order.is_inflight
        assert order.is_working
        assert not order.is_completed
        assert (
            str(order) ==
            "MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=ACCEPTED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=1, tags=None)"  # noqa
        )
        assert (
            repr(order) ==
            "MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=ACCEPTED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=1, tags=None)"  # noqa
        )

    def test_apply_order_rejected_event(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))

        # Act
        order.apply(TestStubs.event_order_rejected(order))

        # Assert
        assert order.status == OrderStatus.REJECTED
        assert not order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert order.is_completed

    def test_apply_order_expired_event(self):
        # Arrange
        order = self.order_factory.stop_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("0.99990"),
            TimeInForce.GTD,
            expire_time=UNIX_EPOCH,
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        # Act
        order.apply(TestStubs.event_order_expired(order))

        # Assert
        assert order.status == OrderStatus.EXPIRED
        assert not order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert order.is_completed

    def test_apply_order_triggered_event(self):
        # Arrange
        order = self.order_factory.stop_limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
            Price.from_str("0.99990"),
            TimeInForce.GTD,
            expire_time=UNIX_EPOCH,
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        # Act
        order.apply(TestStubs.event_order_triggered(order))

        # Assert
        assert order.status == OrderStatus.TRIGGERED
        assert order.is_active
        assert not order.is_inflight
        assert order.is_working
        assert not order.is_completed

    def test_order_status_pending_cancel(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        # Act
        order.apply(TestStubs.event_order_pending_cancel(order))

        # Assert
        assert order.status == OrderStatus.PENDING_CANCEL
        assert order.is_active
        assert order.is_inflight
        assert order.is_working
        assert not order.is_completed
        assert not order.is_pending_update
        assert order.is_pending_cancel
        assert order.event_count == 4

    def test_apply_order_canceled_event(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))
        order.apply(TestStubs.event_order_pending_cancel(order))

        # Act
        order.apply(TestStubs.event_order_canceled(order))

        # Assert
        assert order.status == OrderStatus.CANCELED
        assert not order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert order.is_completed
        assert not order.is_pending_update
        assert not order.is_pending_cancel
        assert order.event_count == 5

    def test_order_status_pending_replace(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        # Act
        order.apply(TestStubs.event_order_pending_update(order))

        # Assert
        assert order.status == OrderStatus.PENDING_UPDATE
        assert order.is_active
        assert order.is_inflight
        assert order.is_working
        assert not order.is_completed
        assert order.is_pending_update
        assert not order.is_pending_cancel
        assert order.event_count == 4

    def test_apply_order_updated_event_to_stop_order(self):
        # Arrange
        order = self.order_factory.stop_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))
        order.apply(TestStubs.event_order_pending_update(order))

        updated = OrderUpdated(
            order.trader_id,
            order.strategy_id,
            order.account_id,
            order.instrument_id,
            order.client_order_id,
            VenueOrderId("1"),
            Quantity.from_int(120000),
            Price.from_str("1.00001"),
            None,
            UUID4(),
            0,
            0,
        )

        # Act
        order.apply(updated)

        # Assert
        assert order.status == OrderStatus.ACCEPTED
        assert order.venue_order_id == VenueOrderId("1")
        assert order.quantity == Quantity.from_int(120000)
        assert order.price == Price.from_str("1.00001")
        assert order.is_active
        assert not order.is_inflight
        assert order.is_working
        assert not order.is_completed
        assert order.event_count == 5

    def test_apply_order_updated_venue_id_change(self):
        # Arrange
        order = self.order_factory.stop_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))
        order.apply(TestStubs.event_order_pending_update(order))

        updated = OrderUpdated(
            order.trader_id,
            order.strategy_id,
            order.account_id,
            order.instrument_id,
            order.client_order_id,
            VenueOrderId("2"),
            Quantity.from_int(120000),
            Price.from_str("1.00001"),
            None,
            UUID4(),
            0,
            0,
        )

        # Act
        order.apply(updated)

        # Assert
        assert order.venue_order_id == VenueOrderId("2")
        assert order.venue_order_ids == [VenueOrderId("1")]

    def test_apply_order_filled_event_to_order_without_accepted(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        filled = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
        )

        # Act
        order.apply(filled)

        # Assert
        assert order.status == OrderStatus.FILLED
        assert order.filled_qty == Quantity.from_int(100000)
        assert order.leaves_qty == Quantity.zero()
        assert order.avg_px == Decimal("1.00001")
        assert len(order.execution_ids) == 1
        assert not order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert order.is_completed
        assert order.ts_last == 0

    def test_apply_order_filled_event_to_market_order(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        filled = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
        )

        # Act
        order.apply(filled)

        # Assert
        assert order.status == OrderStatus.FILLED
        assert order.filled_qty == Quantity.from_int(100000)
        assert order.avg_px == Decimal("1.00001")
        assert len(order.execution_ids) == 1
        assert not order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert order.is_completed
        assert order.ts_last == 0

    def test_apply_partial_fill_events_to_market_order_results_in_partially_filled(
        self, ):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        fill1 = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            execution_id=ExecutionId("1"),
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
            last_qty=Quantity.from_int(20000),
        )

        fill2 = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            execution_id=ExecutionId("2"),
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00002"),
            last_qty=Quantity.from_int(40000),
        )

        # Act
        order.apply(fill1)
        order.apply(fill2)

        # Assert
        assert order.status == OrderStatus.PARTIALLY_FILLED
        assert order.filled_qty == Quantity.from_int(60000)
        assert order.leaves_qty == Quantity.from_int(40000)
        assert order.avg_px == Decimal("1.000014")
        assert len(order.execution_ids) == 2
        assert order.is_active
        assert not order.is_inflight
        assert order.is_working
        assert not order.is_completed
        assert order.ts_last == 0

    def test_apply_filled_events_to_market_order_results_in_filled(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        fill1 = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            execution_id=ExecutionId("1"),
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
            last_qty=Quantity.from_int(20000),
        )

        fill2 = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            execution_id=ExecutionId("2"),
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00002"),
            last_qty=Quantity.from_int(40000),
        )

        fill3 = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            execution_id=ExecutionId("3"),
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00003"),
            last_qty=Quantity.from_int(40000),
        )

        # Act
        order.apply(fill1)
        order.apply(fill2)
        order.apply(fill3)

        # Assert
        assert order.status == OrderStatus.FILLED
        assert order.filled_qty == Quantity.from_int(100000)
        assert order.avg_px == Decimal("1.000018571428571428571428571")
        assert len(order.execution_ids) == 3
        assert not order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert order.is_completed
        assert order.ts_last == 0

    def test_apply_order_filled_event_to_buy_limit_order(self):
        # Arrange
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        filled = OrderFilled(
            order.trader_id,
            order.strategy_id,
            order.account_id,
            order.instrument_id,
            order.client_order_id,
            VenueOrderId("1"),
            ExecutionId("E-1"),
            PositionId("P-1"),
            order.side,
            order.type,
            order.quantity,
            Price.from_str("1.00001"),
            AUDUSD_SIM.quote_currency,
            Money(0, USD),
            LiquiditySide.MAKER,
            UUID4(),
            0,
            0,
        )

        # Act
        order.apply(filled)

        # Assert
        assert order.status == OrderStatus.FILLED
        assert order.filled_qty == Quantity.from_int(100000)
        assert order.price == Price.from_str("1.00000")
        assert order.avg_px == Decimal("1.00001")
        assert order.slippage == Decimal("0.00001")
        assert not order.is_active
        assert not order.is_inflight
        assert not order.is_working
        assert order.is_completed
        assert order.ts_last == 0

    def test_apply_order_partially_filled_event_to_buy_limit_order(self):
        # Arrange
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        order.apply(TestStubs.event_order_submitted(order))
        order.apply(TestStubs.event_order_accepted(order))

        partially = OrderFilled(
            order.trader_id,
            order.strategy_id,
            order.account_id,
            order.instrument_id,
            order.client_order_id,
            VenueOrderId("1"),
            ExecutionId("E-1"),
            PositionId("P-1"),
            order.side,
            order.type,
            Quantity.from_int(50000),
            Price.from_str("0.999999"),
            AUDUSD_SIM.quote_currency,
            Money(0, USD),
            LiquiditySide.MAKER,
            UUID4(),
            1_000_000_000,
            1_000_000_000,
        )

        # Act
        order.apply(partially)

        # Assert
        assert order.status == OrderStatus.PARTIALLY_FILLED
        assert order.filled_qty == Quantity.from_int(50000)
        assert order.price == Price.from_str("1.00000")
        assert order.avg_px == Decimal("0.999999")
        assert order.slippage == Decimal("-0.000001")
        assert order.is_active
        assert not order.is_inflight
        assert order.is_working
        assert not order.is_completed
        assert order.ts_last == 1_000_000_000, order.ts_last
Ejemplo n.º 2
0
class TestMsgPackSerializer:
    def setup(self):
        # Fixture Setup
        self.trader_id = TestIdStubs.trader_id()
        self.strategy_id = TestIdStubs.strategy_id()
        self.account_id = TestIdStubs.account_id()
        self.venue = Venue("SIM")

        self.unpacker = OrderUnpacker()
        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=self.strategy_id,
            clock=TestClock(),
        )

        self.serializer = MsgPackSerializer()

    def test_serialize_unknown_object_raises_runtime_error(self):
        # Arrange, Act
        with pytest.raises(RuntimeError):
            self.serializer.serialize({"type": "UNKNOWN"})

    def test_deserialize_unknown_object_raises_runtime_error(self):
        # Arrange, Act
        with pytest.raises(RuntimeError):
            self.serializer.deserialize(msgpack.packb({"type": "UNKNOWN"}))

    def test_serialize_and_deserialize_fx_instrument(self):
        # Arrange, Act
        serialized = self.serializer.serialize(AUDUSD_SIM)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == AUDUSD_SIM
        print(b64encode(serialized))
        print(deserialized)

    def test_serialize_and_deserialize_crypto_perpetual_instrument(self):
        # Arrange, Act
        serialized = self.serializer.serialize(ETHUSDT_BINANCE)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == ETHUSDT_BINANCE
        print(b64encode(serialized))
        print(deserialized)

    def test_serialize_and_deserialize_crypto_future_instrument(self):
        # Arrange, Act
        serialized = self.serializer.serialize(BTCUSDT_220325)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == BTCUSDT_220325
        print(b64encode(serialized))
        print(deserialized)

    def test_pack_and_unpack_market_orders(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
        )

        # Act
        packed = OrderInitialized.to_dict(order.last_event)
        unpacked = self.unpacker.unpack(packed)

        # Assert
        assert unpacked == order

    def test_pack_and_unpack_limit_orders(self):
        # Arrange
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
            Price(1.00000, precision=5),
            TimeInForce.DAY,
            display_qty=Quantity(50000, precision=0),
        )

        # Act
        packed = OrderInitialized.to_dict(order.last_event)
        unpacked = self.unpacker.unpack(packed)

        # Assert
        assert unpacked == order

    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 test_pack_and_unpack_stop_market_orders(self):
        # Arrange
        order = StopMarketOrder(
            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.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_pack_and_unpack_stop_market_orders_with_expiration(self):
        # Arrange
        order = StopMarketOrder(
            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_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=Price(1.00010, precision=5),
            trigger_type=TriggerType.BID_ASK,
            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_pack_and_unpack_market_to_limit__orders(self):
        # Arrange
        order = MarketToLimitOrder(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            OrderSide.BUY,
            Quantity(100000, precision=0),
            time_in_force=TimeInForce.GTD,  # <-- invalid
            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_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_pack_and_unpack_limit_if_touched_orders(self):
        # Arrange
        order = LimitIfTouchedOrder(
            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=Price(1.00010, precision=5),
            trigger_type=TriggerType.BID_ASK,
            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_pack_and_unpack_stop_limit_orders_with_expiration(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=Price(1.00010, precision=5),
            trigger_type=TriggerType.LAST,
            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_pack_and_unpack_trailing_stop_market_orders_with_expiration(self):
        # Arrange
        order = TrailingStopMarketOrder(
            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,
            trailing_offset=Decimal("0.00010"),
            offset_type=TrailingOffsetType.PRICE,
            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_pack_and_unpack_trailing_stop_market_orders_no_initial_prices(self):
        # Arrange
        order = TrailingStopMarketOrder(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            OrderSide.BUY,
            Quantity(100000, precision=0),
            trigger_price=None,
            trigger_type=TriggerType.DEFAULT,
            trailing_offset=Decimal("0.00010"),
            offset_type=TrailingOffsetType.PRICE,
            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_pack_and_unpack_trailing_stop_limit_orders_with_expiration(self):
        # Arrange
        order = TrailingStopLimitOrder(
            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=Price(1.00010, precision=5),
            trigger_type=TriggerType.MARK,
            limit_offset=Decimal("50"),
            trailing_offset=Decimal("50"),
            offset_type=TrailingOffsetType.TICKS,
            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_pack_and_unpack_trailing_stop_limit_orders_with_no_initial_prices(self):
        # Arrange
        order = TrailingStopLimitOrder(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            OrderSide.BUY,
            Quantity(100000, precision=0),
            price=None,
            trigger_price=None,
            trigger_type=TriggerType.MARK,
            limit_offset=Decimal("50"),
            trailing_offset=Decimal("50"),
            offset_type=TrailingOffsetType.TICKS,
            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_submit_order_commands(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
        )

        command = SubmitOrder(
            self.trader_id,
            StrategyId("SCALPER-001"),
            PositionId("P-123456"),
            order,
            UUID4(),
            0,
            ClientId("SIM"),
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        assert deserialized.order == order
        print(command)
        print(len(serialized))
        print(serialized)
        print(b64encode(serialized))

    def test_serialize_and_deserialize_submit_order_list_commands(
        self,
    ):
        # Arrange
        bracket = self.order_factory.bracket_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
            stop_loss=Price(0.99900, precision=5),
            take_profit=Price(1.00010, precision=5),
        )

        command = SubmitOrderList(
            client_id=ClientId("SIM"),
            trader_id=self.trader_id,
            strategy_id=StrategyId("SCALPER-001"),
            order_list=bracket,
            command_id=UUID4(),
            ts_init=0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        assert deserialized.list == bracket
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_modify_order_commands(self):
        # Arrange
        command = ModifyOrder(
            self.trader_id,
            StrategyId("SCALPER-001"),
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("001"),
            Quantity(100000, precision=0),
            Price(1.00001, precision=5),
            None,
            UUID4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_cancel_order_commands(self):
        # Arrange
        command = CancelOrder(
            self.trader_id,
            StrategyId("SCALPER-001"),
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("001"),
            UUID4(),
            0,
            ClientId("SIM-001"),
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_component_state_changed_events(self):
        # Arrange
        event = ComponentStateChanged(
            trader_id=TestIdStubs.trader_id(),
            component_id=ComponentId("MyActor-001"),
            component_type="MyActor",
            state=ComponentState.RUNNING,
            config={"do_something": True},
            event_id=UUID4(),
            ts_event=0,
            ts_init=0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_account_state_with_base_currency_events(self):
        # Arrange
        event = AccountState(
            account_id=AccountId("SIM", "000"),
            account_type=AccountType.MARGIN,
            base_currency=USD,
            reported=True,
            balances=[
                AccountBalance(
                    Money(1525000, USD),
                    Money(25000, USD),
                    Money(1500000, USD),
                ),
            ],
            margins=[
                MarginBalance(
                    Money(5000, USD),
                    Money(20000, USD),
                    AUDUSD_SIM.id,
                ),
            ],
            info={},
            event_id=UUID4(),
            ts_event=0,
            ts_init=1_000_000_000,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_account_state_without_base_currency_events(self):
        # Arrange
        event = AccountState(
            account_id=AccountId("SIM", "000"),
            account_type=AccountType.MARGIN,
            base_currency=None,
            reported=True,
            balances=[
                AccountBalance(
                    Money(10000, USDT),
                    Money(0, USDT),
                    Money(10000, USDT),
                ),
            ],
            margins=[],
            info={},
            event_id=UUID4(),
            ts_event=0,
            ts_init=1_000_000_000,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    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,
            post_only=False,
            reduce_only=True,
            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="ENTRY",
            event_id=UUID4(),
            ts_init=0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_limit_order_initialized_events(self):
        # Arrange
        options = {
            "expire_time_ns": 1_000_000_000,
            "price": "1.0010",
        }
Ejemplo n.º 3
0
class TestCommands:
    def setup(self):
        # Fixture Setup
        self.clock = TestClock()
        self.uuid_factory = UUIDFactory()

        self.trader_id = TestIdStubs.trader_id()

        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=StrategyId("S-001"),
            clock=TestClock(),
        )

    def test_submit_order_command_to_from_dict_and_str_repr(self):
        # Arrange
        uuid = self.uuid_factory.generate()

        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        command = SubmitOrder(
            trader_id=TraderId("TRADER-001"),
            strategy_id=StrategyId("S-001"),
            position_id=PositionId("P-001"),
            order=order,
            command_id=uuid,
            ts_init=self.clock.timestamp_ns(),
        )

        # Act, Assert
        assert SubmitOrder.from_dict(SubmitOrder.to_dict(command)) == command
        assert (
            str(command) ==
            "SubmitOrder(instrument_id=AUD/USD.SIM, client_order_id=O-19700101-000000-000-001-1, position_id=P-001, order=BUY 100_000 AUD/USD.SIM MARKET GTC)"  # noqa
        )
        assert (
            repr(command) ==
            f"SubmitOrder(client_id=None, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, client_order_id=O-19700101-000000-000-001-1, position_id=P-001, order=BUY 100_000 AUD/USD.SIM MARKET GTC, command_id={uuid}, ts_init=0)"  # noqa
        )

    def test_submit_bracket_order_command_to_from_dict_and_str_repr(self):
        # Arrange
        uuid = self.uuid_factory.generate()

        bracket = self.order_factory.bracket_market(
            instrument_id=AUDUSD_SIM.id,
            order_side=OrderSide.BUY,
            quantity=Quantity.from_int(100000),
            stop_loss=Price.from_str("1.00000"),
            take_profit=Price.from_str("1.00100"),
        )

        command = SubmitOrderList(
            trader_id=TraderId("TRADER-001"),
            strategy_id=StrategyId("S-001"),
            order_list=bracket,
            command_id=uuid,
            ts_init=self.clock.timestamp_ns(),
        )

        # Act, Assert
        assert SubmitOrderList.from_dict(
            SubmitOrderList.to_dict(command)) == command
        assert (
            str(command) ==
            "SubmitOrderList(instrument_id=AUD/USD.SIM, order_list=OrderList(id=1, instrument_id=AUD/USD.SIM, orders=[MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=ENTRY), StopMarketOrder(SELL 100_000 AUD/USD.SIM STOP_MARKET @ 1.00000[DEFAULT] GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-2, venue_order_id=None, tags=STOP_LOSS), LimitOrder(SELL 100_000 AUD/USD.SIM LIMIT @ 1.00100 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-3, venue_order_id=None, tags=TAKE_PROFIT)]))"  # noqa
        )
        assert (
            repr(command) ==
            f"SubmitOrderList(client_id=None, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, order_list=OrderList(id=1, instrument_id=AUD/USD.SIM, orders=[MarketOrder(BUY 100_000 AUD/USD.SIM MARKET GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-1, venue_order_id=None, tags=ENTRY), StopMarketOrder(SELL 100_000 AUD/USD.SIM STOP_MARKET @ 1.00000[DEFAULT] GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-2, venue_order_id=None, tags=STOP_LOSS), LimitOrder(SELL 100_000 AUD/USD.SIM LIMIT @ 1.00100 GTC, status=INITIALIZED, client_order_id=O-19700101-000000-000-001-3, venue_order_id=None, tags=TAKE_PROFIT)]), command_id={uuid}, ts_init=0)"  # noqa
        )

    def test_modify_order_command_to_from_dict_and_str_repr(self):
        # Arrange
        uuid = self.uuid_factory.generate()

        command = ModifyOrder(
            trader_id=TraderId("TRADER-001"),
            strategy_id=StrategyId("S-001"),
            instrument_id=AUDUSD_SIM.id,
            client_order_id=ClientOrderId("O-123456"),
            venue_order_id=VenueOrderId("001"),
            price=Price.from_str("1.00000"),
            trigger_price=Price.from_str("1.00010"),
            quantity=Quantity.from_int(100000),
            command_id=uuid,
            ts_init=self.clock.timestamp_ns(),
        )

        # Act, Assert
        assert ModifyOrder.from_dict(ModifyOrder.to_dict(command)) == command
        assert (
            str(command) ==
            "ModifyOrder(instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=001, quantity=100_000, price=1.00000, trigger_price=1.00010)"  # noqa
        )
        assert (
            repr(command) ==
            f"ModifyOrder(client_id=None, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=001, quantity=100_000, price=1.00000, trigger_price=1.00010, command_id={uuid}, ts_init=0)"  # noqa
        )

    def test_modify_order_command_with_none_venue_order_id_to_from_dict_and_str_repr(
            self):
        # Arrange
        uuid = self.uuid_factory.generate()

        command = ModifyOrder(
            trader_id=TraderId("TRADER-001"),
            strategy_id=StrategyId("S-001"),
            instrument_id=AUDUSD_SIM.id,
            client_order_id=ClientOrderId("O-123456"),
            venue_order_id=None,
            price=Price.from_str("1.00000"),
            trigger_price=Price.from_str("1.00010"),
            quantity=Quantity.from_int(100000),
            command_id=uuid,
            ts_init=self.clock.timestamp_ns(),
        )

        # Act, Assert
        assert ModifyOrder.from_dict(ModifyOrder.to_dict(command)) == command
        assert (
            str(command) ==
            "ModifyOrder(instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=None, quantity=100_000, price=1.00000, trigger_price=1.00010)"  # noqa
        )
        assert (
            repr(command) ==
            f"ModifyOrder(client_id=None, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=None, quantity=100_000, price=1.00000, trigger_price=1.00010, command_id={uuid}, ts_init=0)"  # noqa
        )

    def test_cancel_order_command_to_from_dict_and_str_repr(self):
        # Arrange
        uuid = self.uuid_factory.generate()

        command = CancelOrder(
            trader_id=TraderId("TRADER-001"),
            strategy_id=StrategyId("S-001"),
            instrument_id=AUDUSD_SIM.id,
            client_order_id=ClientOrderId("O-123456"),
            venue_order_id=VenueOrderId("001"),
            command_id=uuid,
            ts_init=self.clock.timestamp_ns(),
        )

        # Act, Assert
        assert CancelOrder.from_dict(CancelOrder.to_dict(command)) == command
        assert (
            str(command) ==
            "CancelOrder(instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=001)"  # noqa
        )
        assert (
            repr(command) ==
            f"CancelOrder(client_id=SIM, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=001, command_id={uuid}, ts_init=0)"  # noqa
        )

    def test_cancel_order_command_with_none_venue_order_id_to_from_dict_and_str_repr(
            self):
        # Arrange
        uuid = self.uuid_factory.generate()

        command = CancelOrder(
            trader_id=TraderId("TRADER-001"),
            strategy_id=StrategyId("S-001"),
            instrument_id=AUDUSD_SIM.id,
            client_order_id=ClientOrderId("O-123456"),
            venue_order_id=None,
            command_id=uuid,
            ts_init=self.clock.timestamp_ns(),
        )

        # Act, Assert
        assert CancelOrder.from_dict(CancelOrder.to_dict(command)) == command
        assert (
            str(command) ==
            "CancelOrder(instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=None)"  # noqa
        )
        assert (
            repr(command) ==
            f"CancelOrder(client_id=SIM, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=None, command_id={uuid}, ts_init=0)"  # noqa
        )

    def test_cancel_all_orders_command_to_from_dict_and_str_repr(self):
        # Arrange
        uuid = self.uuid_factory.generate()

        command = CancelAllOrders(
            trader_id=TraderId("TRADER-001"),
            strategy_id=StrategyId("S-001"),
            instrument_id=AUDUSD_SIM.id,
            command_id=uuid,
            ts_init=self.clock.timestamp_ns(),
        )

        # Act, Assert
        assert CancelAllOrders.from_dict(
            CancelAllOrders.to_dict(command)) == command
        assert str(
            command) == "CancelAllOrders(instrument_id=AUD/USD.SIM)"  # noqa
        assert (
            repr(command) ==
            f"CancelAllOrders(client_id=None, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, command_id={uuid}, ts_init=0)"  # noqa
        )
Ejemplo n.º 4
0
class TestMsgPackSerializer:
    def setup(self):
        # Fixture Setup
        self.trader_id = TestStubs.trader_id()
        self.strategy_id = TestStubs.strategy_id()
        self.account_id = TestStubs.account_id()
        self.venue = Venue("SIM")

        self.unpacker = OrderUnpacker()
        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=self.strategy_id,
            clock=TestClock(),
        )

        self.serializer = MsgPackSerializer()

    def test_serialize_unknown_object_raises_runtime_error(self):
        # Arrange, Act
        with pytest.raises(RuntimeError):
            self.serializer.serialize({"type": "UNKNOWN"})

    def test_deserialize_unknown_object_raises_runtime_error(self):
        # Arrange, Act
        with pytest.raises(RuntimeError):
            self.serializer.deserialize(msgpack.packb({"type": "UNKNOWN"}))

    def test_serialize_and_deserialize_fx_instrument(self):
        # Arrange, Act
        serialized = self.serializer.serialize(AUDUSD_SIM)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == AUDUSD_SIM
        print(b64encode(serialized))
        print(deserialized)

    def test_serialize_and_deserialize_crypto_swap_instrument(self):
        # Arrange, Act
        serialized = self.serializer.serialize(ETHUSDT_BINANCE)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == ETHUSDT_BINANCE
        print(b64encode(serialized))
        print(deserialized)

    def test_serialize_and_deserialize_crypto_instrument(self):
        # Arrange, Act
        serialized = self.serializer.serialize(ETHUSDT_BINANCE)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == ETHUSDT_BINANCE
        print(b64encode(serialized))
        print(deserialized)

    def test_pack_and_unpack_market_orders(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
        )

        # Act
        packed = OrderInitialized.to_dict(order.last_event)
        unpacked = self.unpacker.unpack(packed)

        # Assert
        assert unpacked == order

    def test_pack_and_unpack_limit_orders(self):
        # Arrange
        order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
            Price(1.00000, precision=5),
            TimeInForce.DAY,
            display_qty=Quantity(50000, precision=0),
        )

        # Act
        packed = OrderInitialized.to_dict(order.last_event)
        unpacked = self.unpacker.unpack(packed)

        # Assert
        assert unpacked == order

    def test_pack_and_unpack_limit_orders_with_expire_time(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,
            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_pack_and_unpack_stop_market_orders_with_expire_time(self):
        # Arrange
        order = StopMarketOrder(
            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,
            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_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_pack_and_unpack_stop_limit_orders_with_expire_time(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.GTD,
            expire_time=UNIX_EPOCH,
            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_submit_order_commands(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
        )

        command = SubmitOrder(
            self.trader_id,
            StrategyId("SCALPER-001"),
            PositionId("P-123456"),
            order,
            UUID4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        assert deserialized.order == order
        print(command)
        print(len(serialized))
        print(serialized)
        print(b64encode(serialized))

    def test_serialize_and_deserialize_submit_order_list_commands(self, ):
        # Arrange
        bracket = self.order_factory.bracket_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000, precision=0),
            stop_loss=Price(0.99900, precision=5),
            take_profit=Price(1.00010, precision=5),
        )

        command = SubmitOrderList(
            trader_id=self.trader_id,
            strategy_id=StrategyId("SCALPER-001"),
            order_list=bracket,
            command_id=UUID4(),
            ts_init=0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        assert deserialized.list == bracket
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_amend_order_commands(self):
        # Arrange
        command = ModifyOrder(
            self.trader_id,
            StrategyId("SCALPER-001"),
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("001"),
            Quantity(100000, precision=0),
            Price(1.00001, precision=5),
            None,
            UUID4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_cancel_order_commands(self):
        # Arrange
        command = CancelOrder(
            self.trader_id,
            StrategyId("SCALPER-001"),
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("001"),
            UUID4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_component_state_changed_events(self):
        # Arrange
        event = ComponentStateChanged(
            trader_id=TestStubs.trader_id(),
            component_id=ComponentId("MyActor-001"),
            component_type="MyActor",
            state=ComponentState.RUNNING,
            config={"do_something": True},
            event_id=UUID4(),
            ts_event=0,
            ts_init=0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_account_state_with_base_currency_events(
            self):
        # Arrange
        event = AccountState(
            account_id=AccountId("SIM", "000"),
            account_type=AccountType.MARGIN,
            base_currency=USD,
            reported=True,
            balances=[
                AccountBalance(USD, Money(1525000, USD), Money(0, USD),
                               Money(1525000, USD))
            ],
            info={},
            event_id=UUID4(),
            ts_event=0,
            ts_init=1_000_000_000,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_account_state_without_base_currency_events(
            self):
        # Arrange
        event = AccountState(
            account_id=AccountId("SIM", "000"),
            account_type=AccountType.MARGIN,
            base_currency=None,
            reported=True,
            balances=[
                AccountBalance(
                    USDT,
                    Money(10000, USDT),
                    Money(0, USDT),
                    Money(10000, USDT),
                )
            ],
            info={},
            event_id=UUID4(),
            ts_event=0,
            ts_init=1_000_000_000,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    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_serialize_and_deserialize_limit_order_initialized_events(self):
        # Arrange
        options = {
            "ExpireTime": None,
            "Price": "1.0010",
            "PostOnly": True,
            "Hidden": False,
        }

        event = OrderInitialized(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            OrderSide.SELL,
            OrderType.LIMIT,
            Quantity(100000, precision=0),
            TimeInForce.DAY,
            reduce_only=False,
            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=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_stop_market_order_initialized_events(
            self):
        # Arrange
        options = {
            "ExpireTime": None,
            "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,
            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=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_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_serialize_and_deserialize_order_denied_events(self):
        # Arrange
        event = OrderDenied(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            "Exceeds MAX_NOTIONAL_PER_ORDER",
            UUID4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_submitted_events(self):
        # Arrange
        event = OrderSubmitted(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_accepted_events(self):
        # Arrange
        event = OrderAccepted(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("B-123456"),
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_rejected_events(self):
        # Arrange
        event = OrderRejected(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            "ORDER_ID_INVALID",
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_pending_cancel_events(self):
        # Arrange
        event = OrderPendingCancel(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_pending_replace_events(self):
        # Arrange
        event = OrderPendingUpdate(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_canceled_events(self):
        # Arrange
        event = OrderCanceled(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_update_reject_events(self):
        # Arrange
        event = OrderModifyRejected(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            "ORDER_DOES_NOT_EXIST",
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_cancel_reject_events(self):
        # Arrange
        event = OrderCancelRejected(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            "ORDER_DOES_NOT_EXIST",
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_amended_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_serialize_and_deserialize_order_expired_events(self):
        # Arrange
        event = OrderExpired(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_triggered_events(self):
        # Arrange
        event = OrderTriggered(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_partially_filled_events(self):
        # Arrange
        event = OrderFilled(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            ExecutionId("E123456"),
            PositionId("T123456"),
            OrderSide.SELL,
            OrderType.MARKET,
            Quantity(50000, precision=0),
            Price(1.00000, precision=5),
            AUDUSD_SIM.quote_currency,
            Money(0, USD),
            LiquiditySide.MAKER,
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_order_filled_events(self):
        # Arrange
        event = OrderFilled(
            self.trader_id,
            self.strategy_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("1"),
            ExecutionId("E123456"),
            PositionId("T123456"),
            OrderSide.SELL,
            OrderType.MARKET,
            Quantity(100000, precision=0),
            Price(1.00000, precision=5),
            AUDUSD_SIM.quote_currency,
            Money(0, USD),
            LiquiditySide.TAKER,
            UUID4(),
            0,
            0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_position_opened_events(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        fill = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
        )

        position = Position(instrument=AUDUSD_SIM, fill=fill)

        uuid = UUID4()
        event = PositionOpened.create(position, fill, uuid, 0)

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_position_changed_events(self):
        # Arrange
        order1 = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        fill1 = TestStubs.event_order_filled(
            order1,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
        )

        order2 = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.SELL,
            Quantity.from_int(50000),
        )

        fill2 = TestStubs.event_order_filled(
            order2,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00011"),
        )

        position = Position(instrument=AUDUSD_SIM, fill=fill1)
        position.apply(fill2)

        uuid = UUID4()
        event = PositionChanged.create(position, fill2, uuid, 0)

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event

    def test_serialize_and_deserialize_position_closed_events(self):
        # Arrange
        order1 = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        fill1 = TestStubs.event_order_filled(
            order1,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00001"),
        )

        order2 = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.SELL,
            Quantity.from_int(100000),
        )

        fill2 = TestStubs.event_order_filled(
            order2,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("1.00011"),
        )

        position = Position(instrument=AUDUSD_SIM, fill=fill1)
        position.apply(fill2)

        uuid = UUID4()
        event = PositionClosed.create(position, fill2, uuid, 0)

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event