def test_position_filled_with_no_change_returns_expected_attributes(self):
        # Arrange
        order1 = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000))

        order2 = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.SELL,
            Quantity(100000))

        fill1 = TestStubs.event_order_filled(order1)

        position = Position(fill1)

        fill2 = TestStubs.event_order_filled(
            order2,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S", "001"),
            fill_price=Price("1.00000"),
        )

        last = QuoteTick(
            AUDUSD_FXCM,
            Price("1.00050"),
            Price("1.00048"),
            Quantity(1),
            Quantity(1),
            UNIX_EPOCH,
        )

        # Act
        position.apply(fill2)

        # Assert
        self.assertEqual(Quantity(), position.quantity)
        self.assertEqual(PositionSide.FLAT, position.side)
        self.assertEqual(UNIX_EPOCH, position.opened_time)
        self.assertEqual(1.0, position.avg_open_price)
        self.assertEqual(2, position.event_count())
        self.assertEqual({order1.cl_ord_id, order2.cl_ord_id}, position.cl_ord_ids())
        self.assertEqual({
            ExecutionId("E-19700101-000000-001-001-1"),
            ExecutionId("E-19700101-000000-001-001-2")
        },
            position.execution_ids(),
        )
        self.assertEqual(UNIX_EPOCH, position.closed_time)
        self.assertEqual(1.0, position.avg_close_price)
        self.assertFalse(position.is_long())
        self.assertFalse(position.is_short())
        self.assertTrue(position.is_closed())
        self.assertEqual(0.0, position.realized_points)
        self.assertEqual(0.0, position.realized_return)
        self.assertEqual(Money(0, USD), position.realized_pnl)
        self.assertEqual(Money(0, USD), position.unrealized_pnl(last))
        self.assertEqual(Money(0, USD), position.total_pnl(last))
    def test_position_long_with_multiple_filled_orders_returns_expected_attributes(self):
        # Arrange
        order1 = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000),
        )

        order2 = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000),
        )

        order3 = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.SELL,
            Quantity(200000),
        )

        fill1 = TestStubs.event_order_filled(order1, PositionId("P-123456"), StrategyId("S", "001"))
        fill2 = TestStubs.event_order_filled(order2, PositionId("P-123456"), StrategyId("S", "001"), fill_price=Price("1.00001"))
        fill3 = TestStubs.event_order_filled(order3, PositionId("P-123456"), StrategyId("S", "001"), fill_price=Price("1.00010"))

        last = QuoteTick(
            AUDUSD_FXCM,
            Price("1.00050"),
            Price("1.00048"),
            Quantity(1),
            Quantity(1),
            UNIX_EPOCH,
        )

        # Act
        position = Position(fill1)
        position.apply(fill2)
        position.apply(fill3)

        # Assert
        self.assertEqual(Quantity(), position.quantity)
        self.assertEqual(PositionSide.FLAT, position.side)
        self.assertEqual(UNIX_EPOCH, position.opened_time)
        self.assertEqual(1.000005, position.avg_open_price)
        self.assertEqual(3, position.event_count())
        self.assertEqual({order1.cl_ord_id, order2.cl_ord_id, order3.cl_ord_id}, position.cl_ord_ids())
        self.assertEqual(UNIX_EPOCH, position.closed_time)
        self.assertEqual(1.0001, position.avg_close_price)
        self.assertFalse(position.is_long())
        self.assertFalse(position.is_short())
        self.assertTrue(position.is_closed())
        self.assertEqual(Money(19.00, USD), position.realized_pnl)
        self.assertEqual(Money(0, USD), position.unrealized_pnl(last))
        self.assertEqual(Money(19.00, USD), position.total_pnl(last))
    def test_position_filled_with_buy_order_returns_expected_attributes(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000),
        )

        fill = TestStubs.event_order_filled(
            order,
            PositionId("P-123456"),
            StrategyId("S", "001"),
            Price("1.00001"),
        )

        last = QuoteTick(
            AUDUSD_FXCM,
            Price("1.00050"),
            Price("1.00048"),
            Quantity(1),
            Quantity(1),
            UNIX_EPOCH,
        )

        # Act
        position = Position(fill)

        # Assert
        self.assertEqual(ClientOrderId("O-19700101-000000-001-001-1"), position.from_order)
        self.assertEqual(Quantity(100000), position.quantity)
        self.assertEqual(Quantity(100000), position.peak_quantity)
        self.assertEqual(OrderSide.BUY, position.entry)
        self.assertEqual(PositionSide.LONG, position.side)
        self.assertEqual(UNIX_EPOCH, position.opened_time)
        self.assertIsNone(position.open_duration)
        self.assertEqual(1.00001, position.avg_open_price)
        self.assertEqual(1, position.event_count())
        self.assertEqual({order.cl_ord_id}, position.cl_ord_ids())
        self.assertEqual({ExecutionId("E-19700101-000000-001-001-1")}, position.execution_ids())
        self.assertEqual(ExecutionId("E-19700101-000000-001-001-1"), position.last_execution_id())
        self.assertEqual(PositionId("P-123456"), position.id)
        self.assertTrue(position.is_long())
        self.assertFalse(position.is_short())
        self.assertFalse(position.is_closed())
        self.assertEqual(0.0, position.realized_points)
        self.assertEqual(0.0, position.realized_return)
        self.assertEqual(Money(0, USD), position.realized_pnl)
        self.assertEqual(Money(49.00, USD), position.unrealized_pnl(last))
        self.assertEqual(Money(49.00, USD), position.total_pnl(last))