From cf6b75a3f3a70740d6dff860f59ad51e5dc95a2a Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Oct 2022 07:12:42 +0200 Subject: [PATCH 1/3] Use combined stoploss_adjust where possible --- freqtrade/exchange/binance.py | 18 ------------------ freqtrade/exchange/exchange.py | 6 +++++- freqtrade/exchange/gateio.py | 10 ---------- tests/exchange/test_binance.py | 3 --- 4 files changed, 5 insertions(+), 32 deletions(-) diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index 6d818bab9..b21e64eb2 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -42,24 +42,6 @@ class Binance(Exchange): (TradingMode.FUTURES, MarginMode.ISOLATED) ] - def stoploss_adjust(self, stop_loss: float, order: Dict, side: str) -> bool: - """ - Verify stop_loss against stoploss-order value (limit or price) - Returns True if adjustment is necessary. - :param side: "buy" or "sell" - """ - order_types = ('stop_loss_limit', 'stop', 'stop_market') - - return ( - order.get('stopPrice', None) is None - or ( - order['type'] in order_types - and ( - (side == "sell" and stop_loss > float(order['stopPrice'])) or - (side == "buy" and stop_loss < float(order['stopPrice'])) - ) - )) - def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Tickers: tickers = super().get_tickers(symbols=symbols, cached=cached) if self.trading_mode == TradingMode.FUTURES: diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index ca53e5333..cdbe1804e 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1076,7 +1076,11 @@ class Exchange: Verify stop_loss against stoploss-order value (limit or price) Returns True if adjustment is necessary. """ - raise OperationalException(f"stoploss is not implemented for {self.name}.") + if not self._ft_has.get('stoploss_on_exchange'): + raise OperationalException(f"stoploss is not implemented for {self.name}.") + + return ((side == "sell" and stop_loss > float(order['stopPrice'])) or + (side == "buy" and stop_loss < float(order['stopPrice']))) def _get_stop_order_type(self, user_order_type) -> Tuple[str, str]: diff --git a/freqtrade/exchange/gateio.py b/freqtrade/exchange/gateio.py index ab127a036..de178af02 100644 --- a/freqtrade/exchange/gateio.py +++ b/freqtrade/exchange/gateio.py @@ -126,13 +126,3 @@ class Gateio(Exchange): pair=pair, params={'stop': True} ) - - def stoploss_adjust(self, stop_loss: float, order: Dict, side: str) -> bool: - """ - Verify stop_loss against stoploss-order value (limit or price) - Returns True if adjustment is necessary. - """ - return (order.get('stopPrice', None) is None or ( - side == "sell" and stop_loss > float(order['stopPrice'])) or - (side == "buy" and stop_loss < float(order['stopPrice'])) - ) diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 75aaa0081..1fc8b4153 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -162,9 +162,6 @@ def test_stoploss_adjust_binance(mocker, default_conf, sl1, sl2, sl3, side): } assert exchange.stoploss_adjust(sl1, order, side=side) assert not exchange.stoploss_adjust(sl2, order, side=side) - # Test with invalid order case - order['type'] = 'stop_loss' - assert not exchange.stoploss_adjust(sl3, order, side=side) def test_fill_leverage_tiers_binance(default_conf, mocker): From 6e0ca058f4054ee80bcd2af7c5178e1d403cfc4f Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Oct 2022 07:12:49 +0200 Subject: [PATCH 2/3] Update function-head for _get_stop_params --- freqtrade/exchange/exchange.py | 5 +++-- freqtrade/exchange/huobi.py | 3 ++- freqtrade/exchange/kucoin.py | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index cdbe1804e..5959e457e 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1110,7 +1110,7 @@ class Exchange: 'In stoploss limit order, stop price should be more than limit price') return limit_rate - def _get_stop_params(self, ordertype: str, stop_price: float) -> Dict: + def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> Dict: params = self._params.copy() # Verify if stopPrice works for your exchange! params.update({'stopPrice': stop_price}) @@ -1159,7 +1159,8 @@ class Exchange: return dry_order try: - params = self._get_stop_params(ordertype=ordertype, stop_price=stop_price_norm) + params = self._get_stop_params(side=side, ordertype=ordertype, + stop_price=stop_price_norm) if self.trading_mode == TradingMode.FUTURES: params['reduceOnly'] = True diff --git a/freqtrade/exchange/huobi.py b/freqtrade/exchange/huobi.py index 736515dec..714b154aa 100644 --- a/freqtrade/exchange/huobi.py +++ b/freqtrade/exchange/huobi.py @@ -2,6 +2,7 @@ import logging from typing import Dict +from freqtrade.constants import BuySell from freqtrade.exchange import Exchange @@ -35,7 +36,7 @@ class Huobi(Exchange): ) ) - def _get_stop_params(self, ordertype: str, stop_price: float) -> Dict: + def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> Dict: params = self._params.copy() params.update({ diff --git a/freqtrade/exchange/kucoin.py b/freqtrade/exchange/kucoin.py index f05fd3f56..10b0f7c7e 100644 --- a/freqtrade/exchange/kucoin.py +++ b/freqtrade/exchange/kucoin.py @@ -2,6 +2,7 @@ import logging from typing import Dict +from freqtrade.constants import BuySell from freqtrade.exchange import Exchange @@ -37,7 +38,7 @@ class Kucoin(Exchange): or stop_loss > float(order['stopPrice']) ) - def _get_stop_params(self, ordertype: str, stop_price: float) -> Dict: + def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> Dict: params = self._params.copy() params.update({ From 255f38537ed0d5ece65f4a7923ae472d4cf49d46 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 26 Oct 2022 07:14:33 +0200 Subject: [PATCH 3/3] Simplify stoploss behavior by combining more commonalities --- freqtrade/exchange/exchange.py | 5 ++++- freqtrade/exchange/huobi.py | 13 ------------- freqtrade/exchange/kucoin.py | 10 ---------- tests/exchange/test_huobi.py | 3 +-- 4 files changed, 5 insertions(+), 26 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 5959e457e..4c660142b 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1079,8 +1079,11 @@ class Exchange: if not self._ft_has.get('stoploss_on_exchange'): raise OperationalException(f"stoploss is not implemented for {self.name}.") - return ((side == "sell" and stop_loss > float(order['stopPrice'])) or + return ( + order.get('stopPrice', None) is None + or ((side == "sell" and stop_loss > float(order['stopPrice'])) or (side == "buy" and stop_loss < float(order['stopPrice']))) + ) def _get_stop_order_type(self, user_order_type) -> Tuple[str, str]: diff --git a/freqtrade/exchange/huobi.py b/freqtrade/exchange/huobi.py index 714b154aa..fdb6050a3 100644 --- a/freqtrade/exchange/huobi.py +++ b/freqtrade/exchange/huobi.py @@ -23,19 +23,6 @@ class Huobi(Exchange): "l2_limit_range_required": False, } - def stoploss_adjust(self, stop_loss: float, order: Dict, side: str) -> bool: - """ - Verify stop_loss against stoploss-order value (limit or price) - Returns True if adjustment is necessary. - """ - return ( - order.get('stopPrice', None) is None - or ( - order['type'] == 'stop' - and stop_loss > float(order['stopPrice']) - ) - ) - def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> Dict: params = self._params.copy() diff --git a/freqtrade/exchange/kucoin.py b/freqtrade/exchange/kucoin.py index 10b0f7c7e..6c7d7acfc 100644 --- a/freqtrade/exchange/kucoin.py +++ b/freqtrade/exchange/kucoin.py @@ -28,16 +28,6 @@ class Kucoin(Exchange): "ohlcv_candle_limit": 1500, } - def stoploss_adjust(self, stop_loss: float, order: Dict, side: str) -> bool: - """ - Verify stop_loss against stoploss-order value (limit or price) - Returns True if adjustment is necessary. - """ - return ( - order.get('stopPrice', None) is None - or stop_loss > float(order['stopPrice']) - ) - def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> Dict: params = self._params.copy() diff --git a/tests/exchange/test_huobi.py b/tests/exchange/test_huobi.py index fc7c7cefb..2ce379a47 100644 --- a/tests/exchange/test_huobi.py +++ b/tests/exchange/test_huobi.py @@ -113,5 +113,4 @@ def test_stoploss_adjust_huobi(mocker, default_conf): assert exchange.stoploss_adjust(1501, order, 'sell') assert not exchange.stoploss_adjust(1499, order, 'sell') # Test with invalid order case - order['type'] = 'stop_loss' - assert not exchange.stoploss_adjust(1501, order, 'sell') + assert exchange.stoploss_adjust(1501, order, 'sell')