Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
7299583
feat(exchange): enable krakenfutures in supported list
hallonstedt Jan 11, 2026
271ee6d
feat(exchange): honor subclass has overrides in exchange validation
hallonstedt Jan 11, 2026
51588c2
feat(exchange): apply ft_has overrides in check_exchange
hallonstedt Jan 11, 2026
1a5f412
feat(exchange): register Kraken Futures exchange
hallonstedt Jan 11, 2026
46e96e2
feat(exchange): add Kraken Futures exchange class
hallonstedt Jan 11, 2026
2f7e77a
test(exchange): add Kraken Futures exchange tests
hallonstedt Jan 11, 2026
d9629c4
docs(exchange): add Kraken Futures notes
hallonstedt Jan 11, 2026
04ec24e
krakenfutures: move ohlcv cap to _ft_has and support futures-only onl…
hallonstedt Jan 13, 2026
6fdeab2
krakenfutures: align class name with resolver titlecase and remove un…
hallonstedt Jan 13, 2026
ea5ae96
style: ruff format
hallonstedt Jan 13, 2026
60f71bb
tests: re-enable hyperliquid spot online tests
hallonstedt Jan 14, 2026
507ea87
krakenfutures: convert _filter_params_for_open_closed to instance method
hallonstedt Jan 14, 2026
42361bc
krakenfutures: remove redundant get_ft_has method
hallonstedt Jan 14, 2026
06e2b8a
style: ruff format
hallonstedt Jan 14, 2026
7718e8e
krakenfutures: fix fetch_order to raise exception instead of returnin…
hallonstedt Jan 14, 2026
2077f34
krakenfutures: use Bybit/Hyperliquid funding fee calculation
hallonstedt Jan 15, 2026
5752e52
tests: update krakenfutures tests for get_ft_has removal and InvalidO…
hallonstedt Jan 15, 2026
6c588cc
docs: clarify flex account handling in Kraken Futures balances
Jan 15, 2026
38d197b
krakenfutures: rely on ft_has stoploss params, update tests/docs
hallonstedt Jan 17, 2026
2ed3db3
krakenfutures: use fetch_order_emulated with history fallback
hallonstedt Jan 17, 2026
272771a
docs(exchanges): remove redundant text
hallonstedt Jan 17, 2026
35706eb
krakenfutures: restore get_ft_has so exchange validation sees fetchOr…
hallonstedt Jan 18, 2026
4b23e9c
krakenfutures: strip history-only params from open/closed order calls
hallonstedt Jan 18, 2026
15359f5
krakenfutures: avoid mypy optional assignment in fetch_order
hallonstedt Jan 18, 2026
ca9d4ed
tests: fix _exchange_has_helper input in exchange_utils test
hallonstedt Jan 18, 2026
5af4147
tests: adjust list-exchanges futures assertions for krakenfutures
hallonstedt Jan 19, 2026
cef6372
exchange: drop krakenfutures ohlcv limit override
hallonstedt Jan 19, 2026
1254bd5
tests: align krakenfutures ohlcv limit check
hallonstedt Jan 19, 2026
f2780c7
exchange: drop ccxt workarounds; keep closed-order fallback
hallonstedt Jan 19, 2026
1345cfd
exchange: fallback to canceled orders for krakenfutures fetch_order; …
hallonstedt Jan 19, 2026
3f6e7ca
tests: cover krakenfutures currency sum and funding fees
hallonstedt Jan 20, 2026
7ee4338
tests: increase coverage - krakenfutures edge paths and ft_has overrides
hallonstedt Jan 21, 2026
e5a23f5
test: fix import order in exchange utils test
hallonstedt Jan 22, 2026
b4daabe
test: re-organize imports
hallonstedt Jan 22, 2026
06abc95
test: fix contradictory sorting by ruff and isort 7
hallonstedt Jan 22, 2026
9ddf464
fix(exchange): drop unused get_ft_has override plumbing
hallonstedt Jan 23, 2026
0cab0e8
fix(tests): use myokx for non-futures list-exchanges check
hallonstedt Jan 23, 2026
0d4dadd
docs: add Kraken to the list of supported Futures Exchanges
hallonstedt Jan 23, 2026
6ed4708
krakenfutures: backfill leverage tier notionals
hallonstedt Jan 23, 2026
a8d7a72
tests: drop unused krakenfutures spot leverage flag
hallonstedt Jan 23, 2026
ba80329
krakenfutures: guard maxNotional for non‑contract tiers
hallonstedt Jan 23, 2026
445a222
chore: remove leverage tier fixing code
xmatthias Jan 25, 2026
1d0bcbe
test: remove no longer necessary test
xmatthias Jan 25, 2026
1c77bd6
krakenfutures: improve fetch_order fallback
hallonstedt Jan 31, 2026
cb6a126
chore: remove pointless comments
xmatthias Feb 1, 2026
712fd8a
chore: import formatting
xmatthias Feb 1, 2026
c68c689
chore: revert odd, unnecessary modifications
xmatthias Feb 1, 2026
756f178
exchange_utils: use ccxt exchange.has directly in capability checks
hallonstedt Feb 6, 2026
f81e335
krakenfutures: simplify order/balance handling and harden error mapping
hallonstedt Feb 6, 2026
4f82913
docs: align Kraken Futures config and collateral guidance
hallonstedt Feb 6, 2026
cfa4924
krakenfutures: satisfy mypy narrowing in flex USD used calculation
hallonstedt Feb 6, 2026
bb2f19d
krakenfutures: replace assert with typed None-guard for ruff S101
hallonstedt Feb 6, 2026
bfbae5d
fix(krakenfutures): re-introduce improved stoploss lookup for trigger…
hallonstedt Feb 7, 2026
a831a6e
docs: align krakenfutures link in Readme.md
xmatthias Feb 12, 2026
b190079
test: Simplify live test setup
xmatthias Feb 12, 2026
b25defb
refactor: invert balance logic to simplify function
xmatthias Feb 12, 2026
68c8dd4
chore: krakenfutures tickers don't have volume
xmatthias Feb 12, 2026
83c2ca5
test: krakenfutures has no websockets at the moment
xmatthias Feb 12, 2026
086e1d8
refactor(krakenfutures): simplify stoploss handling after ccxt fix
hallonstedt Feb 14, 2026
f0aedc8
test(krakenfutures): align tests with simplified stoploss handling
hallonstedt Feb 14, 2026
cb2e50a
fix(tests): restore exchange_params return in get_futures_exchange
hallonstedt Feb 14, 2026
0dc2658
krakenfutures: add funding_fee_candle_limit for limited history
hallonstedt Feb 14, 2026
eaa35d7
style: ruff format
hallonstedt Feb 14, 2026
8c1674b
fix(tests): use CandleType.FUTURES in test_ohlcv_limit_futures
hallonstedt Feb 15, 2026
027ac3d
test: simplify longrun tests
xmatthias Feb 16, 2026
d6e6c9d
chore: log fetch_order responses for better tracability
xmatthias Feb 17, 2026
3c4b07c
test: update krakenfutures_tests for usage of __name__
xmatthias Feb 17, 2026
0dfd732
fix: extract triggerPrice from priceTriggerOptions for stoploss orders
hallonstedt Feb 17, 2026
a1e9b6b
fix: compute average price from trades and enrich fees for Kraken Fut…
hallonstedt Feb 17, 2026
c533e48
refactor: remove funding_fee_candle_limit override
hallonstedt Feb 19, 2026
d25b2ea
fix: crash on comparison of filled=None
xmatthias Feb 24, 2026
b1ef0bf
krakenfutures: use safe_value_nested for trigger price extraction
hallonstedt Feb 25, 2026
bfd758d
krakenfutures: recompute average and cost from fills for terminal orders
hallonstedt Feb 25, 2026
1e79c19
krakenfutures: aggregate order fees in _adjust_krakenfutures_order
hallonstedt Feb 25, 2026
35d812a
krakenfutures: run order adjustments via _order_contracts_to_amount
hallonstedt Feb 25, 2026
5096ec8
krakenfutures: defer order-level fee aggregation
hallonstedt Feb 25, 2026
7f9b1a9
krakenfutures: correct ccxt issue link to 27996
hallonstedt Feb 25, 2026
1f4c188
test: add futures market-parsing test
xmatthias Mar 6, 2026
3a28c91
test: add regular market order
xmatthias Mar 6, 2026
437d0a2
test: Improve test sequence (simplifies analysis)
xmatthias Mar 6, 2026
57c7edf
test: update krakenfutures live test
xmatthias Mar 16, 2026
0fda77a
chore: filter open orders by pair
xmatthias Mar 16, 2026
f8b99c6
test(krakenfutures): update stop strip test
xmatthias Mar 17, 2026
32fecd7
test(krakenfutures): improve _ft_has test
xmatthias Mar 17, 2026
200b9da
test: remove unnecessary test
xmatthias Mar 17, 2026
bd9697e
test: fix krakenfutures tests
xmatthias Mar 18, 2026
6bf1901
chore: bump ccxt to 4.5.44
xmatthias Mar 18, 2026
eba9c24
refactor(krakenfutures): drop resolved trigger price workaround
hallonstedt Mar 19, 2026
1bd0404
fix: workaround for missing "filled" parsing
xmatthias Mar 21, 2026
37dbaae
feat(krakenfutures): exchange_override fetchOrders to false
xmatthias Mar 21, 2026
724318c
test(krakenfutures): Add canceled order test
xmatthias Mar 21, 2026
250156f
Merge pull request #12706 from hallonstedt/feature-krakenfutures
xmatthias Mar 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Please read the [exchange-specific notes](https://www.freqtrade.io/en/stable/exc
- [X] [Hyperliquid](https://hyperliquid.xyz/) (A decentralized exchange, or DEX)
- [X] [OKX](https://okx.com/)
- [X] [Bybit](https://bybit.com/)
- [X] [Kraken](https://www.kraken.com/features/futures)

Please make sure to read the [exchange specific notes](https://www.freqtrade.io/en/stable/exchanges/), as well as the [trading with leverage](https://www.freqtrade.io/en/stable/leverage/) documentation before diving in.

Expand Down
2 changes: 2 additions & 0 deletions docs/data-download.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ If `--convert` is also provided, the resample step will happen automatically and
!!! Note "Kraken user"
Kraken users should read [this](exchanges.md#historic-kraken-data) before starting to download data.

Kraken Futures uses standard OHLCV downloads and does not require `--dl-trades`.

Example call:

```bash
Expand Down
26 changes: 26 additions & 0 deletions docs/exchanges.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,32 @@ freqtrade download-data --exchange kraken --dl-trades -p BTC/EUR BCH/EUR
Please pay attention that rateLimit configuration entry holds delay in milliseconds between requests, NOT requests/sec rate.
So, in order to mitigate Kraken API "Rate limit exceeded" exception, this configuration should be increased, NOT decreased.

## Kraken Futures

Kraken Futures uses the exchange id `krakenfutures` and supports isolated futures mode.

```jsonc
"exchange": {
"name": "krakenfutures",
"key": "your_exchange_key",
"secret": "your_exchange_secret"
},
"trading_mode": "futures",
"margin_mode": "isolated",
"stake_currency": "USD"
```

!!! Tip "Stoploss on Exchange"
Kraken Futures supports `stoploss_on_exchange` with both `limit` and `market` stop orders.
Use `order_types.stoploss_price_type` to select the trigger price source (`mark`, `last`, or `index`).

!!! Note "Collateral"
Kraken Futures is USD-settled. Use USD as your stake currency.

!!! Note "Flex (Multi-collateral) Accounts"
Kraken Futures flex accounts allow collateral in multiple currencies, while trading remains USD-settled.
Freqtrade derives the `USD` balance from Kraken margin fields, so keep `stake_currency` set to `USD`.

## 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:
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual,
- [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [Hyperliquid](https://hyperliquid.xyz/) (A decentralized exchange, or DEX)
- [X] [OKX](https://okx.com/)
- [X] [Kraken](https://www.kraken.com/features/futures)

Please make sure to read the [exchange specific notes](exchanges.md), as well as the [trading with leverage](leverage.md) documentation before diving in.

Expand Down
1 change: 1 addition & 0 deletions freqtrade/exchange/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from freqtrade.exchange.hyperliquid import Hyperliquid
from freqtrade.exchange.idex import Idex
from freqtrade.exchange.kraken import Kraken
from freqtrade.exchange.krakenfutures import Krakenfutures
from freqtrade.exchange.kucoin import Kucoin
from freqtrade.exchange.lbank import Lbank
from freqtrade.exchange.luno import Luno
Expand Down
2 changes: 1 addition & 1 deletion freqtrade/exchange/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def _get_logging_mixin():
"bitmex": "Various reasons",
"probit": "Requires additional, regular calls to `signIn()`",
"poloniex": "Does not provide fetch_order endpoint to fetch both open and closed orders",
"krakenfutures": "Unsupported futures exchange",
"kucoinfutures": "Unsupported futures exchange",
"poloniexfutures": "Unsupported futures exchange",
"binancecoinm": "Unsupported futures exchange",
Expand All @@ -63,6 +62,7 @@ def _get_logging_mixin():
"htx",
"hyperliquid",
"kraken",
"krakenfutures",
"okx",
"myokx",
]
Expand Down
300 changes: 300 additions & 0 deletions freqtrade/exchange/krakenfutures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
"""Kraken Futures exchange subclass"""

import logging
from datetime import datetime
from typing import Any

import ccxt

from freqtrade.enums import MarginMode, PriceType, TradingMode
from freqtrade.exceptions import (
DDosProtection,
ExchangeError,
InvalidOrderException,
OperationalException,
TemporaryError,
)
from freqtrade.exchange.common import API_FETCH_ORDER_RETRY_COUNT, retrier
from freqtrade.exchange.exchange import Exchange
from freqtrade.exchange.exchange_types import CcxtBalances, CcxtOrder, FtHas
from freqtrade.misc import safe_value_nested
from freqtrade.util.datetime_helpers import dt_from_ts


logger = logging.getLogger(__name__)


class Krakenfutures(Exchange):
"""Kraken Futures exchange class.

Contains adjustments needed for Freqtrade to work with this exchange.

Key differences from spot Kraken:
- Stop orders use triggerPrice/triggerSignal instead of stopPrice
- Flex (multi-collateral) accounts need USD balance synthesis
"""

_supported_trading_mode_margin_pairs: list[tuple[TradingMode, MarginMode]] = [
(TradingMode.FUTURES, MarginMode.ISOLATED),
]

_ft_has: FtHas = {
"tickers_have_quoteVolume": False,
"stoploss_on_exchange": True,
"stoploss_order_types": {
"limit": "limit",
"market": "market",
},
"stoploss_query_requires_stop_flag": True,
"stop_price_param": "triggerPrice",
"stop_price_prop": "stopPrice",
"stop_price_type_field": "triggerSignal",
"stop_price_type_value_mapping": {
PriceType.LAST: "last",
PriceType.MARK: "mark",
PriceType.INDEX: "index",
},
"exchange_has_overrides": {"fetchOrders": False},
}

@retrier
def get_balances(self, params: dict | None = None) -> CcxtBalances:
"""
Fetch balances with USD synthesis for flex (multi-collateral) accounts.

Kraken Futures flex accounts hold multiple currencies as collateral.
CCXT returns per-currency balances but doesn't expose margin values
as a USD balance. This override synthesizes a USD entry from flex account data
when stake_currency is USD.

Field mapping (margin-centric for internal consistency):
- free: availableMargin (margin available for new positions)
- total: marginEquity (haircut-adjusted collateral + unrealized P&L)
- used: total - free (margin currently in use)

Fallback chain for total: marginEquity -> portfolioValue -> balanceValue
"""
try:
balances = self._api.fetch_balance(params or {})

# Only synthesize USD if stake_currency is USD
stake = str(self._config.get("stake_currency", "")).upper()
if stake == "USD":
# Only synthesize if USD stake - flex only applies for these currencies.
# For flex accounts, synthesize USD balance from margin values
info = balances.get("info", {})
accounts = info.get("accounts", {}) if isinstance(info, dict) else {}
flex = accounts.get("flex", {}) if isinstance(accounts, dict) else {}

if flex:
usd_free = self._safe_float(flex.get("availableMargin"))
# Prefer marginEquity for consistency (same basis as availableMargin)
raw_total = (
flex.get("marginEquity")
or flex.get("portfolioValue")
or flex.get("balanceValue")
)
usd_total = self._safe_float(raw_total)
if usd_free is not None or usd_total is not None:
# Use available value for both if only one is present
usd_free_value = usd_free if usd_free is not None else usd_total
usd_total_value = usd_total if usd_total is not None else usd_free
if usd_free_value is not None and usd_total_value is not None:
usd_used = max(0.0, usd_total_value - usd_free_value)
balances["USD"] = {
"free": usd_free_value,
"used": usd_used,
"total": usd_total_value,
}

# Remove additional info from ccxt results (same as base class)
balances.pop("info", None)
balances.pop("free", None)
balances.pop("total", None)
balances.pop("used", None)

self._log_exchange_response("fetch_balance", balances, add_info=params)
return balances
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.OperationFailed, ccxt.ExchangeError) as e:
raise TemporaryError(
f"Could not get balance due to {e.__class__.__name__}. Message: {e}"
) from e
except ccxt.BaseError as e:
raise OperationalException(e) from e

@staticmethod
def _safe_float(value: Any) -> float | None:
"""Convert value to float, returning None if conversion fails."""
if value is None:
return None
try:
return float(value)
except (ValueError, TypeError):
return None

def _order_contracts_to_amount(self, order: CcxtOrder) -> CcxtOrder:
"""Normalize order and apply Kraken Futures-specific order corrections."""
order = super()._order_contracts_to_amount(order)
return self._adjust_krakenfutures_order(order)

def _adjust_krakenfutures_order(self, order: CcxtOrder) -> CcxtOrder:
"""Apply Kraken Futures-specific order corrections.

For filled terminal orders, always fetch trades and compute VWAP because
CCXT's average is still unreliable.

See: https://github.com/ccxt/ccxt/issues/27996
"""
if order.get("status") == "canceled" and order.get("filled") is None:
# Workaround for missing filled parsing - https://github.com/ccxt/ccxt/issues/28210
order["filled"] = safe_value_nested(order, "info.order.filled", default_value=None)

filled = self._safe_float(order.get("filled")) or 0.0
if order.get("status") in ("canceled", "closed") and filled > 0:
# Compute VWAP and cost for filled orders.
trades = self.get_trades_for_order(
order["id"], order["symbol"], since=dt_from_ts(order["timestamp"])
)
if trades:
total_amount = sum(t["amount"] for t in trades)
if total_amount:
# Compute VWAP
order["average"] = sum(t["price"] * t["amount"] for t in trades) / total_amount
trade_costs = [t["cost"] for t in trades if t.get("cost") is not None]
if trade_costs:
order["cost"] = sum(trade_costs)
return order

def get_trades_for_order(
self, order_id: str, pair: str, since: datetime, params: dict | None = None
) -> list:
"""Fetch trades and enrich with calculated fees.

Kraken Futures' /fills endpoint does not include fee amounts — only
fillType (maker/taker). This enriches each trade with a calculated fee
using the market's fee schedule so Freqtrade's fee detection works.
"""
trades = super().get_trades_for_order(order_id, pair, since, params)
for trade in trades:
if trade.get("fee") is None or trade["fee"].get("cost") is None:
taker_or_maker = trade.get("takerOrMaker", "taker")
symbol = trade.get("symbol", pair)
market = self.markets.get(symbol, {})
fee_rate = market.get(taker_or_maker, market.get("taker", 0.0005))
cost = trade.get("cost")
if cost is not None and fee_rate is not None:
trade["fee"] = {
"cost": cost * fee_rate,
"currency": market.get("quote", "USD"),
"rate": fee_rate,
}
return trades

@retrier(retries=API_FETCH_ORDER_RETRY_COUNT)
def fetch_order(
self, order_id: str, pair: str, params: dict[str, Any] | None = None
) -> CcxtOrder:
"""Fetch order with direct CCXT call and fallback to history endpoints."""
if self._config.get("dry_run"):
return self.fetch_dry_run_order(order_id)

params = params or {}
status_params = {k: v for k, v in params.items() if k not in ("trigger", "stop")}
try:
order = self._api.fetch_order(order_id, pair, params=status_params)
self._log_exchange_response("fetch_order", order)
return self._order_contracts_to_amount(order)
except ccxt.OrderNotFound:
# Expected for older Kraken Futures orders not visible in orders/status.
pass
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except ccxt.InvalidOrder as e:
msg = f"Tried to get an invalid order (pair: {pair} id: {order_id}). Message: {e}"
raise InvalidOrderException(msg) from e
except (ccxt.OperationFailed, ccxt.ExchangeError):
# Fallback to history endpoints for temporary/status endpoint gaps.
pass
except ccxt.BaseError as e:
raise OperationalException(e) from e

order = self._fetch_order_fallback(order_id, pair, params)
if order is not None:
return order

# Order not in status, open, closed, or canceled endpoints - genuinely gone.
# Raise non-retrying InvalidOrderException (Kraken has limited history retention).
raise InvalidOrderException(
f"Order not found in any endpoint (pair: {pair} id: {order_id})"
)

def _fetch_order_fallback(
self, order_id: str, pair: str, params: dict[str, Any]
) -> CcxtOrder | None:
"""Search open, closed, and canceled order endpoints for order_id.

Kraken Futures' orders/status endpoint only returns currently open orders.
Older orders require querying history endpoints (closed/canceled).
For stoploss (trigger) orders, the caller should pass stop=True in params
(handled automatically via stoploss_query_requires_stop_flag in _ft_has)
so that closed/canceled queries hit the trigger history endpoint.
"""
order_id_str = str(order_id)

# Open orders include triggers by default. Avoid passing trigger/stop flags
# to prevent endpoint/filter mismatches.
open_params = {k: v for k, v in params.items() if k not in ("trigger", "stop")}
order = self._find_order_in_list(
self._api.fetch_open_orders, pair, open_params, order_id_str
)
if order is not None:
return order

# Closed/canceled: pass params through (including stop=True for stoploss orders,
# which CCXT maps to the trigger history endpoint).
for fetch_fn in (self._api.fetch_closed_orders, self._api.fetch_canceled_orders):
order = self._find_order_in_list(fetch_fn, pair, params, order_id_str)
if order is not None:
return order

return None

def _find_order_in_list(
self,
fetch_fn,
symbol: str | None,
params: dict[str, Any],
order_id_str: str,
) -> CcxtOrder | None:
"""Fetch orders and return matching order_id, or None."""
try:
orders = fetch_fn(symbol, params=params) or []
self._log_exchange_response(fetch_fn.__name__, orders)
for order in orders:
if str(order.get("id")) == order_id_str:
self._log_exchange_response("fetch_order_fallback", order)

return self._order_contracts_to_amount(order)
except (ccxt.OrderNotFound, ccxt.InvalidOrder) as e:
logger.debug(f"{fetch_fn.__name__} failed: {e}")
return None
except ccxt.DDoSProtection as e:
raise DDosProtection(e) from e
except (ccxt.OperationFailed, ccxt.ExchangeError) as e:
raise TemporaryError(
f"Could not get order due to {e.__class__.__name__}. Message: {e}"
) from e
except ccxt.BaseError as e:
raise OperationalException(e) from e
return None

def get_funding_fees(self, pair: str, amount: float, is_short: bool, open_date) -> float:
"""Fetch funding fees, returning 0.0 if retrieval fails."""
if self.trading_mode == TradingMode.FUTURES:
try:
return self._fetch_and_calculate_funding_fees(pair, amount, is_short, open_date)
except ExchangeError:
logger.warning(f"Could not update funding fees for {pair}.")
return 0.0
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ft-pandas-ta==0.3.16
ta-lib==0.6.8
technical==1.5.4

ccxt==4.5.43
ccxt==4.5.44
cryptography==46.0.5
aiohttp==3.13.3
SQLAlchemy==2.0.48
Expand Down
Loading
Loading