From 33229c91cb160f836eecf28d4949e519034b6339 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 26 Mar 2022 13:53:36 +0100 Subject: [PATCH] Add fetch_trading_fees endpoint --- freqtrade/exchange/exchange.py | 21 ++++++++++++ tests/exchange/test_exchange.py | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index e27a56aff..1d4fc8337 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1299,6 +1299,27 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(e) from e + @retrier + def fetch_trading_fees(self) -> Dict[str, Any]: + """ + Fetch user account trading fees + Can be cached, should not update often. + """ + if (self._config['dry_run'] or self.trading_mode != TradingMode.FUTURES + or not self.exchange_has('fetchTradingFees')): + return {} + try: + trading_fees: Dict[str, Any] = self._api.fetch_trading_fees() + self._log_exchange_response('fetch_trading_fees', trading_fees) + return trading_fees + except ccxt.DDoSProtection as e: + raise DDosProtection(e) from e + except (ccxt.NetworkError, ccxt.ExchangeError) as e: + raise TemporaryError( + f'Could not fetch trading fees due to {e.__class__.__name__}. Message: {e}') from e + except ccxt.BaseError as e: + raise OperationalException(e) from e + @retrier def fetch_bids_asks(self, symbols: List[str] = None, cached: bool = False) -> Dict: """ diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 815ebcec2..d19baf39a 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1624,6 +1624,64 @@ def test_fetch_positions(default_conf, mocker, exchange_name): "fetch_positions", "fetch_positions") +def test_fetch_trading_fees(default_conf, mocker): + api_mock = MagicMock() + tick = { + '1INCH/USDT:USDT': { + 'info': {'user_id': '6266643', + 'taker_fee': '0.0018', + 'maker_fee': '0.0018', + 'gt_discount': False, + 'gt_taker_fee': '0', + 'gt_maker_fee': '0', + 'loan_fee': '0.18', + 'point_type': '1', + 'futures_taker_fee': '0.0005', + 'futures_maker_fee': '0'}, + 'symbol': '1INCH/USDT:USDT', + 'maker': 0.0, + 'taker': 0.0005}, + 'ETH/USDT:USDT': { + 'info': {'user_id': '6266643', + 'taker_fee': '0.0018', + 'maker_fee': '0.0018', + 'gt_discount': False, + 'gt_taker_fee': '0', + 'gt_maker_fee': '0', + 'loan_fee': '0.18', + 'point_type': '1', + 'futures_taker_fee': '0.0005', + 'futures_maker_fee': '0'}, + 'symbol': 'ETH/USDT:USDT', + 'maker': 0.0, + 'taker': 0.0005} + } + exchange_name = 'gateio' + default_conf['dry_run'] = False + default_conf['trading_mode'] = TradingMode.FUTURES + default_conf['margin_mode'] = MarginMode.ISOLATED + api_mock.fetch_trading_fees = MagicMock(return_value=tick) + mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True) + exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) + # retrieve original ticker + tradingfees = exchange.fetch_trading_fees() + + assert '1INCH/USDT:USDT' in tradingfees + assert 'ETH/USDT:USDT' in tradingfees + assert api_mock.fetch_trading_fees.call_count == 1 + + api_mock.fetch_trading_fees.reset_mock() + + ccxt_exceptionhandlers(mocker, default_conf, api_mock, exchange_name, + "fetch_trading_fees", "fetch_trading_fees") + + api_mock.fetch_trading_fees = MagicMock(return_value={}) + exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) + exchange.fetch_trading_fees() + mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True) + assert exchange.fetch_trading_fees() == {} + + def test_fetch_bids_asks(default_conf, mocker): api_mock = MagicMock() tick = {'ETH/BTC': {