From 92e630eb696a97217a7b4246f8bee6bb71408c32 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Wed, 1 Sep 2021 20:34:01 -0600 Subject: [PATCH] Added get_funding_fees method to exchange --- freqtrade/exchange/exchange.py | 23 ++++++++--- tests/exchange/test_exchange.py | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 168dcd575..67eb0ad15 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -9,7 +9,7 @@ import logging from copy import deepcopy from datetime import datetime, timezone from math import ceil -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple, Union import arrow import ccxt @@ -1516,15 +1516,28 @@ class Exchange: self._async_get_trade_history(pair=pair, since=since, until=until, from_id=from_id)) - def get_funding_fees(self, pair: str, since: datetime): + @retrier + def get_funding_fees(self, pair: str, since: Union[datetime, int]) -> float: + """ + Returns the sum of all funding fees that were exchanged for a pair within a timeframe + :param pair: (e.g. ADA/USDT) + :param since: The earliest time of consideration for calculating funding fees, + in unix time or as a datetime + """ + + if not self.exchange_has("fetchFundingHistory"): + raise OperationalException( + f"fetch_funding_history() has not been implemented on ccxt.{self.name}") + + if type(since) is datetime: + since = int(since.strftime('%s')) + try: funding_history = self._api.fetch_funding_history( pair=pair, since=since ) - # TODO: sum all the funding fees in funding_history together - funding_fees = funding_history - return funding_fees + return sum(fee['amount'] for fee in funding_history) except ccxt.DDoSProtection as e: raise DDosProtection(e) from e except (ccxt.NetworkError, ccxt.ExchangeError) as e: diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 42da5dddc..e2a6639a3 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -2926,3 +2926,71 @@ def test_calculate_fee_rate(mocker, default_conf, order, expected) -> None: ]) def test_calculate_backoff(retrycount, max_retries, expected): assert calculate_backoff(retrycount, max_retries) == expected + + +@pytest.mark.parametrize("exchange_name", ['binance', 'ftx']) +def test_get_funding_fees(default_conf, mocker, exchange_name): + api_mock = MagicMock() + api_mock.fetch_funding_history = MagicMock(return_value=[ + { + 'amount': 0.14542341, + 'code': 'USDT', + 'datetime': '2021-09-01T08:00:01.000Z', + 'id': '485478', + 'info': {'asset': 'USDT', + 'income': '0.14542341', + 'incomeType': 'FUNDING_FEE', + 'info': 'FUNDING_FEE', + 'symbol': 'XRPUSDT', + 'time': '1630512001000', + 'tradeId': '', + 'tranId': '4854789484855218760'}, + 'symbol': 'XRP/USDT', + 'timestamp': 1630512001000 + }, + { + 'amount': -0.14642341, + 'code': 'USDT', + 'datetime': '2021-09-01T16:00:01.000Z', + 'id': '485479', + 'info': {'asset': 'USDT', + 'income': '-0.14642341', + 'incomeType': 'FUNDING_FEE', + 'info': 'FUNDING_FEE', + 'symbol': 'XRPUSDT', + 'time': '1630512001000', + 'tradeId': '', + 'tranId': '4854789484855218760'}, + 'symbol': 'XRP/USDT', + 'timestamp': 1630512001000 + } + ]) + type(api_mock).has = PropertyMock(return_value={'fetchFundingHistory': True}) + + # mocker.patch('freqtrade.exchange.Exchange.get_funding_fees', lambda pair, since: y) + exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) + date_time = datetime.strptime("2021-09-01T00:00:01.000Z", '%Y-%m-%dT%H:%M:%S.%fZ') + unix_time = int(date_time.strftime('%s')) + expected_fees = -0.001 # 0.14542341 + -0.14642341 + fees_from_datetime = exchange.get_funding_fees( + pair='XRP/USDT', + since=date_time + ) + fees_from_unix_time = exchange.get_funding_fees( + pair='XRP/USDT', + since=unix_time + ) + + assert(isclose(expected_fees, fees_from_datetime)) + assert(isclose(expected_fees, fees_from_unix_time)) + + ccxt_exceptionhandlers( + mocker, + default_conf, + api_mock, + exchange_name, + "get_funding_fees", + "fetch_funding_history", + pair="XRP/USDT", + since=unix_time + )