From bd87a36ba9c4cdeb02f4887ac2224953eb6db1e3 Mon Sep 17 00:00:00 2001 From: bczhang Date: Fri, 22 Sep 2023 13:32:12 +0800 Subject: [PATCH 01/12] fix bug --- .../derivative/kucoin_perpetual/kucoin_perpetual_derivative.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py index 59fdbec483..14504ed0af 100644 --- a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py +++ b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py @@ -615,7 +615,7 @@ async def _process_account_position_event(self, position_msg: Dict[str, Any]): if "changeReason" in position_msg and position_msg["changeReason"] != "markPriceChange": ex_trading_pair = position_msg["symbol"] trading_pair = await self.trading_pair_associated_to_exchange_symbol(symbol=ex_trading_pair) - amount = Decimal(str(position_msg["currentQty"])) + amount = self.get_value_of_contracts(trading_pair, int(str(position_msg["currentQty"]))) position_side = PositionSide.SHORT if amount < 0 else PositionSide.LONG entry_price = Decimal(str(position_msg["avgEntryPrice"])) leverage = Decimal(str(position_msg["realLeverage"])) From d5e0155ec23f5986a631808bcf681acd5f9009c5 Mon Sep 17 00:00:00 2001 From: bczhang Date: Fri, 22 Sep 2023 18:24:48 +0800 Subject: [PATCH 02/12] format code --- .../kucoin_perpetual/kucoin_perpetual_derivative.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py index 14504ed0af..d742b45638 100644 --- a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py +++ b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py @@ -419,7 +419,7 @@ async def _update_balances(self): self._account_balances.clear() if wallet_balance["data"] is not None: - if type(wallet_balance["data"]) == list: + if type(wallet_balance["data"]) is list: for balance_data in wallet_balance["data"]: currency = str(balance_data["currency"]) self._account_balances[currency] = Decimal(str(balance_data["marginBalance"])) @@ -591,7 +591,7 @@ async def _user_stream_event_listener(self): self._order_tracker.process_order_update(order_update=order_update) elif endpoint == CONSTANTS.WS_SUBSCRIPTION_WALLET_ENDPOINT_NAME: - if type(payload) == list: + if type(payload) is list: for wallet_msg in payload: self._process_wallet_event_message(wallet_msg) else: @@ -831,7 +831,7 @@ async def _get_last_traded_price(self, trading_pair: str) -> float: limit_id=CONSTANTS.LATEST_SYMBOL_INFORMATION_ENDPOINT, ) - if type(resp_json["data"]) == list: + if type(resp_json["data"]) is list: if "lastTradePrice" in resp_json["data"][0]: price = float(resp_json["data"][0]["lastTradePrice"]) else: From b9e8acb6802f2e9b6d347f51b713e203e4d5373a Mon Sep 17 00:00:00 2001 From: bczhang Date: Fri, 22 Sep 2023 18:26:50 +0800 Subject: [PATCH 03/12] format code --- .../kucoin_perpetual/kucoin_perpetual_derivative.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py index d742b45638..3b4d213f62 100644 --- a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py +++ b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py @@ -419,7 +419,7 @@ async def _update_balances(self): self._account_balances.clear() if wallet_balance["data"] is not None: - if type(wallet_balance["data"]) is list: + if isinstance(wallet_balance["data"],list): for balance_data in wallet_balance["data"]: currency = str(balance_data["currency"]) self._account_balances[currency] = Decimal(str(balance_data["marginBalance"])) @@ -591,7 +591,7 @@ async def _user_stream_event_listener(self): self._order_tracker.process_order_update(order_update=order_update) elif endpoint == CONSTANTS.WS_SUBSCRIPTION_WALLET_ENDPOINT_NAME: - if type(payload) is list: + if isinstance(payload, list): for wallet_msg in payload: self._process_wallet_event_message(wallet_msg) else: @@ -830,8 +830,7 @@ async def _get_last_traded_price(self, trading_pair: str) -> float: path_url=CONSTANTS.LATEST_SYMBOL_INFORMATION_ENDPOINT.format(symbol=exchange_symbol), limit_id=CONSTANTS.LATEST_SYMBOL_INFORMATION_ENDPOINT, ) - - if type(resp_json["data"]) is list: + if isinstance(resp_json["data"], list): if "lastTradePrice" in resp_json["data"][0]: price = float(resp_json["data"][0]["lastTradePrice"]) else: From 5409fa0c043585e9f401a303464aa21ca1b0e675 Mon Sep 17 00:00:00 2001 From: bczhang Date: Fri, 22 Sep 2023 18:41:49 +0800 Subject: [PATCH 04/12] format code --- .../derivative/kucoin_perpetual/kucoin_perpetual_derivative.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py index 3b4d213f62..d6bdda7a91 100644 --- a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py +++ b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py @@ -419,7 +419,7 @@ async def _update_balances(self): self._account_balances.clear() if wallet_balance["data"] is not None: - if isinstance(wallet_balance["data"],list): + if isinstance(wallet_balance["data"], list): for balance_data in wallet_balance["data"]: currency = str(balance_data["currency"]) self._account_balances[currency] = Decimal(str(balance_data["marginBalance"])) From 50eb6236731b9c62c79903b2d56a39ffa37aebe1 Mon Sep 17 00:00:00 2001 From: bczhang Date: Mon, 25 Sep 2023 11:29:05 +0800 Subject: [PATCH 05/12] update --- .../kucoin_perpetual/kucoin_perpetual_derivative.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py index d6bdda7a91..d3bbf5b8d8 100644 --- a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py +++ b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py @@ -456,7 +456,7 @@ async def _update_positions(self): data = position ex_trading_pair = data.get("symbol") hb_trading_pair = await self.trading_pair_associated_to_exchange_symbol(ex_trading_pair) - amount = self.get_value_of_contracts(hb_trading_pair, int(str(data["currentQty"]))) + amount = self.get_value_of_contracts(hb_trading_pair, int(Decimal(data["currentQty"]))) position_side = PositionSide.SHORT if amount < 0 else PositionSide.LONG unrealized_pnl = Decimal(str(data["unrealisedPnl"])) entry_price = Decimal(str(data["avgEntryPrice"])) @@ -615,7 +615,7 @@ async def _process_account_position_event(self, position_msg: Dict[str, Any]): if "changeReason" in position_msg and position_msg["changeReason"] != "markPriceChange": ex_trading_pair = position_msg["symbol"] trading_pair = await self.trading_pair_associated_to_exchange_symbol(symbol=ex_trading_pair) - amount = self.get_value_of_contracts(trading_pair, int(str(position_msg["currentQty"]))) + amount = self.get_value_of_contracts(trading_pair, int(Decimal(position_msg["currentQty"]))) position_side = PositionSide.SHORT if amount < 0 else PositionSide.LONG entry_price = Decimal(str(position_msg["avgEntryPrice"])) leverage = Decimal(str(position_msg["realLeverage"])) From 5aef16ea3d00b94af46855e6c8e233470547153d Mon Sep 17 00:00:00 2001 From: bczhang Date: Mon, 25 Sep 2023 11:51:20 +0800 Subject: [PATCH 06/12] update --- .../kucoin_perpetual/kucoin_perpetual_derivative.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py index d3bbf5b8d8..c473af4165 100644 --- a/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py +++ b/hummingbot/connector/derivative/kucoin_perpetual/kucoin_perpetual_derivative.py @@ -456,7 +456,7 @@ async def _update_positions(self): data = position ex_trading_pair = data.get("symbol") hb_trading_pair = await self.trading_pair_associated_to_exchange_symbol(ex_trading_pair) - amount = self.get_value_of_contracts(hb_trading_pair, int(Decimal(data["currentQty"]))) + amount = self.get_value_of_contracts(hb_trading_pair, int(data["currentQty"])) position_side = PositionSide.SHORT if amount < 0 else PositionSide.LONG unrealized_pnl = Decimal(str(data["unrealisedPnl"])) entry_price = Decimal(str(data["avgEntryPrice"])) @@ -615,7 +615,7 @@ async def _process_account_position_event(self, position_msg: Dict[str, Any]): if "changeReason" in position_msg and position_msg["changeReason"] != "markPriceChange": ex_trading_pair = position_msg["symbol"] trading_pair = await self.trading_pair_associated_to_exchange_symbol(symbol=ex_trading_pair) - amount = self.get_value_of_contracts(trading_pair, int(Decimal(position_msg["currentQty"]))) + amount = self.get_value_of_contracts(trading_pair, int(position_msg["currentQty"])) position_side = PositionSide.SHORT if amount < 0 else PositionSide.LONG entry_price = Decimal(str(position_msg["avgEntryPrice"])) leverage = Decimal(str(position_msg["realLeverage"])) From ed52ac1fd61082cd6707f6fbb95980bca3509157 Mon Sep 17 00:00:00 2001 From: bczhang Date: Mon, 25 Sep 2023 12:39:32 +0800 Subject: [PATCH 07/12] update --- .../kucoin_perpetual/test_kucoin_perpetual_derivative.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py index d13f6a63f6..a2d3aeea2c 100644 --- a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py +++ b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py @@ -1018,7 +1018,7 @@ def position_event_for_full_fill_websocket_update(self, order: InFlightOrder, un "changeReason": "positionChange", "currentCost": str(position_value), "openingTimestamp": 1558433191000, - "currentQty": -float(order.amount), + "currentQty": -int(order.amount), "delevPercentage": 0.52, "currentComm": 0.00000271, "realisedGrossCost": 0E-8, From 30ec16b8767fc9e3fbcc044a84f156a8c1a4a3c6 Mon Sep 17 00:00:00 2001 From: bczhang Date: Mon, 25 Sep 2023 13:30:31 +0800 Subject: [PATCH 08/12] update unittest --- .../test_kucoin_perpetual_derivative.py | 94 ++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py index a2d3aeea2c..233a3e6eb0 100644 --- a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py +++ b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py @@ -15,10 +15,11 @@ from hummingbot.client.config.client_config_map import ClientConfigMap from hummingbot.client.config.config_helpers import ClientConfigAdapter from hummingbot.connector.derivative.kucoin_perpetual.kucoin_perpetual_derivative import KucoinPerpetualDerivative +from hummingbot.connector.derivative.position import Position from hummingbot.connector.test_support.perpetual_derivative_test import AbstractPerpetualDerivativeTests from hummingbot.connector.trading_rule import TradingRule from hummingbot.connector.utils import combine_to_hb_trading_pair -from hummingbot.core.data_type.common import OrderType, PositionAction, PositionMode, TradeType +from hummingbot.core.data_type.common import OrderType, PositionAction, PositionMode, TradeType, PositionSide from hummingbot.core.data_type.funding_info import FundingInfo from hummingbot.core.data_type.in_flight_order import InFlightOrder from hummingbot.core.data_type.trade_fee import AddedToCostTradeFee, TokenAmount, TradeFeeBase @@ -1555,3 +1556,94 @@ def test_start_network_update_trading_rules(self, mock_api): self.assertEqual(1, len(self.exchange.trading_rules)) self.assertIn(self.trading_pair, self.exchange.trading_rules) self.assertEqual(repr(self.expected_trading_rule), repr(self.exchange.trading_rules[self.trading_pair])) + + @aioresponses() + def test_user_stream_update_for_order_full_fill(self, mock_api): + self.exchange._set_current_timestamp(1640780000) + leverage = 2 + self.exchange._perpetual_trading.set_leverage(self.trading_pair, leverage) + self.exchange.start_tracking_order( + order_id=self.client_order_id_prefix + "1", + exchange_order_id=self.exchange_order_id_prefix + "1", + trading_pair=self.trading_pair, + order_type=OrderType.LIMIT, + trade_type=TradeType.SELL, + price=Decimal("10000"), + amount=Decimal("1"), + position_action=PositionAction.OPEN, + ) + order = self.exchange.in_flight_orders[self.client_order_id_prefix + "1"] + + order_event = self.order_event_for_full_fill_websocket_update(order=order) + trade_event = self.trade_event_for_full_fill_websocket_update(order=order) + expected_unrealized_pnl = 12 + position_event = self.position_event_for_full_fill_websocket_update( + order=order, unrealized_pnl=expected_unrealized_pnl + ) + + mock_queue = AsyncMock() + event_messages = [] + if trade_event: + event_messages.append(trade_event) + if order_event: + event_messages.append(order_event) + if position_event: + event_messages.append(position_event) + event_messages.append(asyncio.CancelledError) + mock_queue.get.side_effect = event_messages + self.exchange._user_stream_tracker._user_stream = mock_queue + + if self.is_order_fill_http_update_executed_during_websocket_order_event_processing: + self.configure_full_fill_trade_response( + order=order, + mock_api=mock_api) + + try: + self.async_run_with_timeout(self.exchange._user_stream_event_listener()) + except asyncio.CancelledError: + pass + # Execute one more synchronization to ensure the async task that processes the update is finished + self.async_run_with_timeout(order.wait_until_completely_filled()) + + fill_event = self.order_filled_logger.event_log[0] + self.assertEqual(self.exchange.current_timestamp, fill_event.timestamp) + self.assertEqual(order.client_order_id, fill_event.order_id) + self.assertEqual(order.trading_pair, fill_event.trading_pair) + self.assertEqual(order.trade_type, fill_event.trade_type) + self.assertEqual(order.order_type, fill_event.order_type) + self.assertEqual(order.price, fill_event.price) + self.assertEqual(order.amount, fill_event.amount) + expected_fee = self.expected_fill_fee + self.assertEqual(expected_fee, fill_event.trade_fee) + self.assertEqual(leverage, fill_event.leverage) + self.assertEqual(PositionAction.OPEN.value, fill_event.position) + + sell_event = self.sell_order_completed_logger.event_log[0] + self.assertEqual(self.exchange.current_timestamp, sell_event.timestamp) + self.assertEqual(order.client_order_id, sell_event.order_id) + self.assertEqual(order.base_asset, sell_event.base_asset) + self.assertEqual(order.quote_asset, sell_event.quote_asset) + self.assertEqual(order.amount, sell_event.base_asset_amount) + self.assertEqual(order.amount * fill_event.price, sell_event.quote_asset_amount) + self.assertEqual(order.order_type, sell_event.order_type) + self.assertEqual(order.exchange_order_id, sell_event.exchange_order_id) + self.assertNotIn(order.client_order_id, self.exchange.in_flight_orders) + self.assertTrue(order.is_filled) + self.assertTrue(order.is_done) + + self.assertTrue( + self.is_logged( + "INFO", + f"SELL order {order.client_order_id} completely filled." + ) + ) + + self.assertEqual(1, len(self.exchange.account_positions)) + + position: Position = self.exchange.account_positions[self.trading_pair] + self.assertEqual(self.trading_pair, position.trading_pair) + self.assertEqual(PositionSide.SHORT, position.position_side) + self.assertEqual(expected_unrealized_pnl, position.unrealized_pnl) + self.assertEqual(fill_event.price, position.entry_price) + self.assertEqual(-fill_event.amount, (self.exchange.get_quantity_of_contracts(self.trading_pair, position.amount))) + self.assertEqual(leverage, position.leverage) \ No newline at end of file From 7ae6bf47262edd3debfa2470851bd0fa65d5f94c Mon Sep 17 00:00:00 2001 From: bczhang Date: Mon, 25 Sep 2023 14:42:18 +0800 Subject: [PATCH 09/12] format --- .../kucoin_perpetual/test_kucoin_perpetual_derivative.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py index 233a3e6eb0..5cc7bae053 100644 --- a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py +++ b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py @@ -1646,4 +1646,4 @@ def test_user_stream_update_for_order_full_fill(self, mock_api): self.assertEqual(expected_unrealized_pnl, position.unrealized_pnl) self.assertEqual(fill_event.price, position.entry_price) self.assertEqual(-fill_event.amount, (self.exchange.get_quantity_of_contracts(self.trading_pair, position.amount))) - self.assertEqual(leverage, position.leverage) \ No newline at end of file + self.assertEqual(leverage, position.leverage) From 8ebaf6f4052a07cff5163d2fe2ef95608e2ebf1d Mon Sep 17 00:00:00 2001 From: bczhang Date: Mon, 25 Sep 2023 16:47:13 +0800 Subject: [PATCH 10/12] format --- .../kucoin_perpetual/test_kucoin_perpetual_derivative.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py index 5cc7bae053..c16a365326 100644 --- a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py +++ b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py @@ -19,7 +19,7 @@ from hummingbot.connector.test_support.perpetual_derivative_test import AbstractPerpetualDerivativeTests from hummingbot.connector.trading_rule import TradingRule from hummingbot.connector.utils import combine_to_hb_trading_pair -from hummingbot.core.data_type.common import OrderType, PositionAction, PositionMode, TradeType, PositionSide +from hummingbot.core.data_type.common import OrderType, PositionAction, PositionMode, PositionSide, TradeType from hummingbot.core.data_type.funding_info import FundingInfo from hummingbot.core.data_type.in_flight_order import InFlightOrder from hummingbot.core.data_type.trade_fee import AddedToCostTradeFee, TokenAmount, TradeFeeBase From 869fee6cd48ee58c55c3511ef590f4ccccb4638f Mon Sep 17 00:00:00 2001 From: bczhang Date: Mon, 25 Sep 2023 17:34:49 +0800 Subject: [PATCH 11/12] format --- .../kucoin_perpetual/test_kucoin_perpetual_derivative.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py index c16a365326..1dfe01fc07 100644 --- a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py +++ b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py @@ -1560,6 +1560,7 @@ def test_start_network_update_trading_rules(self, mock_api): @aioresponses() def test_user_stream_update_for_order_full_fill(self, mock_api): self.exchange._set_current_timestamp(1640780000) + self._simulate_trading_rules_initialized() leverage = 2 self.exchange._perpetual_trading.set_leverage(self.trading_pair, leverage) self.exchange.start_tracking_order( From 1bb2d1b60d075bd15f361d1dd575dd5c10c3d6cb Mon Sep 17 00:00:00 2001 From: bczhang Date: Tue, 26 Sep 2023 11:33:53 +0800 Subject: [PATCH 12/12] update unittest --- .../test_kucoin_perpetual_derivative.py | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py index 1dfe01fc07..eeacd4c940 100644 --- a/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py +++ b/test/hummingbot/connector/derivative/kucoin_perpetual/test_kucoin_perpetual_derivative.py @@ -975,7 +975,7 @@ def trade_event_for_full_fill_websocket_update(self, order: InFlightOrder): "size": float(order.amount) * 1000, "fee": str(self.expected_fill_fee.percent), "remainSize": "0", - "matchSize": float(order.amount) * 1000, + "matchSize": float(order.amount) * 1000000, "canceledSize": "0", "clientOid": order.client_order_id or "", "orderTime": 1545914149935808589, @@ -1648,3 +1648,66 @@ def test_user_stream_update_for_order_full_fill(self, mock_api): self.assertEqual(fill_event.price, position.entry_price) self.assertEqual(-fill_event.amount, (self.exchange.get_quantity_of_contracts(self.trading_pair, position.amount))) self.assertEqual(leverage, position.leverage) + + @aioresponses() + def test_lost_order_user_stream_full_fill_events_are_processed(self, mock_api): + self.exchange._set_current_timestamp(1640780000) + self._simulate_trading_rules_initialized() + self.exchange.start_tracking_order( + order_id=self.client_order_id_prefix + "1", + exchange_order_id=str(self.expected_exchange_order_id), + trading_pair=self.trading_pair, + order_type=OrderType.LIMIT, + trade_type=TradeType.BUY, + price=Decimal("10000"), + amount=Decimal("1"), + ) + order = self.exchange.in_flight_orders[self.client_order_id_prefix + "1"] + + for _ in range(self.exchange._order_tracker._lost_order_count_limit + 1): + self.async_run_with_timeout( + self.exchange._order_tracker.process_order_not_found(client_order_id=order.client_order_id)) + + self.assertNotIn(order.client_order_id, self.exchange.in_flight_orders) + + order_event = self.order_event_for_full_fill_websocket_update(order=order) + trade_event = self.trade_event_for_full_fill_websocket_update(order=order) + + mock_queue = AsyncMock() + event_messages = [] + if trade_event: + event_messages.append(trade_event) + if order_event: + event_messages.append(order_event) + event_messages.append(asyncio.CancelledError) + mock_queue.get.side_effect = event_messages + self.exchange._user_stream_tracker._user_stream = mock_queue + + if self.is_order_fill_http_update_executed_during_websocket_order_event_processing: + self.configure_full_fill_trade_response( + order=order, + mock_api=mock_api) + + try: + self.async_run_with_timeout(self.exchange._user_stream_event_listener()) + except asyncio.CancelledError: + pass + # Execute one more synchronization to ensure the async task that processes the update is finished + self.async_run_with_timeout(order.wait_until_completely_filled()) + + fill_event = self.order_filled_logger.event_log[0] + self.assertEqual(self.exchange.current_timestamp, fill_event.timestamp) + self.assertEqual(order.client_order_id, fill_event.order_id) + self.assertEqual(order.trading_pair, fill_event.trading_pair) + self.assertEqual(order.trade_type, fill_event.trade_type) + self.assertEqual(order.order_type, fill_event.order_type) + self.assertEqual(order.price, fill_event.price) + self.assertEqual(order.amount, fill_event.amount) + expected_fee = self.expected_fill_fee + self.assertEqual(expected_fee, fill_event.trade_fee) + + self.assertEqual(0, len(self.buy_order_completed_logger.event_log)) + self.assertNotIn(order.client_order_id, self.exchange.in_flight_orders) + self.assertNotIn(order.client_order_id, self.exchange._order_tracker.lost_orders) + self.assertTrue(order.is_filled) + self.assertTrue(order.is_failure)