Add compat tests
This commit is contained in:
parent
c8c2d89893
commit
8d4163d003
@ -1609,12 +1609,11 @@ class Exchange:
|
|||||||
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
|
Returns the sum of all funding fees that were exchanged for a pair within a timeframe
|
||||||
|
Dry-run handling happens as part of _calculate_funding_fees.
|
||||||
:param pair: (e.g. ADA/USDT)
|
:param pair: (e.g. ADA/USDT)
|
||||||
:param since: The earliest time of consideration for calculating funding fees,
|
:param since: The earliest time of consideration for calculating funding fees,
|
||||||
in unix time or as a datetime
|
in unix time or as a datetime
|
||||||
"""
|
"""
|
||||||
# TODO-lev: Add dry-run handling for this.
|
|
||||||
|
|
||||||
if not self.exchange_has("fetchFundingHistory"):
|
if not self.exchange_has("fetchFundingHistory"):
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f"fetch_funding_history() is not available using {self.name}"
|
f"fetch_funding_history() is not available using {self.name}"
|
||||||
@ -1889,13 +1888,8 @@ class Exchange:
|
|||||||
d = datetime.fromtimestamp(int(fund['timestamp'] / 1000), timezone.utc)
|
d = datetime.fromtimestamp(int(fund['timestamp'] / 1000), timezone.utc)
|
||||||
# Round down to the nearest hour, in case of a delayed timestamp
|
# Round down to the nearest hour, in case of a delayed timestamp
|
||||||
# The millisecond timestamps can be delayed ~20ms
|
# The millisecond timestamps can be delayed ~20ms
|
||||||
time = datetime(
|
time = int(timeframe_to_prev_date('1h', d).timestamp() * 1000)
|
||||||
d.year,
|
|
||||||
d.month,
|
|
||||||
d.day,
|
|
||||||
d.hour,
|
|
||||||
tzinfo=timezone.utc
|
|
||||||
).timestamp() * 1000
|
|
||||||
funding_history[time] = fund['fundingRate']
|
funding_history[time] = fund['fundingRate']
|
||||||
return funding_history
|
return funding_history
|
||||||
except ccxt.DDoSProtection as e:
|
except ccxt.DDoSProtection as e:
|
||||||
|
@ -12,7 +12,7 @@ import pytest
|
|||||||
|
|
||||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date
|
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date
|
||||||
from freqtrade.resolvers.exchange_resolver import ExchangeResolver
|
from freqtrade.resolvers.exchange_resolver import ExchangeResolver
|
||||||
from tests.conftest import get_default_conf
|
from tests.conftest import get_default_conf_usdt
|
||||||
|
|
||||||
|
|
||||||
# Exchanges that should be tested
|
# Exchanges that should be tested
|
||||||
@ -33,9 +33,11 @@ EXCHANGES = {
|
|||||||
'timeframe': '5m',
|
'timeframe': '5m',
|
||||||
},
|
},
|
||||||
'ftx': {
|
'ftx': {
|
||||||
'pair': 'BTC/USDT',
|
'pair': 'BTC/USD',
|
||||||
'hasQuoteVolume': True,
|
'hasQuoteVolume': True,
|
||||||
'timeframe': '5m',
|
'timeframe': '5m',
|
||||||
|
'futures_pair': 'BTC-PERP',
|
||||||
|
'futures': True,
|
||||||
},
|
},
|
||||||
'kucoin': {
|
'kucoin': {
|
||||||
'pair': 'BTC/USDT',
|
'pair': 'BTC/USDT',
|
||||||
@ -46,6 +48,7 @@ EXCHANGES = {
|
|||||||
'pair': 'BTC/USDT',
|
'pair': 'BTC/USDT',
|
||||||
'hasQuoteVolume': True,
|
'hasQuoteVolume': True,
|
||||||
'timeframe': '5m',
|
'timeframe': '5m',
|
||||||
|
'futures': True,
|
||||||
},
|
},
|
||||||
'okex': {
|
'okex': {
|
||||||
'pair': 'BTC/USDT',
|
'pair': 'BTC/USDT',
|
||||||
@ -57,7 +60,7 @@ EXCHANGES = {
|
|||||||
|
|
||||||
@pytest.fixture(scope="class")
|
@pytest.fixture(scope="class")
|
||||||
def exchange_conf():
|
def exchange_conf():
|
||||||
config = get_default_conf((Path(__file__).parent / "testdata").resolve())
|
config = get_default_conf_usdt((Path(__file__).parent / "testdata").resolve())
|
||||||
config['exchange']['pair_whitelist'] = []
|
config['exchange']['pair_whitelist'] = []
|
||||||
config['exchange']['key'] = ''
|
config['exchange']['key'] = ''
|
||||||
config['exchange']['secret'] = ''
|
config['exchange']['secret'] = ''
|
||||||
@ -73,6 +76,19 @@ def exchange(request, exchange_conf):
|
|||||||
yield exchange, request.param
|
yield exchange, request.param
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(params=EXCHANGES, scope="class")
|
||||||
|
def exchange_futures(request, exchange_conf):
|
||||||
|
if not EXCHANGES[request.param].get('futures') is True:
|
||||||
|
yield None, request.param
|
||||||
|
else:
|
||||||
|
exchange_conf['exchange']['name'] = request.param
|
||||||
|
exchange_conf['trading_mode'] = 'futures'
|
||||||
|
exchange_conf['collateral'] = 'cross'
|
||||||
|
exchange = ExchangeResolver.load_exchange(request.param, exchange_conf, validate=True)
|
||||||
|
|
||||||
|
yield exchange, request.param
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.longrun
|
@pytest.mark.longrun
|
||||||
class TestCCXTExchange():
|
class TestCCXTExchange():
|
||||||
|
|
||||||
@ -149,6 +165,24 @@ class TestCCXTExchange():
|
|||||||
now = datetime.now(timezone.utc) - timedelta(minutes=(timeframe_to_minutes(timeframe) * 2))
|
now = datetime.now(timezone.utc) - timedelta(minutes=(timeframe_to_minutes(timeframe) * 2))
|
||||||
assert exchange.klines(pair_tf).iloc[-1]['date'] >= timeframe_to_prev_date(timeframe, now)
|
assert exchange.klines(pair_tf).iloc[-1]['date'] >= timeframe_to_prev_date(timeframe, now)
|
||||||
|
|
||||||
|
@pytest.mark.skip("No futures support yet")
|
||||||
|
def test_ccxt_fetch_funding_rate_history(self, exchange_futures):
|
||||||
|
# TODO-lev: enable this test once Futures mode is enabled.
|
||||||
|
exchange, exchangename = exchange_futures
|
||||||
|
if not exchange:
|
||||||
|
# exchange_futures only returns values for supported exchanges
|
||||||
|
return
|
||||||
|
|
||||||
|
pair = EXCHANGES[exchangename].get('futures_pair', EXCHANGES[exchangename]['pair'])
|
||||||
|
since = int((datetime.now(timezone.utc) - timedelta(days=5)).timestamp() * 1000)
|
||||||
|
|
||||||
|
rate = exchange.get_funding_rate_history(pair, since)
|
||||||
|
assert isinstance(rate, dict)
|
||||||
|
this_hour = timeframe_to_prev_date('1h')
|
||||||
|
prev_hour = this_hour - timedelta(hours=1)
|
||||||
|
assert rate[int(this_hour.timestamp() * 1000)] != 0.0
|
||||||
|
assert rate[int(prev_hour.timestamp() * 1000)] != 0.0
|
||||||
|
|
||||||
# TODO: tests fetch_trades (?)
|
# TODO: tests fetch_trades (?)
|
||||||
|
|
||||||
def test_ccxt_get_fee(self, exchange):
|
def test_ccxt_get_fee(self, exchange):
|
||||||
|
Loading…
Reference in New Issue
Block a user