krakenfutures: move ohlcv cap to _ft_has and support futures-only online tests
This commit is contained in:
@@ -53,6 +53,7 @@ class KrakenFutures(Exchange):
|
||||
PriceType.MARK: "mark",
|
||||
PriceType.INDEX: "index",
|
||||
},
|
||||
"ohlcv_candle_limit": 2000,
|
||||
# override ccxt has-gaps
|
||||
"exchange_has_overrides": {
|
||||
"fetchOrder": True,
|
||||
@@ -593,19 +594,5 @@ class KrakenFutures(Exchange):
|
||||
return v.strip()
|
||||
return "mark"
|
||||
|
||||
def ohlcv_candle_limit(
|
||||
self,
|
||||
timeframe: str,
|
||||
candle_type: CandleType,
|
||||
since_ms: int | None = None,
|
||||
) -> int:
|
||||
limit = super().ohlcv_candle_limit(
|
||||
timeframe,
|
||||
candle_type=candle_type,
|
||||
since_ms=since_ms,
|
||||
)
|
||||
return min(limit, 2000)
|
||||
|
||||
|
||||
class Krakenfutures(KrakenFutures):
|
||||
pass
|
||||
|
||||
@@ -23,11 +23,11 @@ def test_krakenfutures_get_ft_has():
|
||||
|
||||
def test_krakenfutures_ohlcv_candle_limit_caps_at_2000(mocker, default_conf):
|
||||
"""Test that OHLCV candle limit is capped at 2000."""
|
||||
mocker.patch.object(Exchange, "ohlcv_candle_limit", return_value=5000)
|
||||
|
||||
ex = get_patched_exchange(mocker, default_conf, exchange="krakenfutures")
|
||||
assert isinstance(ex, KrakenFutures)
|
||||
|
||||
mocker.patch.object(ex, "features", return_value=5000)
|
||||
|
||||
assert ex.ohlcv_candle_limit("1m", candle_type=CandleType.FUTURES) == 2000
|
||||
|
||||
|
||||
|
||||
@@ -548,6 +548,7 @@ EXCHANGES: dict[str, TestExchangeOnlineSetup] = {
|
||||
"hasQuoteVolume": False,
|
||||
"timeframe": "30m",
|
||||
"futures": True,
|
||||
"futures_only": True,
|
||||
"candle_count": 5000,
|
||||
"orderbook_max_entries": 20,
|
||||
"futures_pair": "BTC/USDC:USDC",
|
||||
@@ -559,6 +560,19 @@ EXCHANGES: dict[str, TestExchangeOnlineSetup] = {
|
||||
# TODO: re-enable hyperliquid websocket tests
|
||||
"skip_ws_tests": True,
|
||||
},
|
||||
"krakenfutures": {
|
||||
"pair": "BTC/USD:USD",
|
||||
"stake_currency": "USD",
|
||||
"hasQuoteVolume": False,
|
||||
"timeframe": "1h",
|
||||
"futures": True,
|
||||
"futures_only": True,
|
||||
"candle_count": 2000,
|
||||
"futures_pair": "BTC/USD:USD",
|
||||
"hasQuoteVolumeFutures": False,
|
||||
"leverage_tiers_public": False,
|
||||
"leverage_in_spot_market": False,
|
||||
},
|
||||
}
|
||||
|
||||
EXCHANGES_FUTURES = [exch for exch, params in EXCHANGES.items() if params.get("futures")]
|
||||
@@ -591,11 +605,15 @@ def set_test_proxy(config: Config, use_proxy: bool) -> Config:
|
||||
return config
|
||||
|
||||
|
||||
def get_exchange(exchange_name, exchange_conf):
|
||||
def get_exchange(exchange_name, exchange_conf, class_mocker=None):
|
||||
exchange_params = EXCHANGES[exchange_name]
|
||||
if exchange_params.get("futures_only"):
|
||||
pytest.skip(f"Exchange {exchange_name} is futures-only, skipping spot tests.")
|
||||
exchange_conf = set_test_proxy(exchange_conf, exchange_params.get("use_ci_proxy", False))
|
||||
exchange_conf["exchange"]["name"] = exchange_name
|
||||
exchange_conf["stake_currency"] = exchange_params["stake_currency"]
|
||||
if class_mocker:
|
||||
class_mocker.patch(f"{EXMS}.ft_additional_exchange_init")
|
||||
exchange = ExchangeResolver.load_exchange(
|
||||
exchange_conf, validate=True, load_leverage_tiers=True
|
||||
)
|
||||
@@ -608,25 +626,30 @@ def get_futures_exchange(exchange_name, exchange_conf, class_mocker):
|
||||
|
||||
if exchange_params.get("futures") is not True:
|
||||
pytest.skip(f"Exchange {exchange_name} does not support futures.")
|
||||
else:
|
||||
exchange_conf = deepcopy(exchange_conf)
|
||||
exchange_conf = set_test_proxy(exchange_conf, exchange_params.get("use_ci_proxy", False))
|
||||
exchange_conf["trading_mode"] = "futures"
|
||||
exchange_conf["margin_mode"] = "isolated"
|
||||
exchange_conf = deepcopy(exchange_conf)
|
||||
exchange_conf = set_test_proxy(exchange_conf, exchange_params.get("use_ci_proxy", False))
|
||||
exchange_conf["exchange"]["name"] = exchange_name
|
||||
exchange_conf["stake_currency"] = exchange_params["stake_currency"]
|
||||
exchange_conf["trading_mode"] = "futures"
|
||||
exchange_conf["margin_mode"] = "isolated"
|
||||
|
||||
class_mocker.patch("freqtrade.exchange.binance.Binance.fill_leverage_tiers")
|
||||
class_mocker.patch(f"{EXMS}.fetch_trading_fees")
|
||||
class_mocker.patch(f"{EXMS}.ft_additional_exchange_init")
|
||||
class_mocker.patch(f"{EXMS}.load_cached_leverage_tiers", return_value=None)
|
||||
class_mocker.patch(f"{EXMS}.cache_leverage_tiers")
|
||||
class_mocker.patch("freqtrade.exchange.binance.Binance.fill_leverage_tiers")
|
||||
class_mocker.patch(f"{EXMS}.fetch_trading_fees")
|
||||
class_mocker.patch(f"{EXMS}.ft_additional_exchange_init")
|
||||
class_mocker.patch(f"{EXMS}.load_cached_leverage_tiers", return_value=None)
|
||||
class_mocker.patch(f"{EXMS}.cache_leverage_tiers")
|
||||
|
||||
return get_exchange(exchange_name, exchange_conf)
|
||||
exchange = ExchangeResolver.load_exchange(
|
||||
exchange_conf, validate=True, load_leverage_tiers=True
|
||||
)
|
||||
return exchange, exchange_name
|
||||
|
||||
|
||||
@pytest.fixture(params=EXCHANGES, scope="class")
|
||||
def exchange(request, exchange_conf, class_mocker):
|
||||
class_mocker.patch(f"{EXMS}.ft_additional_exchange_init")
|
||||
exchange, name, exchange_params = get_exchange(request.param, exchange_conf)
|
||||
exchange, name, exchange_params = get_exchange(
|
||||
request.param, exchange_conf, class_mocker
|
||||
)
|
||||
yield exchange, name, exchange_params
|
||||
exchange.close()
|
||||
|
||||
@@ -653,7 +676,7 @@ def exchange_ws(request, exchange_conf, exchange_mode, class_mocker):
|
||||
if exchange_param.get("skip_ws_tests"):
|
||||
pytest.skip(f"{request.param} does not support websocket tests.")
|
||||
if exchange_mode == "spot":
|
||||
exchange, name, _ = get_exchange(request.param, exchange_conf)
|
||||
exchange, name, _ = get_exchange(request.param, exchange_conf, class_mocker)
|
||||
pair = exchange_param["pair"]
|
||||
elif exchange_param.get("futures"):
|
||||
exchange, name, _ = get_futures_exchange(
|
||||
|
||||
@@ -64,7 +64,12 @@ class TestCCXTExchange:
|
||||
if not expected_count:
|
||||
pytest.skip("No expected candle count for exchange")
|
||||
|
||||
assert exch.ohlcv_candle_limit("1m", CandleType.FUTURES) == expected_count
|
||||
candle_type = (
|
||||
CandleType.FUTURES
|
||||
if exchange_params.get("futures_only")
|
||||
else CandleType.SPOT
|
||||
)
|
||||
assert exch.ohlcv_candle_limit("1m", candle_type) == expected_count
|
||||
|
||||
def test_load_markets_futures(self, exchange_futures: EXCHANGE_FIXTURE_TYPE):
|
||||
exchange, _, exchange_params = exchange_futures
|
||||
|
||||
Reference in New Issue
Block a user