diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index a87a5dc55..f7eb03b57 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -1,7 +1,6 @@ """ Binance exchange subclass """ import logging -from datetime import datetime -from typing import Any, Dict, List, Optional +from typing import Dict, List import arrow import ccxt @@ -27,13 +26,6 @@ class Binance(Exchange): "l2_limit_range": [5, 10, 20, 50, 100, 500, 1000], } funding_fee_times: List[int] = [0, 8, 16] # hours of the day - _funding_interest_rates: Dict = {} # TODO-lev: delete - - def __init__(self, config: Dict[str, Any], validate: bool = True) -> None: - super().__init__(config, validate) - # TODO-lev: Uncomment once lev-exchange merged in - # if self.trading_mode == TradingMode.FUTURES: - # self._funding_interest_rates = self._get_funding_interest_rates() def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: """ @@ -101,51 +93,6 @@ class Binance(Exchange): except ccxt.BaseError as e: raise OperationalException(e) from e - def _get_premium_index(self, pair: str, date: datetime) -> float: - raise OperationalException(f'_get_premium_index has not been implemented on {self.name}') - - def _get_mark_price(self, pair: str, date: datetime) -> float: - raise OperationalException(f'_get_mark_price has not been implemented on {self.name}') - - def _get_funding_interest_rates(self): - rates = self._api.fetch_funding_rates() - interest_rates = {} - for pair, data in rates.items(): - interest_rates[pair] = data['interestRate'] - return interest_rates - - def _calculate_funding_rate(self, pair: str, premium_index: float) -> Optional[float]: - """ - Get's the funding_rate for a pair at a specific date and time in the past - """ - return ( - premium_index + - max(min(self._funding_interest_rates[pair] - premium_index, 0.0005), -0.0005) - ) - - def _get_funding_fee( - self, - pair: str, - contract_size: float, - mark_price: float, - premium_index: Optional[float], - ) -> float: - """ - Calculates a single funding fee - :param contract_size: The amount/quanity - :param mark_price: The price of the asset that the contract is based off of - :param funding_rate: the interest rate and the premium - - interest rate: 0.03% daily, BNBUSDT, LINKUSDT, and LTCUSDT are 0% - - premium: varies by price difference between the perpetual contract and mark price - """ - if premium_index is None: - raise OperationalException("Premium index cannot be None for Binance._get_funding_fee") - nominal_value = mark_price * contract_size - funding_rate = self._calculate_funding_rate(pair, premium_index) - if funding_rate is None: - raise OperationalException("Funding rate should never be none on Binance") - return nominal_value * funding_rate - async def _async_get_historic_ohlcv(self, pair: str, timeframe: str, since_ms: int, is_new_pair: bool ) -> List: diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 7e1fb9e57..786b8d168 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -1529,14 +1529,6 @@ class Exchange: self._async_get_trade_history(pair=pair, since=since, until=until, from_id=from_id)) - # https://www.binance.com/en/support/faq/360033525031 - def fetch_funding_rate(self, pair): - if not self.exchange_has("fetchFundingHistory"): - raise OperationalException( - f"fetch_funding_history() has not been implemented on ccxt.{self.name}") - - return self._api.fetch_funding_rates() - @retrier def get_funding_fees_from_exchange(self, pair: str, since: Union[datetime, int]) -> float: """ @@ -1567,37 +1559,6 @@ class Exchange: except ccxt.BaseError as e: raise OperationalException(e) from e - def _get_premium_index(self, pair: str, date: datetime) -> float: - raise OperationalException(f'_get_premium_index has not been implemented on {self.name}') - - def _get_mark_price(self, pair: str, date: datetime) -> float: - raise OperationalException(f'_get_mark_price has not been implemented on {self.name}') - - def _get_funding_rate(self, pair: str, when: datetime): - """ - Get's the funding_rate for a pair at a specific date and time in the past - """ - # TODO-lev: implement - raise OperationalException(f"get_funding_rate has not been implemented for {self.name}") - - def _get_funding_fee( - self, - pair: str, - contract_size: float, - mark_price: float, - premium_index: Optional[float], - # index_price: float, - # interest_rate: float) - ) -> float: - """ - Calculates a single funding fee - :param contract_size: The amount/quanity - :param mark_price: The price of the asset that the contract is based off of - :param funding_rate: the interest rate and the premium - - premium: varies by price difference between the perpetual contract and mark price - """ - raise OperationalException(f"Funding fee has not been implemented for {self.name}") - def _get_funding_fee_dates(self, open_date: datetime, close_date: datetime): """ Get's the date and time of every funding fee that happened between two datetimes @@ -1614,34 +1575,6 @@ class Exchange: return results - def calculate_funding_fees( - self, - pair: str, - amount: float, - open_date: datetime, - close_date: datetime - ) -> float: - """ - calculates the sum of all funding fees that occurred for a pair during a futures trade - :param pair: The quote/base pair of the trade - :param amount: The quantity of the trade - :param open_date: The date and time that the trade started - :param close_date: The date and time that the trade ended - """ - - fees: float = 0 - for date in self._get_funding_fee_dates(open_date, close_date): - premium_index = self._get_premium_index(pair, date) - mark_price = self._get_mark_price(pair, date) - fees += self._get_funding_fee( - pair=pair, - contract_size=amount, - mark_price=mark_price, - premium_index=premium_index - ) - - return fees - def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool: return exchange_name in ccxt_exchanges(ccxt_module) diff --git a/freqtrade/exchange/ftx.py b/freqtrade/exchange/ftx.py index ae3659711..8abf84104 100644 --- a/freqtrade/exchange/ftx.py +++ b/freqtrade/exchange/ftx.py @@ -1,7 +1,6 @@ """ FTX exchange subclass """ import logging -from datetime import datetime -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List import ccxt @@ -154,25 +153,3 @@ class Ftx(Exchange): if order['type'] == 'stop': return safe_value_fallback2(order, order, 'id_stop', 'id') return order['id'] - - def _get_funding_rate(self, pair: str, when: datetime) -> Optional[float]: - """FTX doesn't use this""" - return None - - def _get_funding_fee( - self, - pair: str, - contract_size: float, - mark_price: float, - premium_index: Optional[float], - # index_price: float, - # interest_rate: float) - ) -> float: - """ - Calculates a single funding fee - Always paid in USD on FTX # TODO: How do we account for this - : param contract_size: The amount/quanity - : param mark_price: The price of the asset that the contract is based off of - : param funding_rate: Must be None on ftx - """ - return (contract_size * mark_price) / 24 diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index 5f7c2c080..9de1947db 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -707,7 +707,6 @@ class LocalTrade(): return float(self._calc_base_close(amount, rate, fee) - total_interest) elif (trading_mode == TradingMode.FUTURES): - self.add_funding_fees() funding_fees = self.funding_fees or 0.0 return float(self._calc_base_close(amount, rate, fee)) + funding_fees else: @@ -786,19 +785,6 @@ class LocalTrade(): else: return None - def add_funding_fees(self): - if self.trading_mode == TradingMode.FUTURES: - # TODO-lev: Calculate this correctly and add it - # if self.config['runmode'].value in ('backtest', 'hyperopt'): - # self.funding_fees = getattr(Exchange, self.exchange).calculate_funding_fees( - # self.exchange, - # self.pair, - # self.amount, - # self.open_date_utc, - # self.close_date_utc - # ) - return - @staticmethod def get_trades_proxy(*, pair: str = None, is_open: bool = None, open_date: datetime = None, close_date: datetime = None, diff --git a/tests/exchange/test_binance.py b/tests/exchange/test_binance.py index 6c8798015..dd85c3abe 100644 --- a/tests/exchange/test_binance.py +++ b/tests/exchange/test_binance.py @@ -108,14 +108,6 @@ def test_stoploss_adjust_binance(mocker, default_conf): assert not exchange.stoploss_adjust(1501, order) -def test_get_funding_rate(): - return - - -def test__get_funding_fee(): - return - - @pytest.mark.asyncio async def test__async_get_historic_ohlcv_binance(default_conf, mocker, caplog): ohlcv = [ diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index abbbbe4a7..561a9cec5 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -3044,15 +3044,3 @@ def test_get_funding_fees(default_conf, mocker, exchange_name): pair="XRP/USDT", since=unix_time ) - - -def test_get_mark_price(): - return - - -def test_get_funding_fee_dates(): - return - - -def test_calculate_funding_fees(): - return diff --git a/tests/exchange/test_ftx.py b/tests/exchange/test_ftx.py index a4281c595..3794bb79c 100644 --- a/tests/exchange/test_ftx.py +++ b/tests/exchange/test_ftx.py @@ -1,4 +1,3 @@ -from datetime import datetime, timedelta from random import randint from unittest.mock import MagicMock @@ -192,18 +191,3 @@ def test_get_order_id(mocker, default_conf): } } assert exchange.get_order_id_conditional(order) == '1111' - - -@pytest.mark.parametrize("pair,when", [ - ('XRP/USDT', datetime.utcnow()), - ('ADA/BTC', datetime.utcnow()), - ('XRP/USDT', datetime.utcnow() - timedelta(hours=30)), -]) -def test__get_funding_rate(default_conf, mocker, pair, when): - api_mock = MagicMock() - exchange = get_patched_exchange(mocker, default_conf, api_mock, id="ftx") - assert exchange._get_funding_rate(pair, when) is None - - -def test__get_funding_fee(): - return