From 331159a3d832256738988ab4bfa2fed2d4c53112 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 14 Aug 2024 21:18:47 +0200 Subject: [PATCH] fix: ensure handle_onexchange_order works without false warnings futures were not properly handled in this command. closes #10533 --- freqtrade/freqtradebot.py | 6 +++++- freqtrade/wallets.py | 11 +++++++++++ tests/freqtradebot/test_freqtradebot.py | 2 +- tests/test_wallets.py | 4 ++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index c970e440b..dff99e93e 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -542,7 +542,11 @@ class FreqtradeBot(LoggingMixin): ) else: trade.exit_reason = prev_exit_reason - total = self.wallets.get_total(trade.base_currency) if trade.base_currency else 0 + total = ( + self.wallets.get_owned(trade.pair, trade.base_currency) + if trade.base_currency + else 0 + ) if total < trade.amount: if trade.fully_canceled_entry_order_count == len(trade.orders): logger.warning( diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py index 1e7281ddd..336f24b77 100644 --- a/freqtrade/wallets.py +++ b/freqtrade/wallets.py @@ -66,6 +66,17 @@ class Wallets: else: return 0 + def get_owned(self, pair: str, base_currency: str) -> float: + """ + Get currently owned value. + Designed to work across both spot and futures. + """ + if self._config.get("trading_mode", "spot") != TradingMode.FUTURES: + return self.get_total(base_currency) or 0 + if pos := self._positions.get(pair): + return pos.position + return 0 + def _update_dry(self) -> None: """ Update from database in dry-run mode diff --git a/tests/freqtradebot/test_freqtradebot.py b/tests/freqtradebot/test_freqtradebot.py index 23dfbb785..7c45928a2 100644 --- a/tests/freqtradebot/test_freqtradebot.py +++ b/tests/freqtradebot/test_freqtradebot.py @@ -4909,7 +4909,7 @@ def test_handle_onexchange_order_changed_amount( leverage=1, ) freqtrade.wallets = MagicMock() - freqtrade.wallets.get_total = MagicMock(return_value=entry_order["amount"] * factor) + freqtrade.wallets.get_owned = MagicMock(return_value=entry_order["amount"] * factor) trade.orders.append(Order.parse_from_ccxt_object(entry_order, "ADA/USDT", entry_side(is_short))) Trade.session.add(trade) diff --git a/tests/test_wallets.py b/tests/test_wallets.py index f33222b7c..d68fbd226 100644 --- a/tests/test_wallets.py +++ b/tests/test_wallets.py @@ -65,6 +65,7 @@ def test_sync_wallet_at_boot(mocker, default_conf): assert freqtrade.wallets.get_free("GAS") == 0.270739 assert freqtrade.wallets.get_used("GAS") == 0.1 assert freqtrade.wallets.get_total("GAS") == 0.260439 + assert freqtrade.wallets.get_owned("GAS/USDT", "GAS") == 0.260439 update_mock = mocker.patch("freqtrade.wallets.Wallets._update_live") freqtrade.wallets.update(False) assert update_mock.call_count == 0 @@ -74,6 +75,7 @@ def test_sync_wallet_at_boot(mocker, default_conf): assert freqtrade.wallets.get_free("NOCURRENCY") == 0 assert freqtrade.wallets.get_used("NOCURRENCY") == 0 assert freqtrade.wallets.get_total("NOCURRENCY") == 0 + assert freqtrade.wallets.get_owned("NOCURRENCY/USDT", "NOCURRENCY") == 0 def test_sync_wallet_missing_data(mocker, default_conf): @@ -336,6 +338,8 @@ def test_sync_wallet_futures_live(mocker, default_conf): assert "USDT" in freqtrade.wallets._wallets assert "ETH/USDT:USDT" in freqtrade.wallets._positions assert freqtrade.wallets._last_wallet_refresh is not None + assert freqtrade.wallets.get_owned("ETH/USDT:USDT", "ETH") == 1000 + assert freqtrade.wallets.get_owned("SOL/USDT:USDT", "SOL") == 0 # Remove ETH/USDT:USDT position del mock_result[0]