From 9a8c24ddf3f199d05a15e0e011b8d85b4ea25e7b Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 26 Mar 2022 14:57:42 +0100 Subject: [PATCH] Update gateio to patch fees --- freqtrade/exchange/exchange.py | 4 ++++ freqtrade/exchange/gateio.py | 24 ++++++++++++++++++++++++ freqtrade/freqtradebot.py | 1 + tests/exchange/test_exchange.py | 6 ++---- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 1d4fc8337..3a39f9300 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -75,6 +75,7 @@ class Exchange: "mark_ohlcv_price": "mark", "mark_ohlcv_timeframe": "8h", "ccxt_futures_name": "swap", + "needs_trading_fees": False, # use fetch_trading_fees to cache fees } _ft_has: Dict = {} _ft_has_futures: Dict = {} @@ -451,6 +452,9 @@ class Exchange: self._markets = self._api.load_markets() self._load_async_markets() self._last_markets_refresh = arrow.utcnow().int_timestamp + if self._ft_has['needs_trading_fees']: + self.trading_fees = self.fetch_trading_fees() + except ccxt.BaseError: logger.exception('Unable to initialize markets.') diff --git a/freqtrade/exchange/gateio.py b/freqtrade/exchange/gateio.py index 50ff0c872..726b5c7ed 100644 --- a/freqtrade/exchange/gateio.py +++ b/freqtrade/exchange/gateio.py @@ -27,6 +27,10 @@ class Gateio(Exchange): "stoploss_on_exchange": True, } + _ft_has_futures: Dict = { + "needs_trading_fees": True + } + _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ # TradingMode.SPOT always supported and not required in this list # (TradingMode.MARGIN, MarginMode.CROSS), @@ -42,6 +46,26 @@ class Gateio(Exchange): raise OperationalException( f'Exchange {self.name} does not support market orders.') + def fetch_order(self, order_id: str, pair: str, params={}) -> Dict: + order = super().fetch_order(order_id, pair, params) + + if self.trading_mode == TradingMode.FUTURES and order.get('fee') is None: + # Futures usually don't contain fees in the response. + # As such, futures orders on gateio will not contain a fee, which causes + # a repeated "update fee" cycle and wrong calculations. + # Therefore we patch the response with fees if it's not available. + # An alternative also contianing fees would be + # privateFuturesGetSettleAccountBook({"settle": "usdt"}) + + pair_fees = self.trading_fees.get(pair, {}) + if pair_fees and pair_fees['taker'] is not None: + order['fee'] = { + 'currency': self.get_pair_quote_currency(pair), + 'cost': abs(order['cost']) * pair_fees['taker'], + 'rate': pair_fees['taker'], + } + return order + def fetch_stoploss_order(self, order_id: str, pair: str, params={}) -> Dict: return self.fetch_order( order_id=order_id, diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 089a5804a..ebc129777 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -1564,6 +1564,7 @@ class FreqtradeBot(LoggingMixin): if not order_obj: raise DependencyException( f"Order_obj not found for {order_id}. This should not have happened.") + self.handle_order_fee(trade, order_obj, order) trade.update_trade(order_obj) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index d19baf39a..24ca47e8b 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -1663,11 +1663,9 @@ def test_fetch_trading_fees(default_conf, mocker): 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 '1INCH/USDT:USDT' in exchange.trading_fees + assert 'ETH/USDT:USDT' in exchange.trading_fees assert api_mock.fetch_trading_fees.call_count == 1 api_mock.fetch_trading_fees.reset_mock()