diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index b0c88a51a..138c02647 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -8,7 +8,7 @@ from freqtrade.exchange.binance import Binance from freqtrade.exchange.bittrex import Bittrex from freqtrade.exchange.bybit import Bybit from freqtrade.exchange.coinbasepro import Coinbasepro -from freqtrade.exchange.exchange import (available_exchanges, ccxt_exchanges, +from freqtrade.exchange.exchange import (available_exchanges, ccxt_exchanges, hours_to_time, is_exchange_known_ccxt, is_exchange_officially_supported, market_is_active, timeframe_to_minutes, timeframe_to_msecs, timeframe_to_next_date, timeframe_to_prev_date, diff --git a/freqtrade/exchange/binance.py b/freqtrade/exchange/binance.py index ba4f510d3..9be06e94d 100644 --- a/freqtrade/exchange/binance.py +++ b/freqtrade/exchange/binance.py @@ -1,12 +1,12 @@ """ Binance exchange subclass """ import logging -from typing import Dict, Optional +from typing import Dict, List import ccxt - +from datetime import time from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException, OperationalException, TemporaryError) -from freqtrade.exchange import Exchange +from freqtrade.exchange import Exchange, hours_to_time from freqtrade.exchange.common import retrier @@ -23,6 +23,7 @@ class Binance(Exchange): "trades_pagination_arg": "fromId", "l2_limit_range": [5, 10, 20, 50, 100, 500, 1000], } + funding_fee_times: List[time] = hours_to_time([0, 8, 16]) def stoploss_adjust(self, stop_loss: float, order: Dict) -> bool: """ diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index d82c20599..22f6f029d 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -7,7 +7,7 @@ import http import inspect import logging from copy import deepcopy -from datetime import datetime, timezone +from datetime import datetime, time, timezone from math import ceil from typing import Any, Dict, List, Optional, Tuple @@ -69,6 +69,7 @@ class Exchange: "l2_limit_range_required": True, # Allow Empty L2 limit (kucoin) } _ft_has: Dict = {} + funding_fee_times: List[time] = [] def __init__(self, config: Dict[str, Any], validate: bool = True) -> None: """ @@ -1525,6 +1526,15 @@ class Exchange: return self._api.fetch_funding_rates() +def hours_to_time(hours: List[int]) -> List[time]: + ''' + :param hours: a list of hours as a time of day (e.g. [1, 16] is 01:00 and 16:00 o'clock) + :return: a list of datetime time objects that correspond to the hours in hours + ''' + # TODO-lev: These must be utc time + return [datetime.strptime(str(t), '%H').time() for t in hours] + + 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 f1d633ca9..6f5c28e58 100644 --- a/freqtrade/exchange/ftx.py +++ b/freqtrade/exchange/ftx.py @@ -1,12 +1,12 @@ """ FTX exchange subclass """ import logging -from typing import Any, Dict, Optional +from typing import Any, Dict, List import ccxt - +from datetime import time from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException, OperationalException, TemporaryError) -from freqtrade.exchange import Exchange +from freqtrade.exchange import Exchange, hours_to_time from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT, retrier from freqtrade.misc import safe_value_fallback2 @@ -20,6 +20,7 @@ class Ftx(Exchange): "stoploss_on_exchange": True, "ohlcv_candle_limit": 1500, } + funding_fee_times: List[time] = hours_to_time(list(range(0, 23))) def market_is_tradable(self, market: Dict[str, Any]) -> bool: """ diff --git a/freqtrade/exchange/kraken.py b/freqtrade/exchange/kraken.py index 1b069aa6c..d69ac9e33 100644 --- a/freqtrade/exchange/kraken.py +++ b/freqtrade/exchange/kraken.py @@ -1,12 +1,12 @@ """ Kraken exchange subclass """ import logging -from typing import Any, Dict +from typing import Any, Dict, List import ccxt - +from datetime import time from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException, OperationalException, TemporaryError) -from freqtrade.exchange import Exchange +from freqtrade.exchange import Exchange, hours_to_time from freqtrade.exchange.common import retrier @@ -22,6 +22,7 @@ class Kraken(Exchange): "trades_pagination": "id", "trades_pagination_arg": "since", } + funding_fee_times: List[time] = hours_to_time([0, 4, 8, 12, 16, 20]) def market_is_tradable(self, market: Dict[str, Any]) -> bool: """