From 5abd616ae998c8e92eb70d239e78d54357778a8b Mon Sep 17 00:00:00 2001 From: Achmad Fathoni Date: Tue, 2 May 2023 23:01:51 +0700 Subject: [PATCH 1/5] Fix disrepancy in freqai doc code example --- docs/freqai-configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/freqai-configuration.md b/docs/freqai-configuration.md index e7aca20be..6b4112ebd 100644 --- a/docs/freqai-configuration.md +++ b/docs/freqai-configuration.md @@ -43,10 +43,10 @@ The FreqAI strategy requires including the following lines of code in the standa def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - # the model will return all labels created by user in `set_freqai_labels()` + # the model will return all labels created by user in `feature_engineering_*` # (& appended targets), an indication of whether or not the prediction should be accepted, # the target mean/std values for each of the labels created by user in - # `feature_engineering_*` for each training period. + # `set_freqai_targets()` for each training period. dataframe = self.freqai.start(dataframe, metadata, self) From 265d782af8e906e92636fe519b0a75ca29126680 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 10 Jun 2023 09:29:14 +0200 Subject: [PATCH 2/5] Implement the requested changes. --- docs/freqai-configuration.md | 2 +- freqtrade/templates/FreqaiExampleStrategy.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/freqai-configuration.md b/docs/freqai-configuration.md index 6b4112ebd..692daaf1e 100644 --- a/docs/freqai-configuration.md +++ b/docs/freqai-configuration.md @@ -43,7 +43,7 @@ The FreqAI strategy requires including the following lines of code in the standa def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - # the model will return all labels created by user in `feature_engineering_*` + # the model will return all labels created by user in `set_freqai_targets()` # (& appended targets), an indication of whether or not the prediction should be accepted, # the target mean/std values for each of the labels created by user in # `set_freqai_targets()` for each training period. diff --git a/freqtrade/templates/FreqaiExampleStrategy.py b/freqtrade/templates/FreqaiExampleStrategy.py index 493ea17f3..e0b4d045b 100644 --- a/freqtrade/templates/FreqaiExampleStrategy.py +++ b/freqtrade/templates/FreqaiExampleStrategy.py @@ -229,7 +229,7 @@ class FreqaiExampleStrategy(IStrategy): # All indicators must be populated by feature_engineering_*() functions - # the model will return all labels created by user in `feature_engineering_*` + # the model will return all labels created by user in `set_freqai_targets()` # (& appended targets), an indication of whether or not the prediction should be accepted, # the target mean/std values for each of the labels created by user in # `set_freqai_targets()` for each training period. From cfe88f06d2b990d7df7f8a1364b36ce126d6cb78 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 10 Jun 2023 16:29:43 +0200 Subject: [PATCH 3/5] Improve behavior of okx rebuys when using stop on exchange closes #8755 --- freqtrade/exchange/okx.py | 21 +++++++++++++++++++-- tests/exchange/test_okx.py | 4 ++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/okx.py b/freqtrade/exchange/okx.py index af889897c..8ad3c2cdb 100644 --- a/freqtrade/exchange/okx.py +++ b/freqtrade/exchange/okx.py @@ -125,6 +125,20 @@ class Okx(Exchange): params['posSide'] = self._get_posSide(side, reduceOnly) return params + def __fetch_leverage_already_set(self, pair: str, leverage: float, side: BuySell) -> bool: + try: + res_lev = self._api.fetch_leverage(symbol=pair, params={ + "mgnMode": self.margin_mode.value, + "posSide": self._get_posSide(side, False), + }) + self._log_exchange_response('get_leverage', res_lev) + already_set = all(float(x['lever']) == leverage for x in res_lev['data']) + return already_set + + except ccxt.BaseError: + # Assume all errors as "not set yet" + return False + @retrier def _lev_prep(self, pair: str, leverage: float, side: BuySell, accept_fail: bool = False): if self.trading_mode != TradingMode.SPOT and self.margin_mode is not None: @@ -141,8 +155,11 @@ class Okx(Exchange): except ccxt.DDoSProtection as e: raise DDosProtection(e) from e except (ccxt.NetworkError, ccxt.ExchangeError) as e: - raise TemporaryError( - f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e + already_set = self.__fetch_leverage_already_set(pair, leverage, side) + if not already_set: + raise TemporaryError( + f'Could not set leverage due to {e.__class__.__name__}. Message: {e}' + ) from e except ccxt.BaseError as e: raise OperationalException(e) from e diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index 3824eddb7..378466ae4 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -499,7 +499,11 @@ def test__set_leverage_okx(mocker, default_conf): assert api_mock.set_leverage.call_args_list[0][1]['params'] == { 'mgnMode': 'isolated', 'posSide': 'net'} + api_mock.set_leverage = MagicMock(side_effect=ccxt.NetworkError()) + exchange._lev_prep('BTC/USDT:USDT', 3.2, 'buy') + api_mock.fetch_leverage.call_count == 1 + api_mock.fetch_leverage = MagicMock(side_effect=ccxt.NetworkError()) ccxt_exceptionhandlers( mocker, default_conf, From 2806110869e7c1f08b411fb215ade1d332e35c6f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 10 Jun 2023 16:41:37 +0200 Subject: [PATCH 4/5] Add explicit test for okx cancel_stop --- tests/exchange/test_okx.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index 378466ae4..aaffff1df 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -596,3 +596,15 @@ def test_stoploss_adjust_okx(mocker, default_conf, sl1, sl2, sl3, side): } assert exchange.stoploss_adjust(sl1, order, side=side) assert not exchange.stoploss_adjust(sl2, order, side=side) + + +def test_stoploss_cancel_okx(mocker, default_conf): + exchange = get_patched_exchange(mocker, default_conf, id='okx') + + exchange.cancel_order = MagicMock() + + exchange.cancel_stoploss_order('1234', 'ETH/USDT') + assert exchange.cancel_order.call_count == 1 + assert exchange.cancel_order.call_args_list[0][1]['order_id'] == '1234' + assert exchange.cancel_order.call_args_list[0][1]['pair'] == 'ETH/USDT' + assert exchange.cancel_order.call_args_list[0][1]['params'] == {'stop': True} From e332fbfb47ba146c222f9d846d8f8d286fb416e1 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 10 Jun 2023 16:55:42 +0200 Subject: [PATCH 5/5] Add explicit test for okx get_stop_params --- tests/exchange/test_okx.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/exchange/test_okx.py b/tests/exchange/test_okx.py index aaffff1df..e8f059118 100644 --- a/tests/exchange/test_okx.py +++ b/tests/exchange/test_okx.py @@ -608,3 +608,13 @@ def test_stoploss_cancel_okx(mocker, default_conf): assert exchange.cancel_order.call_args_list[0][1]['order_id'] == '1234' assert exchange.cancel_order.call_args_list[0][1]['pair'] == 'ETH/USDT' assert exchange.cancel_order.call_args_list[0][1]['params'] == {'stop': True} + + +def test__get_stop_params_okx(mocker, default_conf): + default_conf['trading_mode'] = 'futures' + default_conf['margin_mode'] = 'isolated' + exchange = get_patched_exchange(mocker, default_conf, id='okx') + params = exchange._get_stop_params('ETH/USDT:USDT', 1500, 'sell') + + assert params['tdMode'] == 'isolated' + assert params['posSide'] == 'net'