diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 8ac6b8c..f23e165 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -4,3 +4,6 @@ updates: directory: "/" schedule: interval: "monthly" + groups: + all: + dependency-type: "production" diff --git a/src/kraken_infinity_grid/order_management.py b/src/kraken_infinity_grid/order_management.py index df42151..e653f97 100644 --- a/src/kraken_infinity_grid/order_management.py +++ b/src/kraken_infinity_grid/order_management.py @@ -621,10 +621,14 @@ def handle_filled_order_event( tries += 1 if order_details["status"] != "closed": - self.__s.save_exit( - "handle_filled_order_event - fetched order is not closed!" - f" {order_details}", + LOG.warning( + "Can not handle filled order, since the fetched order is not" + " closed in upstream!" + " This may happen due to Kraken's websocket API being faster" + " than their REST backend. Retrying in a few seconds...", ) + self.handle_filled_order_event(txid=txid) + return # ====================================================================== if self.__s.dry_run: @@ -830,6 +834,6 @@ def get_orders_info_with_retry( f"Failed to retrieve order info for '{txid}' after" f" {max_tries} retries!", ) - order_details["txid"] = txid + order_details["txid"] = txid return order_details # type: ignore[no-any-return] diff --git a/src/kraken_infinity_grid/telegram.py b/src/kraken_infinity_grid/telegram.py index 2eeacdc..7bf287d 100644 --- a/src/kraken_infinity_grid/telegram.py +++ b/src/kraken_infinity_grid/telegram.py @@ -104,13 +104,14 @@ def send_telegram_update(self: Self) -> None: message += "\n```\n" message += f" 🏷️ Price in {self.__s.quote_currency}\n" + max_orders_to_list: int = 5 next_sells = [ order["price"] for order in self.__s.orderbook.get_orders( filters={"side": "sell"}, order_by=("price", "ASC"), - limit=5, + limit=max_orders_to_list, ) ] next_sells.reverse() @@ -122,7 +123,7 @@ def send_telegram_update(self: Self) -> None: change = (sell_price / self.__s.ticker.last - 1) * 100 if index == 0: message += f" │ ┌[ {sell_price} (+{change:.2f}%)\n" - elif index <= n_sells - 1 and index != 4: + elif index <= n_sells - 1 and index != max_orders_to_list: message += f" │ ├[ {sell_price} (+{change:.2f}%)\n" message += f" └──┼> {self.__s.ticker.last}\n" @@ -131,13 +132,13 @@ def send_telegram_update(self: Self) -> None: for order in self.__s.orderbook.get_orders( filters={"side": "buy"}, order_by=("price", "DESC"), - limit=5, + limit=max_orders_to_list, ) ] if (n_buys := len(next_buys)) != 0: for index, buy_price in enumerate(next_buys): change = (buy_price / self.__s.ticker.last - 1) * 100 - if index < n_buys - 1 and index != 4: + if index < n_buys - 1 and index != max_orders_to_list: message += f" ├[ {buy_price} ({change:.2f}%)\n" else: message += f" └[ {buy_price} ({change:.2f}%)" diff --git a/tests/test_order_management.py b/tests/test_order_management.py index 12ef8b7..3d91d23 100644 --- a/tests/test_order_management.py +++ b/tests/test_order_management.py @@ -838,10 +838,11 @@ def test_handle_filled_order_event_buy_order_not_closed_retry_failing( mock_handle_arbitrage: mock.Mock, mock_get_orders_info_with_retry: mock.Mock, order_manager: OrderManager, + caplog: pytest.LogCaptureFixture, ) -> None: """ - Test handling a filled order event failing due to too much retries of - retrieving the order information. + Test handling a filled order event that fails too often an triggers a recall + of themselves. """ mock_get_orders_info_with_retry.side_effect = [ { @@ -851,15 +852,26 @@ def test_handle_filled_order_event_buy_order_not_closed_retry_failing( "vol_exec": 0.1, } for _ in range(4) + ] + [ # Mark as closed after some time + { + "descr": {"pair": "BTCUSD", "type": "buy", "price": 50000.0}, + "status": "closed", + "userref": 13456789, + "vol_exec": 0.1, + }, ] with ( - pytest.raises(SystemExit, match=r".*fetched order is not closed.*"), mock.patch("kraken_infinity_grid.order_management.sleep", return_value=None), ): order_manager.handle_filled_order_event(txid="txid1") - mock_handle_arbitrage.assert_not_called() + mock_handle_arbitrage.assert_called_once() + + assert ( + "Can not handle filled order, since the fetched order is not closed in upstream!" + in caplog.text + ) @mock.patch.object(OrderManager, "get_orders_info_with_retry")