krakenfutures: rely on ft_has stoploss params, update tests/docs

This commit is contained in:
matstedt
2026-01-17 15:44:10 +01:00
committed by Matthias
parent 6c588cce65
commit 38d197b3bf
3 changed files with 28 additions and 48 deletions
+6 -13
View File
@@ -227,8 +227,11 @@ Kraken Futures uses the exchange id `krakenfutures` and supports isolated future
"key": "your_exchange_key", "key": "your_exchange_key",
"secret": "your_exchange_secret", "secret": "your_exchange_secret",
"ccxt_config": {"enableRateLimit": true}, "ccxt_config": {"enableRateLimit": true},
"ccxt_async_config": {"enableRateLimit": true}, "ccxt_async_config": {"enableRateLimit": true}
"triggerSignal": "mark" // "mark" (default), "last", or "index" },
"order_types": {
"stoploss": "market",
"stoploss_price_type": "mark" // "mark" (default), "last", or "index"
}, },
"trading_mode": "futures", "trading_mode": "futures",
"margin_mode": "isolated", "margin_mode": "isolated",
@@ -237,7 +240,7 @@ Kraken Futures uses the exchange id `krakenfutures` and supports isolated future
!!! Tip "Stoploss on Exchange" !!! Tip "Stoploss on Exchange"
Kraken Futures supports `stoploss_on_exchange` with both `limit` and `market` stop orders. Kraken Futures supports `stoploss_on_exchange` with both `limit` and `market` stop orders.
Use `exchange.triggerSignal` to select the trigger price source (`mark`, `last`, or `index`). Use `order_types.stoploss_price_type` to select the trigger price source (`mark`, `last`, or `index`).
!!! Note "Collateral" !!! Note "Collateral"
Kraken Futures is USD-settled. Kraken allows EUR collateral, but USD is the recommended stake currency. Kraken Futures is USD-settled. Kraken allows EUR collateral, but USD is the recommended stake currency.
@@ -245,16 +248,6 @@ Kraken Futures uses the exchange id `krakenfutures` and supports isolated future
!!! Note "Pair format" !!! Note "Pair format"
Futures pairs use CCXT symbols, for example `BTC/USD:USD`. Futures pairs use CCXT symbols, for example `BTC/USD:USD`.
### Data download
Kraken Futures uses normal OHLCV downloads.
```bash
freqtrade download-data --exchange krakenfutures --trading-mode futures --pairs BTC/USD:USD --timeframes 1m 5m
```
Note: OHLCV requests are capped at 2000 candles per call, so large downloads may take longer.
## Kucoin ## Kucoin
Kucoin requires a passphrase for each api key, you will therefore need to add this key into the configuration so your exchange section looks as follows: Kucoin requires a passphrase for each api key, you will therefore need to add this key into the configuration so your exchange section looks as follows:
-26
View File
@@ -8,7 +8,6 @@ from typing import Any
from ccxt.base.errors import NotSupported, OrderNotFound from ccxt.base.errors import NotSupported, OrderNotFound
from freqtrade.constants import BuySell
from freqtrade.enums import MarginMode, PriceType, TradingMode from freqtrade.enums import MarginMode, PriceType, TradingMode
from freqtrade.exceptions import ExchangeError, InvalidOrderException from freqtrade.exceptions import ExchangeError, InvalidOrderException
from freqtrade.exchange.common import retrier from freqtrade.exchange.common import retrier
@@ -537,28 +536,3 @@ class Krakenfutures(Exchange):
) -> list[dict[str, Any]]: ) -> list[dict[str, Any]]:
params = self._filter_params_for_open_closed(params or {}) params = self._filter_params_for_open_closed(params or {})
return self._api.fetch_closed_orders(pair, since, limit, params) return self._api.fetch_closed_orders(pair, since, limit, params)
def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> dict[str, Any]:
params: dict[str, Any] = super()._get_stop_params(
side=side, ordertype=ordertype, stop_price=stop_price
)
# Force Kraken Futures naming
params.setdefault("triggerPrice", stop_price)
trigger_signal = self._get_trigger_signal()
if trigger_signal is not None:
params.setdefault("triggerSignal", trigger_signal)
if getattr(self, "trading_mode", None) == TradingMode.FUTURES:
params.setdefault("reduceOnly", True)
return params
def _get_trigger_signal(self) -> str | None:
ex_conf = self._config.get("exchange")
if isinstance(ex_conf, dict):
v = ex_conf.get("triggerSignal") or ex_conf.get("trigger_signal")
if isinstance(v, str) and v.strip():
return v.strip()
return "mark"
+22 -9
View File
@@ -3,6 +3,7 @@
from __future__ import annotations from __future__ import annotations
from copy import deepcopy from copy import deepcopy
from unittest.mock import MagicMock
import pytest import pytest
from ccxt.base.errors import NotSupported from ccxt.base.errors import NotSupported
@@ -11,7 +12,7 @@ from freqtrade.enums import CandleType, MarginMode, TradingMode
from freqtrade.exceptions import InvalidOrderException from freqtrade.exceptions import InvalidOrderException
from freqtrade.exchange.exchange import Exchange from freqtrade.exchange.exchange import Exchange
from freqtrade.exchange.krakenfutures import Krakenfutures from freqtrade.exchange.krakenfutures import Krakenfutures
from tests.conftest import get_patched_exchange from tests.conftest import EXMS, get_patched_exchange
def test_krakenfutures_ft_has_overrides(): def test_krakenfutures_ft_has_overrides():
@@ -169,20 +170,32 @@ def test_krakenfutures_fetch_order_falls_back_to_history_orders(mocker, default_
assert res["filled"] == 0.0 assert res["filled"] == 0.0
def test_krakenfutures_get_stop_params_adds_triggerprice_signal_and_reduceonly( def test_krakenfutures_create_stoploss_uses_trigger_price_type(mocker, default_conf):
mocker, default_conf """Test create_stoploss uses triggerPrice, triggerSignal, and reduceOnly."""
): api_mock = MagicMock()
"""Test _get_stop_params adds triggerPrice, triggerSignal, and reduceOnly.""" api_mock.create_order = MagicMock(return_value={"id": "order-id", "info": {"foo": "bar"}})
conf = deepcopy(default_conf) conf = deepcopy(default_conf)
conf["dry_run"] = False
conf["trading_mode"] = TradingMode.FUTURES conf["trading_mode"] = TradingMode.FUTURES
conf["margin_mode"] = MarginMode.ISOLATED conf["margin_mode"] = MarginMode.ISOLATED
if isinstance(conf.get("exchange"), dict): mocker.patch(f"{EXMS}.amount_to_precision", lambda s, x, y: y)
conf["exchange"]["triggerSignal"] = "mark" mocker.patch(f"{EXMS}.price_to_precision", lambda s, x, y, **kwargs: y)
ex = get_patched_exchange(mocker, conf, exchange="krakenfutures") ex = get_patched_exchange(mocker, conf, api_mock, exchange="krakenfutures")
params = ex._get_stop_params(side="sell", ordertype="market", stop_price=90000.0) ex.create_stoploss(
pair="ETH/BTC",
amount=1,
stop_price=90000.0,
side="sell",
order_types={"stoploss": "market", "stoploss_price_type": "mark"},
leverage=1.0,
)
call_args = api_mock.create_order.call_args
params = call_args[1].get("params") if call_args[1] else call_args[0][5]
assert params["triggerPrice"] == 90000.0 assert params["triggerPrice"] == 90000.0
assert params["triggerSignal"] == "mark" assert params["triggerSignal"] == "mark"