Exemplo n.º 1
0
    def test_process_trade_update_does_not_trigger_filled_event_update_status_when_completely_filled(self):
        order: InFlightOrder = InFlightOrder(
            client_order_id="someClientOrderId",
            exchange_order_id="someExchangeOrderId",
            trading_pair=self.trading_pair,
            order_type=OrderType.LIMIT,
            trade_type=TradeType.BUY,
            amount=Decimal("1000.0"),
            creation_timestamp=1640001112.0,
            price=Decimal("1.0"),
            initial_state=OrderState.OPEN,
        )
        self.tracker.start_tracking_order(order)

        fee_paid: Decimal = self.trade_fee_percent * order.amount
        trade_update: TradeUpdate = TradeUpdate(
            trade_id=1,
            client_order_id=order.client_order_id,
            exchange_order_id=order.exchange_order_id,
            trading_pair=order.trading_pair,
            fill_price=order.price,
            fill_base_amount=order.amount,
            fill_quote_amount=order.price * order.amount,
            fee=AddedToCostTradeFee(flat_fees=[TokenAmount(token=self.quote_asset, amount=fee_paid)]),
            fill_timestamp=1,
        )

        self.tracker.process_trade_update(trade_update)

        fetched_order: InFlightOrder = self.tracker.fetch_order(order.client_order_id)
        self.assertTrue(fetched_order.is_filled)
        self.assertIn(fetched_order.client_order_id, self.tracker.active_orders)
        self.assertNotIn(fetched_order.client_order_id, self.tracker.cached_orders)

        self.assertTrue(
            self._is_logged(
                "INFO",
                f"The {order.trade_type.name.upper()} order {order.client_order_id} amounting to "
                f"{order.amount}/{order.amount} {order.base_asset} has been filled.",
            )
        )

        self.assertEqual(1, len(self.order_filled_logger.event_log))
        self.assertEqual(0, len(self.buy_order_completed_logger.event_log))

        order_filled_event: OrderFilledEvent = self.order_filled_logger.event_log[0]
        self.assertIsNotNone(order_filled_event)

        self.assertEqual(order_filled_event.order_id, order.client_order_id)
        self.assertEqual(order_filled_event.price, trade_update.fill_price)
        self.assertEqual(order_filled_event.amount, trade_update.fill_base_amount)
        self.assertEqual(
            order_filled_event.trade_fee, AddedToCostTradeFee(flat_fees=[TokenAmount(self.quote_asset, fee_paid)])
        )
    def test_updating_order_states_with_both_process_order_update_and_process_trade_update(
            self):
        order: InFlightOrder = InFlightOrder(
            client_order_id="someClientOrderId",
            trading_pair=self.trading_pair,
            order_type=OrderType.LIMIT,
            trade_type=TradeType.BUY,
            amount=Decimal("1000.0"),
            creation_timestamp=1640001112.0,
            price=Decimal("1.0"),
        )
        self.tracker.start_tracking_order(order)

        order_creation_update: OrderUpdate = OrderUpdate(
            client_order_id=order.client_order_id,
            exchange_order_id="someExchangeOrderId",
            trading_pair=self.trading_pair,
            update_timestamp=1,
            new_state=OrderState.OPEN,
        )

        update_future = self.tracker.process_order_update(
            order_creation_update)
        self.async_run_with_timeout(update_future)

        open_order: InFlightOrder = self.tracker.fetch_tracked_order(
            order.client_order_id)

        # Check order_creation_update has been successfully applied
        self.assertEqual(open_order.exchange_order_id,
                         order_creation_update.exchange_order_id)
        self.assertTrue(open_order.exchange_order_id_update_event.is_set())
        self.assertEqual(open_order.current_state,
                         order_creation_update.new_state)
        self.assertTrue(open_order.is_open)
        self.assertEqual(0, len(open_order.order_fills))

        trade_filled_price: Decimal = order.price
        trade_filled_amount: Decimal = order.amount
        fee_paid: Decimal = self.trade_fee_percent * trade_filled_amount
        trade_update: TradeUpdate = TradeUpdate(
            trade_id=1,
            client_order_id=order.client_order_id,
            exchange_order_id=order.exchange_order_id,
            trading_pair=order.trading_pair,
            fill_price=trade_filled_price,
            fill_base_amount=trade_filled_amount,
            fill_quote_amount=trade_filled_price * trade_filled_amount,
            fee=AddedToCostTradeFee(flat_fees=[
                TokenAmount(token=self.quote_asset, amount=fee_paid)
            ]),
            fill_timestamp=2,
        )

        self.tracker.process_trade_update(trade_update)
        self.assertEqual(1, len(self.tracker.active_orders))
        self.assertEqual(0, len(self.tracker.cached_orders))
    def test_process_trade_update_trigger_filled_event_flat_fee(self):
        order: InFlightOrder = InFlightOrder(
            client_order_id="someClientOrderId",
            exchange_order_id="someExchangeOrderId",
            trading_pair=self.trading_pair,
            order_type=OrderType.LIMIT,
            trade_type=TradeType.BUY,
            amount=Decimal("1000.0"),
            price=Decimal("1.0"),
            initial_state=OrderState.OPEN,
        )
        self.tracker.start_tracking_order(order)

        trade_filled_price: Decimal = Decimal("0.5")
        trade_filled_amount: Decimal = order.amount / Decimal("2.0")
        fee_paid: Decimal = self.trade_fee_percent * trade_filled_amount
        trade_update: TradeUpdate = TradeUpdate(
            trade_id=1,
            client_order_id=order.client_order_id,
            exchange_order_id=order.exchange_order_id,
            trading_pair=order.trading_pair,
            fill_price=trade_filled_price,
            fill_base_amount=trade_filled_amount,
            fill_quote_amount=trade_filled_price * trade_filled_amount,
            fee_asset=self.base_asset,
            fee_paid=fee_paid,
            fill_timestamp=1,
        )

        self.tracker.process_trade_update(trade_update)

        self.assertTrue(
            self._is_logged(
                "INFO",
                f"The {order.trade_type.name.upper()} order {order.client_order_id} amounting to "
                f"{trade_filled_amount}/{order.amount} {order.base_asset} has been filled.",
            ))

        self.assertEqual(1, len(self.connector.event_logs))
        order_filled_event: OrderFilledEvent = self.connector.event_logs[0]

        self.assertEqual(order_filled_event.order_id, order.client_order_id)
        self.assertEqual(order_filled_event.price, trade_update.fill_price)
        self.assertEqual(order_filled_event.amount,
                         trade_update.fill_base_amount)
        self.assertEqual(
            order_filled_event.trade_fee,
            AddedToCostTradeFee(
                flat_fees=[TokenAmount(self.base_asset, fee_paid)]))
    def test_update_to_close_order_is_not_processed_until_order_completelly_filled(
            self):
        order: InFlightOrder = InFlightOrder(
            client_order_id="someClientOrderId",
            trading_pair=self.trading_pair,
            order_type=OrderType.LIMIT,
            trade_type=TradeType.BUY,
            amount=Decimal("1000.0"),
            price=Decimal("1.0"),
            creation_timestamp=1640001112.223,
        )
        self.tracker.start_tracking_order(order)

        order_creation_update: OrderUpdate = OrderUpdate(
            client_order_id=order.client_order_id,
            exchange_order_id="someExchangeOrderId",
            trading_pair=self.trading_pair,
            update_timestamp=1,
            new_state=OrderState.OPEN,
        )

        trade_update: TradeUpdate = TradeUpdate(
            trade_id="1",
            client_order_id=order.client_order_id,
            exchange_order_id=order.exchange_order_id,
            trading_pair=order.trading_pair,
            fill_price=Decimal("1100"),
            fill_base_amount=order.amount,
            fill_quote_amount=order.amount * Decimal("1100"),
            fee=AddedToCostTradeFee(flat_fees=[
                TokenAmount(token=self.quote_asset, amount=Decimal("10"))
            ]),
            fill_timestamp=10,
        )

        order_completion_update: OrderUpdate = OrderUpdate(
            client_order_id=order.client_order_id,
            exchange_order_id="someExchangeOrderId",
            trading_pair=self.trading_pair,
            update_timestamp=2,
            new_state=OrderState.FILLED,
        )

        # We invert the orders update processing on purpose, to force the test scenario without using sleeps
        self.connector._set_current_timestamp(1640001100)
        completion_update_future = self.tracker.process_order_update(
            order_completion_update)

        self.connector._set_current_timestamp(1640001105)
        creation_update_future = self.tracker.process_order_update(
            order_creation_update)
        self.async_run_with_timeout(creation_update_future)

        order: InFlightOrder = self.tracker.fetch_order(
            client_order_id=order.client_order_id)

        # Check order_creation_update has been successfully applied
        self.assertFalse(order.is_done)
        self.assertFalse(order.is_filled)
        self.assertFalse(order.completely_filled_event.is_set())

        fill_timetamp = 1640001115
        self.connector._set_current_timestamp(fill_timetamp)
        self.tracker.process_trade_update(trade_update)
        self.assertTrue(order.completely_filled_event.is_set())

        self.connector._set_current_timestamp(1640001120)
        self.async_run_with_timeout(completion_update_future)

        self.assertTrue(order.is_filled)
        fill_event: OrderFilledEvent = self.order_filled_logger.event_log[0]
        self.assertEqual(fill_timetamp, fill_event.timestamp)

        complete_event: BuyOrderCompletedEvent = self.buy_order_completed_logger.event_log[
            0]
        self.assertGreaterEqual(complete_event.timestamp, 1640001120)
Exemplo n.º 5
0
 def latest_trade_fee(self) -> AddedToCostTradeFee:
     trade_fee: AddedToCostTradeFee = (
         AddedToCostTradeFee(percent=self.trade_fee_percent)
         if self.trade_fee_percent else AddedToCostTradeFee(
             flat_fees=[TokenAmount(self.fee_asset, self.last_fee_paid)]))
     return trade_fee
    def test_process_trade_update_trigger_filled_event_update_status_when_completely_filled(
            self):
        order: InFlightOrder = InFlightOrder(
            client_order_id="someClientOrderId",
            exchange_order_id="someExchangeOrderId",
            trading_pair=self.trading_pair,
            order_type=OrderType.LIMIT,
            trade_type=TradeType.BUY,
            amount=Decimal("1000.0"),
            price=Decimal("1.0"),
            initial_state=OrderState.OPEN,
        )
        self.tracker.start_tracking_order(order)

        fee_paid: Decimal = self.trade_fee_percent * order.amount
        trade_update: TradeUpdate = TradeUpdate(
            trade_id=1,
            client_order_id=order.client_order_id,
            exchange_order_id=order.exchange_order_id,
            trading_pair=order.trading_pair,
            fill_price=order.price,
            fill_base_amount=order.amount,
            fill_quote_amount=order.price * order.amount,
            fee_asset=self.base_asset,
            fee_paid=fee_paid,
            fill_timestamp=1,
        )

        self.tracker.process_trade_update(trade_update)

        fetched_order: InFlightOrder = self.tracker.fetch_order(
            order.client_order_id)
        self.assertTrue(fetched_order.is_filled)
        self.assertNotIn(fetched_order.client_order_id,
                         self.tracker.active_orders)
        self.assertIn(fetched_order.client_order_id,
                      self.tracker.cached_orders)

        self.assertTrue(
            self._is_logged(
                "INFO",
                f"The {order.trade_type.name.upper()} order {order.client_order_id} amounting to "
                f"{order.amount}/{order.amount} {order.base_asset} has been filled.",
            ))

        self.assertEqual(2, len(self.connector.event_logs))

        order_filled_event: Optional[OrderFilledEvent] = None
        order_completed_event: Optional[BuyOrderCompletedEvent] = None
        for event in self.connector.event_logs:
            if isinstance(event, OrderFilledEvent):
                order_filled_event = event
            if isinstance(event, BuyOrderCompletedEvent):
                order_completed_event = event

        self.assertIsNotNone(order_filled_event)
        self.assertIsNotNone(order_completed_event)

        self.assertEqual(order_filled_event.order_id, order.client_order_id)
        self.assertEqual(order_filled_event.price, trade_update.fill_price)
        self.assertEqual(order_filled_event.amount,
                         trade_update.fill_base_amount)
        self.assertEqual(
            order_filled_event.trade_fee,
            AddedToCostTradeFee(
                flat_fees=[TokenAmount(self.base_asset, fee_paid)]))

        self.assertEqual(order_completed_event.order_id, order.client_order_id)
        self.assertEqual(order_completed_event.exchange_order_id,
                         order.exchange_order_id)
        self.assertEqual(order_completed_event.base_asset_amount, order.amount)
        self.assertEqual(
            order_completed_event.quote_asset_amount,
            trade_update.fill_price * trade_update.fill_base_amount)
        self.assertEqual(order_completed_event.fee_amount,
                         trade_update.fee_paid)