def test_position_filled_with_sell_order_returns_expected_attributes(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.SELL,
            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(Quantity(100000), position.quantity)
        self.assertEqual(Quantity(100000), position.peak_quantity)
        self.assertEqual(PositionSide.SHORT, position.side)
        self.assertEqual(UNIX_EPOCH, position.opened_time)
        self.assertEqual(1.00001, position.avg_open_price)
        self.assertEqual(1, position.event_count())
        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.assertFalse(position.is_long())
        self.assertTrue(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(-47.00, USD), position.unrealized_pnl(last))
        self.assertEqual(Money(-47.00, USD), position.total_pnl(last))
    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
        self.assertEqual(OrderState.PARTIALLY_FILLED, order.state)
        self.assertEqual(Quantity.from_int(60000), order.filled_qty)
        self.assertEqual(Decimal("1.000014"), order.avg_px)
        self.assertEqual(2, len(order.execution_ids))
        self.assertTrue(order.is_working)
        self.assertFalse(order.is_completed)
        self.assertEqual(0, order.execution_ns)
Beispiel #3
0
    def test_apply_partial_fill_events_to_market_order_results_in_partially_filled(
            self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
        )

        submitted = TestStubs.event_order_submitted(order)
        accepted = TestStubs.event_order_accepted(order)

        fill1 = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S", "001"),
            fill_price=Price("1.00001"),
            fill_qty=Quantity(20000),
        )

        fill2 = TestStubs.event_order_filled(
            order,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S", "001"),
            fill_price=Price("1.00002"),
            fill_qty=Quantity(40000),
        )

        order.apply(submitted)
        order.apply(accepted)

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

        # Assert
        self.assertEqual(OrderState.PARTIALLY_FILLED, order.state)
        self.assertEqual(Quantity(60000), order.filled_qty)
        self.assertEqual(Decimal("1.000014"), order.avg_price)
        self.assertEqual(2, len(order.execution_ids))
        self.assertFalse(order.is_completed)
        self.assertEqual(UNIX_EPOCH, order.filled_timestamp)
    def test_update_order_for_closed_order(self):
        # Arrange
        order = self.strategy.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        position_id = PositionId("P-1")
        self.cache.add_order(order, position_id)
        order.apply(TestEventStubs.order_submitted(order))
        self.cache.update_order(order)

        order.apply(TestEventStubs.order_accepted(order))
        self.cache.update_order(order)

        fill = TestEventStubs.order_filled(order,
                                           instrument=AUDUSD_SIM,
                                           last_px=Price.from_str("1.00001"))

        order.apply(fill)

        # Act
        self.cache.update_order(order)

        # Assert
        assert self.cache.order_exists(order.client_order_id)
        assert order.client_order_id in self.cache.client_order_ids()
        assert order in self.cache.orders()
        assert order not in self.cache.orders_open()
        assert order not in self.cache.orders_open(
            instrument_id=order.instrument_id)
        assert order not in self.cache.orders_open(
            strategy_id=self.strategy.id)
        assert order not in self.cache.orders_open(
            instrument_id=order.instrument_id, strategy_id=self.strategy.id)
        assert order in self.cache.orders_closed()
        assert order in self.cache.orders_closed(
            instrument_id=order.instrument_id)
        assert order in self.cache.orders_closed(strategy_id=self.strategy.id)
        assert order in self.cache.orders_closed(
            instrument_id=order.instrument_id, strategy_id=self.strategy.id)
        assert order not in self.cache.orders_inflight()
        assert order not in self.cache.orders_inflight(
            instrument_id=order.instrument_id)
        assert order not in self.cache.orders_inflight(
            strategy_id=self.strategy.id)
        assert order not in self.cache.orders_inflight(
            instrument_id=order.instrument_id, strategy_id=self.strategy.id)

        assert self.cache.venue_order_id(
            order.client_order_id) == order.venue_order_id
        assert self.cache.orders_open_count() == 0
        assert self.cache.orders_closed_count() == 1
        assert self.cache.orders_inflight_count() == 0
        assert self.cache.orders_total_count() == 1
Beispiel #5
0
    def test_update_order_for_completed_order(self):
        # Arrange
        order = self.strategy.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        position_id = PositionId("P-1")
        self.cache.add_order(order, position_id)
        order.apply(TestStubs.event_order_submitted(order))
        self.cache.update_order(order)

        order.apply(TestStubs.event_order_accepted(order))
        self.cache.update_order(order)

        fill = TestStubs.event_order_filled(order,
                                            instrument=AUDUSD_SIM,
                                            last_px=Price.from_str("1.00001"))

        order.apply(fill)

        # Act
        self.cache.update_order(order)

        # Assert
        self.assertTrue(self.cache.order_exists(order.client_order_id))
        self.assertIn(order.client_order_id, self.cache.client_order_ids())
        self.assertIn(order, self.cache.orders())
        self.assertIn(order, self.cache.orders_completed())
        self.assertIn(
            order,
            self.cache.orders_completed(instrument_id=order.instrument_id))
        self.assertIn(
            order, self.cache.orders_completed(strategy_id=self.strategy.id))
        self.assertIn(
            order,
            self.cache.orders_completed(instrument_id=order.instrument_id,
                                        strategy_id=self.strategy.id),
        )
        self.assertNotIn(order, self.cache.orders_working())
        self.assertNotIn(
            order,
            self.cache.orders_working(instrument_id=order.instrument_id))
        self.assertNotIn(
            order, self.cache.orders_working(strategy_id=self.strategy.id))
        self.assertNotIn(
            order,
            self.cache.orders_working(instrument_id=order.instrument_id,
                                      strategy_id=self.strategy.id),
        )
        self.assertEqual(order.venue_order_id,
                         self.cache.venue_order_id(order.client_order_id))
        self.assertEqual(0, self.cache.orders_working_count())
        self.assertEqual(1, self.cache.orders_completed_count())
        self.assertEqual(1, self.cache.orders_total_count())
    def test_position_flipped_when_reduce_order_exceeds_original_quantity(
            self):
        # Arrange
        # Prepare market
        open_quote = QuoteTick(
            USDJPY_SIM.symbol,
            Price("90.002"),
            Price("90.003"),
            Quantity(1),
            Quantity(1),
            UNIX_EPOCH,
        )

        self.data_engine.process(open_quote)
        self.exchange.process_tick(open_quote)

        order_open = self.strategy.order_factory.market(
            USDJPY_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
        )

        # Act 1
        self.strategy.submit_order(order_open)

        reduce_quote = QuoteTick(
            USDJPY_SIM.symbol,
            Price("100.003"),
            Price("100.003"),
            Quantity(1),
            Quantity(1),
            UNIX_EPOCH,
        )

        self.exchange.process_tick(reduce_quote)
        self.portfolio.update_tick(reduce_quote)

        order_reduce = self.strategy.order_factory.market(
            USDJPY_SIM.symbol,
            OrderSide.SELL,
            Quantity(150000),
        )

        # Act 2
        self.strategy.submit_order(
            order_reduce,
            PositionId("P-19700101-000000-000-001-1"))  # Generated by platform

        # Assert
        print(self.exec_engine.cache.positions())
        position_open = self.exec_engine.cache.positions_open()[0]
        position_closed = self.exec_engine.cache.positions_closed()[0]
        self.assertEqual(PositionSide.SHORT, position_open.side)
        self.assertEqual(Quantity(50000), position_open.quantity)
        self.assertEqual(Money(999619.98, JPY), position_closed.realized_pnl)
        self.assertEqual([Money(380.02, JPY)], position_closed.commissions())
Beispiel #7
0
    def test_position_filled_with_sell_order_returns_expected_attributes(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.SELL,
            Quantity.from_int(100000),
        )

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

        last = Price.from_str("1.00050")

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

        # Assert
        assert position.quantity == Quantity.from_int(100000)
        assert position.peak_qty == Quantity.from_int(100000)
        assert position.side == PositionSide.SHORT
        assert position.ts_opened == 0
        assert position.avg_px_open == Decimal("1.00001")
        assert position.event_count == 1
        assert position.trade_ids == [TradeId("E-19700101-000000-000-001-1")]
        assert position.last_trade_id == TradeId("E-19700101-000000-000-001-1")
        assert position.id == PositionId("P-123456")
        assert not position.is_long
        assert position.is_short
        assert position.is_open
        assert not position.is_closed
        assert position.realized_points == 0
        assert position.realized_return == 0
        assert position.realized_pnl == Money(-2.00, USD)
        assert position.unrealized_pnl(last) == Money(-49.00, USD)
        assert position.total_pnl(last) == Money(-51.00, USD)
        assert position.commissions() == [Money(2.00, USD)]
        assert repr(
            position) == "Position(SHORT 100_000 AUD/USD.SIM, id=P-123456)"
    def test_position_filled_with_sell_order_returns_expected_attributes(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.symbol,
            OrderSide.SELL,
            Quantity(100000),
        )

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

        last = Price("1.00050")

        # Act
        position = Position(fill)

        # Assert
        self.assertEqual(Quantity(100000), position.quantity)
        self.assertEqual(Quantity(100000), position.peak_quantity)
        self.assertEqual(PositionSide.SHORT, position.side)
        self.assertEqual(UNIX_EPOCH, position.opened_time)
        self.assertEqual(Decimal("1.00001"), position.avg_open)
        self.assertEqual(1, position.event_count)
        self.assertEqual([ExecutionId("E-19700101-000000-000-001-1")], position.execution_ids)
        self.assertEqual(ExecutionId("E-19700101-000000-000-001-1"), position.last_execution_id)
        self.assertEqual(PositionId("P-123456"), position.id)
        self.assertFalse(position.is_long)
        self.assertTrue(position.is_short)
        self.assertTrue(position.is_open)
        self.assertFalse(position.is_closed)
        self.assertEqual(0, position.realized_points)
        self.assertEqual(0, position.realized_return)
        self.assertEqual(Money(-2.00, USD), position.realized_pnl)
        self.assertEqual(Money(-49.00, USD), position.unrealized_pnl(last))
        self.assertEqual(Money(-51.00, USD), position.total_pnl(last))
        self.assertEqual(Money(2.00, USD), position.commission)
        self.assertEqual([Money(2.00, USD)], position.commissions())
        self.assertEqual("Position(id=P-123456, SHORT 100,000 AUD/USD.SIM)", repr(position))
    def test_add_position(self):
        # Arrange
        order = self.strategy.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
        )

        position_id = PositionId("P-1")
        self.cache.add_order(order, position_id)

        fill = TestEventStubs.order_filled(
            order,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-1"),
            last_px=Price.from_str("1.00000"),
        )

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

        # Act
        self.cache.add_position(position, OMSType.HEDGING)

        # Assert
        assert self.cache.position_exists(position.id)
        assert position.id in self.cache.position_ids()
        assert position in self.cache.positions()
        assert position in self.cache.positions_open()
        assert position in self.cache.positions_open(
            instrument_id=position.instrument_id)
        assert position in self.cache.positions_open(
            strategy_id=self.strategy.id)
        assert position in self.cache.positions_open(
            instrument_id=position.instrument_id, strategy_id=self.strategy.id)
        assert position not in self.cache.positions_closed()
        assert position not in self.cache.positions_closed(
            instrument_id=position.instrument_id)
        assert position not in self.cache.positions_closed(
            strategy_id=self.strategy.id)
        assert position not in self.cache.positions_closed(
            instrument_id=position.instrument_id, strategy_id=self.strategy.id)
        assert self.cache.position_for_order(order.client_order_id) == position
        assert self.cache.orders_for_position(position.id) == [order]
    def test_update_orders_working(self):
        # Arrange
        self.portfolio.register_account(self.account)

        # Create two working orders
        order1 = self.order_factory.stop_market(
            BTCUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity("10.5"),
            Price("25000.00"),
        )

        order2 = self.order_factory.stop_market(
            BTCUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity("10.5"),
            Price("25000.00"),
        )

        # Push state to WORKING
        order1.apply(TestStubs.event_order_submitted(order1))
        order1.apply(TestStubs.event_order_accepted(order1))

        filled1 = TestStubs.event_order_filled(
            order1,
            instrument=BTCUSDT_BINANCE,
            position_id=PositionId("P-1"),
            strategy_id=StrategyId("S", "1"),
            fill_price=Price("25000.00"),
        )

        # Push state to FILLED
        order1.apply(filled1)

        # Push state to WORKING
        order2.apply(TestStubs.event_order_submitted(order2))
        order2.apply(TestStubs.event_order_accepted(order2))
        order2.apply(TestStubs.event_order_working(order2))

        # Update the last quote
        last = QuoteTick(
            BTCUSDT_BINANCE.symbol,
            Price("25001.00"),
            Price("25002.00"),
            Quantity(1),
            Quantity(1),
            UNIX_EPOCH,
        )

        # Act
        self.portfolio.update_tick(last)
        self.portfolio.initialize_orders({order1, order2})

        # Assert
        self.assertEqual({}, self.portfolio.initial_margins(BINANCE))
    def test_update_order_for_accepted_order(self):
        # Arrange
        order = self.strategy.order_factory.stop_market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity.from_int(100000),
            Price.from_str("1.00000"),
        )

        position_id = PositionId("P-1")
        self.cache.add_order(order, position_id)

        order.apply(TestStubs.event_order_submitted(order))
        self.cache.update_order(order)

        order.apply(TestStubs.event_order_accepted(order))

        # Act
        self.cache.update_order(order)

        # Assert
        assert self.cache.order_exists(order.client_order_id)
        assert order.client_order_id in self.cache.client_order_ids()
        assert order in self.cache.orders()
        assert order in self.cache.orders_active()
        assert order in self.cache.orders_active(instrument_id=order.instrument_id)
        assert order in self.cache.orders_active(strategy_id=self.strategy.id)
        assert order in self.cache.orders_active(
            instrument_id=order.instrument_id, strategy_id=self.strategy.id
        )
        assert order not in self.cache.orders_inflight()
        assert order not in self.cache.orders_inflight()
        assert order not in self.cache.orders_inflight(instrument_id=order.instrument_id)
        assert order not in self.cache.orders_inflight(strategy_id=self.strategy.id)
        assert order not in self.cache.orders_inflight(
            instrument_id=order.instrument_id, strategy_id=self.strategy.id
        )
        assert order in self.cache.orders_working()
        assert order in self.cache.orders_working(instrument_id=order.instrument_id)
        assert order in self.cache.orders_working(strategy_id=self.strategy.id)
        assert order in self.cache.orders_working(
            instrument_id=order.instrument_id, strategy_id=self.strategy.id
        )
        assert order not in self.cache.orders_completed()
        assert order not in self.cache.orders_completed(instrument_id=order.instrument_id)
        assert order not in self.cache.orders_completed(strategy_id=self.strategy.id)
        assert order not in self.cache.orders_completed(
            instrument_id=order.instrument_id, strategy_id=self.strategy.id
        )

        assert self.cache.orders_active_count() == 1
        assert self.cache.orders_inflight_count() == 0
        assert self.cache.orders_working_count() == 1
        assert self.cache.orders_completed_count() == 0
        assert self.cache.orders_total_count() == 1
Beispiel #12
0
    def test_generate_order_fills_report(self):
        # Arrange
        report_provider = ReportProvider()

        order1 = self.order_factory.limit(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(1500000),
            Price("0.80010"),
        )

        order1.apply(TestStubs.event_order_submitted(order1))
        order1.apply(TestStubs.event_order_accepted(order1))
        order1.apply(TestStubs.event_order_working(order1))

        order2 = self.order_factory.limit(
            AUDUSD_SIM.symbol,
            OrderSide.SELL,
            Quantity(1500000),
            Price("0.80000"),
        )

        submitted2 = TestStubs.event_order_submitted(order2)
        accepted2 = TestStubs.event_order_accepted(order2)
        working2 = TestStubs.event_order_working(order2)

        order2.apply(submitted2)
        order2.apply(accepted2)
        order2.apply(working2)

        filled = TestStubs.event_order_filled(
            order1,
            instrument=AUDUSD_SIM,
            position_id=PositionId("P-1"),
            strategy_id=StrategyId("S", "1"),
            fill_price=Price("0.80011"),
        )

        order1.apply(filled)

        orders = [order1, order2]

        # Act
        report = report_provider.generate_order_fills_report(orders)

        # Assert
        self.assertEqual(1, len(report))
        self.assertEqual("cl_ord_id", report.index.name)
        self.assertEqual(order1.cl_ord_id.value, report.index[0])
        self.assertEqual("AUD/USD", report.iloc[0]["symbol"])
        self.assertEqual("BUY", report.iloc[0]["side"])
        self.assertEqual("LIMIT", report.iloc[0]["type"])
        self.assertEqual(1500000, report.iloc[0]["quantity"])
        self.assertEqual(0.80011, report.iloc[0]["avg_price"])
        self.assertEqual(0.00001, report.iloc[0]["slippage"])
Beispiel #13
0
    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 = TestEventStubs.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 = TestEventStubs.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
Beispiel #14
0
    def test_calculate_pnls_for_multi_currency_cash_account_adabtc(self):
        # Arrange
        event = AccountState(
            account_id=AccountId("SIM", "001"),
            account_type=AccountType.CASH,
            base_currency=None,  # Multi-currency
            reported=True,
            balances=[
                AccountBalance(
                    BTC,
                    Money(1.00000000, BTC),
                    Money(0.00000000, BTC),
                    Money(1.00000000, BTC),
                ),
                AccountBalance(
                    ADA,
                    Money(1000.00000000, ADA),
                    Money(0.00000000, ADA),
                    Money(1000.00000000, ADA),
                ),
            ],
            info={},  # No default currency set
            event_id=UUID4(),
            ts_event=0,
            ts_init=0,
        )

        account = CashAccount(event)

        order = self.order_factory.market(
            ADABTC_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_int(100),
        )

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

        position = Position(ADABTC_BINANCE, fill)

        # Act
        result = account.calculate_pnls(
            instrument=ADABTC_BINANCE,
            position=position,
            fill=fill,
        )

        # Assert
        assert result == [Money(100.000000, ADA), Money(-0.00410410, BTC)]
Beispiel #15
0
    def on_bar(self, bar_type, bar):

        self.object_storer.store((bar_type, Bar))

        if bar_type.equals(self.bar_type):
            if self.ema1.value > self.ema2.value:
                buy_order = self.order_factory.market(self.bar_type.symbol,
                                                      Label('TestStrategy1_E'),
                                                      OrderSide.BUY, 100000)

                self.submit_order(buy_order, PositionId(str(buy_order.id)))
                self.position_id = buy_order.id

            elif self.ema1.value < self.ema2.value:
                sell_order = self.order_factory.market(
                    self.bar_type.symbol, Label('TestStrategy1_E'),
                    OrderSide.SELL, 100000)

                self.submit_order(sell_order, PositionId(str(sell_order.id)))
                self.position_id = sell_order.id
    def test_calculate_unrealized_pnl_for_long(self):
        # Arrange
        order1 = self.order_factory.market(
            BTCUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity("2.000000"),
        )

        order2 = self.order_factory.market(
            BTCUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity("2.000000"),
        )

        fill1 = TestStubs.event_order_filled(
            order1,
            instrument=BTCUSDT_BINANCE,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S", "001"),
            fill_price=Price("10500.00"),
        )

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

        position = Position(fill1)
        position.apply(fill2)

        # Act
        pnl = position.unrealized_pnl(Price("11505.60"))

        # Assert
        self.assertEqual(Money("4022.40000000", USDT), pnl)
        self.assertEqual(Money("-42.00000000", USDT), position.realized_pnl)
        self.assertEqual([Money("42.00000000", USDT)], position.commissions())
        self.assertEqual(Money("42.00000000", USDT), position.commission)
    def test_update_order_for_accepted_order(self):
        # Arrange
        order = self.strategy.order_factory.stop_market(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
            Price("1.00000"),
        )

        position_id = PositionId('P-1')
        self.cache.add_order(order, position_id)

        order.apply(TestStubs.event_order_submitted(order))
        self.cache.update_order(order)

        order.apply(TestStubs.event_order_accepted(order))

        # Act
        self.cache.update_order(order)

        # Assert
        self.assertTrue(self.cache.order_exists(order.cl_ord_id))
        self.assertIn(order.cl_ord_id, self.cache.order_ids())
        self.assertIn(order, self.cache.orders())
        self.assertIn(order, self.cache.orders_active())
        self.assertIn(order, self.cache.orders_active(symbol=order.symbol))
        self.assertIn(order,
                      self.cache.orders_active(strategy_id=self.strategy.id))
        self.assertIn(
            order,
            self.cache.orders_active(symbol=order.symbol,
                                     strategy_id=self.strategy.id))
        self.assertIn(order, self.cache.orders_working())
        self.assertIn(order, self.cache.orders_working(symbol=order.symbol))
        self.assertIn(order,
                      self.cache.orders_working(strategy_id=self.strategy.id))
        self.assertIn(
            order,
            self.cache.orders_working(symbol=order.symbol,
                                      strategy_id=self.strategy.id))
        self.assertNotIn(order, self.cache.orders_completed())
        self.assertNotIn(order,
                         self.cache.orders_completed(symbol=order.symbol))
        self.assertNotIn(
            order, self.cache.orders_completed(strategy_id=self.strategy.id))
        self.assertNotIn(
            order,
            self.cache.orders_completed(symbol=order.symbol,
                                        strategy_id=self.strategy.id))
        self.assertEqual(1, self.cache.orders_active_count())
        self.assertEqual(1, self.cache.orders_working_count())
        self.assertEqual(0, self.cache.orders_completed_count())
        self.assertEqual(1, self.cache.orders_total_count())
Beispiel #18
0
    def test_can_change_clock(self):
        # Arrange
        clock = TestClock()
        strategy = TradingStrategy(order_id_tag='001')

        # Act
        strategy.change_clock(clock)

        # Assert
        self.assertEqual(UNIX_EPOCH, strategy.time_now())
        self.assertEqual(PositionId('P-19700101-000000-000-001-1'),
                         strategy.position_id_generator.generate())
Beispiel #19
0
    def test_position_partial_fills_with_buy_order_returns_expected_attributes(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000))

        order_partially_filled = OrderPartiallyFilled(
            self.account_id,
            order.id,
            ExecutionId('E123456'),
            PositionIdBroker('T123456'),
            order.symbol,
            order.side,
            Quantity(50000),
            Quantity(50000),
            Price(1.00001, 5),
            Currency.USD,
            UNIX_EPOCH,
            GUID(uuid.uuid4()),
            UNIX_EPOCH)

        last = Tick(AUDUSD_FXCM,
                    Price(1.00050, 5),
                    Price(1.00048, 5),
                    Volume(1),
                    Volume(1),
                    UNIX_EPOCH)

        position = Position(PositionId('P-123456'), order_partially_filled)

        # Act
        # Assert
        self.assertEqual(Quantity(50000), position.quantity)
        self.assertEqual(Quantity(50000), position.peak_quantity)
        self.assertEqual(MarketPosition.LONG, position.market_position)
        self.assertEqual(UNIX_EPOCH, position.opened_time)
        self.assertEqual(1.00001, position.average_open_price)
        self.assertEqual(1, position.event_count)
        self.assertEqual(ExecutionId('E123456'), position.last_execution_id)
        self.assertEqual(PositionIdBroker('T123456'), position.id_broker)
        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, Currency.USD), position.realized_pnl)
        self.assertEqual(0.0004899999999998794, position.unrealized_points(last))
        self.assertEqual(0.0004899951000488789, position.unrealized_return(last))
        self.assertEqual(Money(24.50, Currency.USD), position.unrealized_pnl(last))
        self.assertEqual(0.0004899999999998794, position.total_points(last))
        self.assertEqual(0.0004899951000488789, position.total_return(last))
        self.assertEqual(Money(24.50, Currency.USD), position.total_pnl(last))
Beispiel #20
0
    def test_reset_id_generator(self):
        # Arrange
        self.position_id_generator.generate(StrategyId("S", "002"))
        self.position_id_generator.generate(StrategyId("S", "002"))
        self.position_id_generator.generate(StrategyId("S", "002"))

        # Act
        self.position_id_generator.reset()
        result1 = self.position_id_generator.generate(StrategyId("S", "002"))

        # Assert
        self.assertEqual(PositionId("P-19700101-000000-001-002-1"), result1)
Beispiel #21
0
    def test_can_reset_id_generator(self):
        # Arrange
        self.position_id_generator.generate()
        self.position_id_generator.generate()
        self.position_id_generator.generate()

        # Act
        self.position_id_generator.reset()
        result1 = self.position_id_generator.generate()

        # Assert
        self.assertEqual(PositionId('P-19700101-000000-001-001-1'), result1)
Beispiel #22
0
    def test_calculate_unrealized_pnl_for_long(self):
        # Arrange
        order1 = self.order_factory.market(
            BTCUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_str("2.000000"),
        )

        order2 = self.order_factory.market(
            BTCUSDT_BINANCE.id,
            OrderSide.BUY,
            Quantity.from_str("2.000000"),
        )

        fill1 = TestEventStubs.order_filled(
            order1,
            instrument=BTCUSDT_BINANCE,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("10500.00"),
        )

        fill2 = TestEventStubs.order_filled(
            order2,
            instrument=BTCUSDT_BINANCE,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S-001"),
            last_px=Price.from_str("10500.00"),
        )

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

        # Act
        pnl = position.unrealized_pnl(Price.from_str("11505.60"))

        # Assert
        assert pnl == Money(4022.40000000, USDT)
        assert position.realized_pnl == Money(-42.00000000, USDT)
        assert position.commissions() == [Money(42.00000000, USDT)]
Beispiel #23
0
    def test_handle_position_opening_with_position_id_none(self):
        # Arrange
        self.exec_engine.start()

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

        self.exec_engine.register_strategy(strategy)

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

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

        self.exec_engine.execute(submit_order)

        # Act
        self.exec_engine.process(TestStubs.event_order_submitted(order))
        self.exec_engine.process(TestStubs.event_order_accepted(order))
        self.exec_engine.process(TestStubs.event_order_filled(order, AUDUSD_SIM, PositionId.null()))

        expected_id = PositionId("P-000-AUD/USD.SIM-1")  # Generated inside engine

        # Assert
        self.assertTrue(self.cache.position_exists(expected_id))
        self.assertTrue(self.cache.is_position_open(expected_id))
        self.assertFalse(self.cache.is_position_closed(expected_id))
        self.assertEqual(Position, type(self.cache.position(expected_id)))
        self.assertIn(expected_id, self.cache.position_ids())
        self.assertNotIn(expected_id, self.cache.position_closed_ids(strategy_id=strategy.id))
        self.assertNotIn(expected_id, self.cache.position_closed_ids())
        self.assertIn(expected_id, self.cache.position_open_ids(strategy_id=strategy.id))
        self.assertIn(expected_id, self.cache.position_open_ids())
        self.assertEqual(1, self.cache.positions_total_count())
        self.assertEqual(1, self.cache.positions_open_count())
        self.assertEqual(0, self.cache.positions_closed_count())
Beispiel #24
0
    def test_handle_position_opening_with_position_id_none(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag="001")
        strategy.register_trader(
            TraderId("TESTER", "000"),
            clock=self.clock,
            uuid_factory=TestUUIDFactory(),
            logger=self.logger,
        )

        self.exec_engine.register_strategy(strategy)

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

        submit_order = SubmitOrder(self.venue, self.trader_id, self.account_id,
                                   strategy.id, PositionId.py_null(), order,
                                   self.uuid_factory.generate(),
                                   self.clock.utc_now())

        self.exec_engine.execute(submit_order)

        # Act
        self.exec_engine.process(TestStubs.event_order_submitted(order))
        self.exec_engine.process(TestStubs.event_order_accepted(order))
        self.exec_engine.process(TestStubs.event_order_filled(order))

        expected_id = PositionId(
            "O-19700101-000000-000-001-1")  # Stubbed from order id

        # Assert
        self.assertTrue(self.cache.position_exists(expected_id))
        self.assertTrue(self.cache.is_position_open(expected_id))
        self.assertFalse(self.cache.is_position_closed(expected_id))
        self.assertFalse(
            self.exec_engine.cache.is_flat(strategy_id=strategy.id))
        self.assertFalse(self.exec_engine.cache.is_flat())
        self.assertEqual(Position, type(self.cache.position(expected_id)))
        self.assertTrue(expected_id in self.cache.position_ids())
        self.assertTrue(expected_id not in self.cache.position_closed_ids(
            strategy_id=strategy.id))
        self.assertTrue(expected_id not in self.cache.position_closed_ids())
        self.assertTrue(expected_id in self.cache.position_open_ids(
            strategy_id=strategy.id))
        self.assertTrue(expected_id in self.cache.position_open_ids())
        self.assertEqual(1, self.cache.positions_total_count())
        self.assertEqual(1, self.cache.positions_open_count())
        self.assertEqual(0, self.cache.positions_closed_count())
        self.assertTrue(self.cache.position_exists_for_order(order.cl_ord_id))
def nautilus_objects() -> List[Any]:
    """A list of nautilus instances for testing serialization"""
    instrument = TestInstrumentProvider.default_fx_ccy("AUD/USD")
    position_id = PositionId("P-001")
    buy = TestExecStubs.limit_order()
    buy_submitted, buy_accepted, buy_filled = _make_order_events(
        buy,
        instrument=instrument,
        position_id=position_id,
        trade_id=TradeId("BUY"),
    )
    sell = TestExecStubs.limit_order(order_side=OrderSide.SELL)
    _, _, sell_filled = _make_order_events(
        sell,
        instrument=instrument,
        position_id=position_id,
        trade_id=TradeId("SELL"),
    )
    open_position = Position(instrument=instrument, fill=buy_filled)
    closed_position = Position(instrument=instrument, fill=buy_filled)
    closed_position.apply(sell_filled)

    return [
        TestDataStubs.ticker(),
        TestDataStubs.quote_tick_5decimal(),
        TestDataStubs.trade_tick_5decimal(),
        TestDataStubs.bar_5decimal(),
        TestDataStubs.venue_status_update(),
        TestDataStubs.instrument_status_update(),
        TestEventStubs.component_state_changed(),
        TestEventStubs.trading_state_changed(),
        TestEventStubs.betting_account_state(),
        TestEventStubs.cash_account_state(),
        TestEventStubs.margin_account_state(),
        # ORDERS
        TestEventStubs.order_accepted(buy),
        TestEventStubs.order_rejected(buy),
        TestEventStubs.order_pending_update(buy_accepted),
        TestEventStubs.order_pending_cancel(buy_accepted),
        TestEventStubs.order_filled(
            order=buy,
            instrument=instrument,
            position_id=open_position.id,
        ),
        TestEventStubs.order_canceled(buy_accepted),
        TestEventStubs.order_expired(buy),
        TestEventStubs.order_triggered(buy),
        # POSITIONS
        TestEventStubs.position_opened(open_position),
        TestEventStubs.position_changed(open_position),
        TestEventStubs.position_closed(closed_position),
    ]
Beispiel #26
0
    def test_reset_id_generator(self):
        # Arrange
        self.position_id_generator.generate(TestStubs.symbol_audusd_fxcm())
        self.position_id_generator.generate(TestStubs.symbol_audusd_fxcm())
        self.position_id_generator.generate(TestStubs.symbol_audusd_fxcm())

        # Act
        self.position_id_generator.reset()
        result1 = self.position_id_generator.generate(
            TestStubs.symbol_audusd_fxcm())

        # Assert
        self.assertEqual(PositionId("P-001-AUD/USD.SIM-1"), result1)
    def test_market_value_when_insufficient_data_for_xrate_returns_none(self):
        # Arrange
        state = AccountState(
            account_id=AccountId("BITMEX", "01234"),
            balances=[Money("10.00000000", BTC), Money("10.00000000", ETH)],
            balances_free=[Money("10.00000000", BTC), Money("10.00000000", ETH)],
            balances_locked=[Money("0.00000000", BTC), Money("0.00000000", ETH)],
            info={},
            event_id=uuid4(),
            event_timestamp=UNIX_EPOCH,
        )

        account = Account(state)

        self.portfolio.register_account(account)

        order = self.order_factory.market(
            ETHUSD_BITMEX.symbol,
            OrderSide.BUY,
            Quantity(100),
        )

        fill = TestStubs.event_order_filled(
            order=order,
            instrument=ETHUSD_BITMEX,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S", "001"),
            fill_price=Price("376.05"),
        )

        last_ethusd = QuoteTick(
            ETHUSD_BITMEX.symbol,
            Price("376.05"),
            Price("377.10"),
            Quantity("16"),
            Quantity("25"),
            UNIX_EPOCH,
        )

        position = Position(fill)

        self.portfolio.update_position(TestStubs.event_position_opened(position))
        self.data_cache.add_quote_tick(last_ethusd)
        self.portfolio.update_tick(last_ethusd)

        # Act
        result = self.portfolio.market_values(BITMEX)

        # Assert
        # TODO: Currently no Quanto thus no xrate required
        self.assertEqual({ETH: Money('0.02659221', ETH)}, result)
    def test_opening_one_long_position_updates_portfolio(self):
        # Arrange
        order = self.order_factory.market(
            BTCUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity("10.000000"),
        )

        fill = TestStubs.event_order_filled(
            order=order,
            instrument=BTCUSDT_BINANCE,
            position_id=PositionId("P-123456"),
            strategy_id=StrategyId("S", "001"),
            fill_price=Price("10500.00"),
        )

        last = QuoteTick(
            BTCUSDT_BINANCE.symbol,
            Price("10510.00"),
            Price("10511.00"),
            Quantity("1.000000"),
            Quantity("1.000000"),
            UNIX_EPOCH,
        )

        self.data_cache.add_quote_tick(last)
        self.portfolio.update_tick(last)

        position = Position(fill)

        # Act
        self.portfolio.update_position(
            TestStubs.event_position_opened(position))

        # Assert
        self.assertEqual({USDT: Money("105100.00000000", USDT)},
                         self.portfolio.market_values(BINANCE))
        self.assertEqual({USDT: Money("100.00000000", USDT)},
                         self.portfolio.unrealized_pnls(BINANCE))
        self.assertEqual({}, self.portfolio.maint_margins(BINANCE))
        self.assertEqual(Money("105100.00000000", USDT),
                         self.portfolio.market_value(BTCUSDT_BINANCE.symbol))
        self.assertEqual(Money("100.00000000", USDT),
                         self.portfolio.unrealized_pnl(BTCUSDT_BINANCE.symbol))
        self.assertEqual(Decimal("10.00000000"),
                         self.portfolio.net_position(order.symbol))
        self.assertTrue(self.portfolio.is_net_long(order.symbol))
        self.assertFalse(self.portfolio.is_net_short(order.symbol))
        self.assertFalse(self.portfolio.is_flat(order.symbol))
        self.assertFalse(self.portfolio.is_completely_flat())
Beispiel #29
0
    def test_apply_order_partially_filled_event_to_buy_limit_order(self):
        # Arrange
        order = self.order_factory.limit(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
            Price("1.00000"),
        )

        submitted = TestStubs.event_order_submitted(order)
        accepted = TestStubs.event_order_accepted(order)
        working = TestStubs.event_order_working(order)

        partially = OrderFilled(
            self.account_id,
            order.cl_ord_id,
            OrderId("1"),
            ExecutionId("E-1"),
            PositionId("P-1"),
            StrategyId.null(),
            order.symbol,
            order.side,
            Quantity(50000),
            Quantity(50000),
            Quantity(50000),
            Price("0.999999"),
            AUDUSD_SIM.quote_currency,
            AUDUSD_SIM.is_inverse,
            Money(0, USD),
            LiquiditySide.MAKER,
            UNIX_EPOCH,
            uuid4(),
            UNIX_EPOCH,
        )

        order.apply(submitted)
        order.apply(accepted)
        order.apply(working)

        # Act
        order.apply(partially)

        # Assert
        self.assertEqual(OrderState.PARTIALLY_FILLED, order.state)
        self.assertEqual(Quantity(50000), order.filled_qty)
        self.assertEqual(Price("1.00000"), order.price)
        self.assertEqual(Decimal("0.999999"), order.avg_price)
        self.assertEqual(Decimal("-0.000001"), order.slippage)
        self.assertFalse(order.is_completed)
        self.assertEqual(UNIX_EPOCH, order.filled_timestamp)
Beispiel #30
0
    def test_load_order_when_order_in_database_returns_order(self):
        # Arrange
        order = self.strategy.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000))
        position_id = PositionId('P-1')
        self.database.add_order(order, position_id)

        # Act
        result = self.database.load_order(order.cl_ord_id)

        # Assert
        self.assertEqual(order, result)