moved dry run check for funding fees to exchange

This commit is contained in:
Sam Germain 2021-11-08 01:50:50 -06:00
parent 252e45ebf2
commit bea37e5ea3
3 changed files with 55 additions and 34 deletions

View File

@ -1606,7 +1606,7 @@ class Exchange:
until=until, from_id=from_id))
@retrier
def get_funding_fees_from_exchange(self, pair: str, since: Union[datetime, int]) -> float:
def _get_funding_fees_from_exchange(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)
@ -1794,7 +1794,7 @@ class Exchange:
raise OperationalException(f'Could not fetch historical mark price candle (OHLCV) data '
f'for pair {pair}. Message: {e}') from e
def calculate_funding_fees(
def _calculate_funding_fees(
self,
pair: str,
amount: float,
@ -1825,16 +1825,43 @@ class Exchange:
funding_fee_dates = self._get_funding_fee_dates(open_date, close_date)
for date in funding_fee_dates:
timestamp = int(date.timestamp()) * 1000
funding_rate = funding_rate_history[timestamp]
mark_price = mark_price_history[timestamp]
fees += self._get_funding_fee(
size=amount,
mark_price=mark_price,
funding_rate=funding_rate
)
if timestamp in funding_rate_history:
funding_rate = funding_rate_history[timestamp]
else:
logger.warning(
f"Funding rate for {pair} at {date} not found in funding_rate_history"
f"Funding fee calculation may be incorrect"
)
if timestamp in mark_price_history:
mark_price = mark_price_history[timestamp]
else:
logger.warning(
f"Mark price for {pair} at {date} not found in funding_rate_history"
f"Funding fee calculation may be incorrect"
)
if funding_rate and mark_price:
fees += self._get_funding_fee(
size=amount,
mark_price=mark_price,
funding_rate=funding_rate
)
return fees
def get_funding_fees(self, pair: str, amount: float, open_date: datetime):
if self._config['dry_run']:
funding_fees = self._calculate_funding_fees(
pair,
amount,
open_date
)
else:
funding_fees = self._get_funding_fees_from_exchange(
pair,
open_date
)
return funding_fees
@retrier
def get_funding_rate_history(
self,

View File

@ -270,17 +270,11 @@ class FreqtradeBot(LoggingMixin):
if self.trading_mode == TradingMode.FUTURES:
trades = Trade.get_open_trades()
for trade in trades:
if self.config['dry_run']:
funding_fees = self.exchange.calculate_funding_fees(
trade.pair,
trade.amount,
trade.open_date
)
else:
funding_fees = self.exchange.get_funding_fees_from_exchange(
trade.pair,
trade.open_date
)
funding_fees = self.exchange.get_funding_fees(
trade.pair,
trade.amount,
trade.open_date
)
trade.funding_fees = funding_fees
def startup_update_open_orders(self):
@ -712,7 +706,7 @@ class FreqtradeBot(LoggingMixin):
fee = self.exchange.get_fee(symbol=pair, taker_or_maker='maker')
open_date = datetime.now(timezone.utc)
if self.trading_mode == TradingMode.FUTURES:
funding_fees = self.exchange.get_funding_fees_from_exchange(pair, open_date)
funding_fees = self.exchange.get_funding_fees(pair, amount, open_date)
else:
funding_fees = 0.0

View File

@ -3058,7 +3058,7 @@ def test_calculate_backoff(retrycount, max_retries, expected):
@pytest.mark.parametrize("exchange_name", ['binance', 'ftx'])
def test_get_funding_fees_from_exchange(default_conf, mocker, exchange_name):
def test__get_funding_fees_from_exchange(default_conf, mocker, exchange_name):
api_mock = MagicMock()
api_mock.fetch_funding_history = MagicMock(return_value=[
{
@ -3101,11 +3101,11 @@ def test_get_funding_fees_from_exchange(default_conf, mocker, exchange_name):
date_time = datetime.strptime("2021-09-01T00:00:01.000Z", '%Y-%m-%dT%H:%M:%S.%fZ')
unix_time = int(date_time.timestamp())
expected_fees = -0.001 # 0.14542341 + -0.14642341
fees_from_datetime = exchange.get_funding_fees_from_exchange(
fees_from_datetime = exchange._get_funding_fees_from_exchange(
pair='XRP/USDT',
since=date_time
)
fees_from_unix_time = exchange.get_funding_fees_from_exchange(
fees_from_unix_time = exchange._get_funding_fees_from_exchange(
pair='XRP/USDT',
since=unix_time
)
@ -3118,7 +3118,7 @@ def test_get_funding_fees_from_exchange(default_conf, mocker, exchange_name):
default_conf,
api_mock,
exchange_name,
"get_funding_fees_from_exchange",
"_get_funding_fees_from_exchange",
"fetch_funding_history",
pair="XRP/USDT",
since=unix_time
@ -3519,7 +3519,7 @@ def test_get_funding_rate_history(mocker, default_conf, funding_rate_history):
('binance', "2021-09-01 00:00:00", "2021-09-01 07:59:59", 30.0, -0.0006647999999999999),
('binance', "2021-09-01 00:00:00", "2021-09-01 12:00:00", 30.0, -0.0009140999999999999),
('binance', "2021-09-01 00:00:01", "2021-09-01 08:00:00", 30.0, -0.0009140999999999999),
# TODO: Uncoment once calculate_funding_fees can pass time_in_ratio to exchange._get_funding_fee
# TODO: Uncoment once _calculate_funding_fees can pas time_in_ratio to exchange._get_funding_fee
# ('kraken', "2021-09-01 00:00:00", "2021-09-01 08:00:00", 30.0, -0.0014937),
# ('kraken', "2021-09-01 00:00:15", "2021-09-01 08:00:00", 30.0, -0.0008289),
# ('kraken', "2021-09-01 01:00:14", "2021-09-01 08:00:00", 30.0, -0.0008289),
@ -3533,11 +3533,11 @@ def test_get_funding_rate_history(mocker, default_conf, funding_rate_history):
('gateio', "2021-09-01 00:00:00", "2021-09-01 12:00:00", 30.0, -0.0009140999999999999),
('gateio', "2021-09-01 00:00:01", "2021-09-01 08:00:00", 30.0, -0.0002493),
('binance', "2021-09-01 00:00:00", "2021-09-01 08:00:00", 50.0, -0.0015235000000000001),
# TODO: Uncoment once calculate_funding_fees can pass time_in_ratio to exchange._get_funding_fee
# TODO: Uncoment once _calculate_funding_fees can pas time_in_ratio to exchange._get_funding_fee
# ('kraken', "2021-09-01 00:00:00", "2021-09-01 08:00:00", 50.0, -0.0024895),
('ftx', "2021-09-01 00:00:00", "2021-09-01 08:00:00", 50.0, 0.0016680000000000002),
])
def test_calculate_funding_fees(
def test__calculate_funding_fees(
mocker,
default_conf,
funding_rate_history,
@ -3592,18 +3592,18 @@ def test_calculate_funding_fees(
type(api_mock).has = PropertyMock(return_value={'fetchFundingRateHistory': True})
exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange)
funding_fees = exchange.calculate_funding_fees('ADA/USDT', amount, d1, d2)
funding_fees = exchange._calculate_funding_fees('ADA/USDT', amount, d1, d2)
assert funding_fees == expected_fees
@pytest.mark.parametrize('name,expected_fees_8,expected_fees_10,expected_fees_12', [
('binance', -0.0009140999999999999, -0.0009140999999999999, -0.0009140999999999999),
# TODO: Uncoment once calculate_funding_fees can pass time_in_ratio to exchange._get_funding_fee
# TODO: Uncoment once _calculate_funding_fees can pas time_in_ratio to exchange._get_funding_fee
# ('kraken', -0.0014937, -0.0014937, 0.0045759),
('ftx', 0.0010008000000000003, 0.0021084, 0.0146691),
('gateio', -0.0009140999999999999, -0.0009140999999999999, -0.0009140999999999999),
])
def test_calculate_funding_fees_datetime_called(
def test__calculate_funding_fees_datetime_called(
mocker,
default_conf,
funding_rate_history,
@ -3624,11 +3624,11 @@ def test_calculate_funding_fees_datetime_called(
d1 = datetime.strptime("2021-09-01 00:00:00 +0000", '%Y-%m-%d %H:%M:%S %z')
time_machine.move_to("2021-09-01 08:00:00 +00:00")
funding_fees = exchange.calculate_funding_fees('ADA/USDT', 30.0, d1)
funding_fees = exchange._calculate_funding_fees('ADA/USDT', 30.0, d1)
assert funding_fees == expected_fees_8
time_machine.move_to("2021-09-01 10:00:00 +00:00")
funding_fees = exchange.calculate_funding_fees('ADA/USDT', 30.0, d1)
funding_fees = exchange._calculate_funding_fees('ADA/USDT', 30.0, d1)
assert funding_fees == expected_fees_10
time_machine.move_to("2021-09-01 12:00:00 +00:00")
funding_fees = exchange.calculate_funding_fees('ADA/USDT', 30.0, d1)
funding_fees = exchange._calculate_funding_fees('ADA/USDT', 30.0, d1)
assert funding_fees == expected_fees_12