From adce6e4f68fb85b05c4c4c1838137c2bf5b178d3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 24 May 2025 09:20:30 +0200 Subject: [PATCH] fix: don't try to place stoploss orders with blocking assets --- freqtrade/exchange/binance.py | 2 ++ freqtrade/exchange/bybit.py | 1 + freqtrade/exchange/exchange.py | 1 + freqtrade/exchange/exchange_types.py | 1 + freqtrade/exchange/gate.py | 1 + freqtrade/exchange/hyperliquid.py | 1 + freqtrade/exchange/okx.py | 1 + freqtrade/freqtradebot.py | 6 +++++- 8 files changed, 13 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index c58dde75b..a9693adbf 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -32,6 +32,7 @@ class Binance(Exchange): "stop_price_param": "stopPrice", "stop_price_prop": "stopPrice", "stoploss_order_types": {"limit": "stop_loss_limit"}, + "stoploss_blocks_assets": True, # By default stoploss orders block assets "order_time_in_force": ["GTC", "FOK", "IOC", "PO"], "trades_pagination": "id", "trades_pagination_arg": "fromId", @@ -43,6 +44,7 @@ class Binance(Exchange): _ft_has_futures: FtHas = { "funding_fee_candle_limit": 1000, "stoploss_order_types": {"limit": "stop", "market": "stop_market"}, + "stoploss_blocks_assets": False, # Stoploss orders do not block assets "order_time_in_force": ["GTC", "FOK", "IOC"], "tickers_have_price": False, "floor_leverage": True, diff --git a/freqtrade/exchange/bybit.py b/freqtrade/exchange/bybit.py index 97a5ab68e..e45adf4bb 100644 --- a/freqtrade/exchange/bybit.py +++ b/freqtrade/exchange/bybit.py @@ -49,6 +49,7 @@ class Bybit(Exchange): "funding_fee_candle_limit": 200, "stoploss_on_exchange": True, "stoploss_order_types": {"limit": "limit", "market": "market"}, + "stoploss_blocks_assets": False, # bybit response parsing fails to populate stopLossPrice "stop_price_prop": "stopPrice", "stop_price_type_field": "triggerBy", diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 3dd0eb489..88e392fc8 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -131,6 +131,7 @@ class Exchange: "stop_price_param": "stopLossPrice", # Used for stoploss_on_exchange request "stop_price_prop": "stopLossPrice", # Used for stoploss_on_exchange response parsing "stoploss_order_types": {}, + "stoploss_blocks_assets": True, # By default stoploss orders block assets "order_time_in_force": ["GTC"], "ohlcv_params": {}, "ohlcv_has_history": True, # Some exchanges (Kraken) don't provide history via ohlcv diff --git a/freqtrade/exchange/exchange_types.py b/freqtrade/exchange/exchange_types.py index 544f14ea6..02cd8d58a 100644 --- a/freqtrade/exchange/exchange_types.py +++ b/freqtrade/exchange/exchange_types.py @@ -15,6 +15,7 @@ class FtHas(TypedDict, total=False): stop_price_type_field: str stop_price_type_value_mapping: dict stoploss_order_types: dict[str, str] + stoploss_blocks_assets: bool # ohlcv ohlcv_params: dict ohlcv_candle_limit: int diff --git a/freqtrade/exchange/gate.py b/freqtrade/exchange/gate.py index 49f0ee74b..3fc0b0040 100644 --- a/freqtrade/exchange/gate.py +++ b/freqtrade/exchange/gate.py @@ -46,6 +46,7 @@ class Gate(Exchange): "funding_fee_candle_limit": 90, "stop_price_type_field": "price_type", "l2_limit_upper": 300, + "stoploss_blocks_assets": False, "stop_price_type_value_mapping": { PriceType.LAST: 0, PriceType.MARK: 1, diff --git a/freqtrade/exchange/hyperliquid.py b/freqtrade/exchange/hyperliquid.py index b6ec23942..ae1de3b64 100644 --- a/freqtrade/exchange/hyperliquid.py +++ b/freqtrade/exchange/hyperliquid.py @@ -32,6 +32,7 @@ class Hyperliquid(Exchange): _ft_has_futures: FtHas = { "stoploss_on_exchange": True, "stoploss_order_types": {"limit": "limit"}, + "stoploss_blocks_assets": False, "stop_price_prop": "stopPrice", "funding_fee_timeframe": "1h", "funding_fee_candle_limit": 500, diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index e9784f12e..bd25fccea 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -44,6 +44,7 @@ class Okx(Exchange): PriceType.MARK: "index", PriceType.INDEX: "mark", }, + "stoploss_blocks_assets": False, "ws_enabled": True, } diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 8ee65e2dd..1f0b862f6 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1476,7 +1476,11 @@ class FreqtradeBot(LoggingMixin): self.handle_protections(trade.pair, trade.trade_direction) return True - if not trade.has_open_position or not trade.is_open: + if ( + not trade.has_open_position + or not trade.is_open + or (trade.has_open_orders and self.exchange.get_option("stoploss_blocks_assets", True)) + ): # The trade can be closed already (sell-order fill confirmation came in this iteration) return False