mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-02-13 09:40:29 +00:00
feat: add typedDict for LeverageTiers - fix unbound upper bound for get_max_leverage
This commit is contained in:
@@ -73,6 +73,7 @@ from freqtrade.exchange.exchange_types import (
|
||||
CcxtPosition,
|
||||
FtHas,
|
||||
FundingRate,
|
||||
LeverageTier,
|
||||
OHLCVResponse,
|
||||
OrderBook,
|
||||
Ticker,
|
||||
@@ -194,7 +195,7 @@ class Exchange:
|
||||
self._exchange_ws: ExchangeWS | None = None
|
||||
self._markets: dict = {}
|
||||
self._trading_fees: dict[str, Any] = {}
|
||||
self._leverage_tiers: dict[str, list[dict]] = {}
|
||||
self._leverage_tiers: dict[str, list[LeverageTier]] = {}
|
||||
# Lock event loop. This is necessary to avoid race-conditions when using force* commands
|
||||
# Due to funding fee fetching.
|
||||
self._loop_lock = Lock()
|
||||
@@ -3621,7 +3622,7 @@ class Exchange:
|
||||
pair_tiers.append(self.parse_leverage_tier(tier))
|
||||
self._leverage_tiers[pair] = pair_tiers
|
||||
|
||||
def parse_leverage_tier(self, tier) -> dict:
|
||||
def parse_leverage_tier(self, tier) -> LeverageTier:
|
||||
info = tier.get("info", {})
|
||||
return {
|
||||
"minNotional": tier["minNotional"],
|
||||
@@ -3662,7 +3663,11 @@ class Exchange:
|
||||
for tier in pair_tiers:
|
||||
# Adjust notional by leverage to do a proper comparison
|
||||
min_stake = tier["minNotional"] / (prior_max_lev or tier["maxLeverage"])
|
||||
max_stake = tier["maxNotional"] / tier["maxLeverage"]
|
||||
max_stake = (
|
||||
tier["maxNotional"] / tier["maxLeverage"]
|
||||
if tier["maxNotional"] is not None
|
||||
else float("inf")
|
||||
)
|
||||
prior_max_lev = tier["maxLeverage"]
|
||||
if min_stake <= stake_amount <= max_stake:
|
||||
return tier["maxLeverage"]
|
||||
|
||||
@@ -115,5 +115,27 @@ class CcxtPosition(TypedDict):
|
||||
|
||||
CcxtOrder = dict[str, Any]
|
||||
|
||||
|
||||
class LeverageTier(TypedDict):
|
||||
"""
|
||||
Represents a single leverage tier returned by the exchange.
|
||||
|
||||
Attributes:
|
||||
minNotional: Minimum notional value (quote currency) for which this tier applies.
|
||||
maxNotional: Maximum notional value (quote currency) for which this tier applies.
|
||||
When ``maxNotional`` is ``None``, the tier is unbounded on the upper side,
|
||||
i.e. there is no maximum notional limit for this tier
|
||||
maintenanceMarginRate: Maintenance margin rate for this tier (fraction, e.g. 0.005 for 0.5%)
|
||||
maxLeverage: Maximum leverage allowed for this tier
|
||||
maintAmt: Optional fixed maintenance margin amount, if provided by the exchange
|
||||
"""
|
||||
|
||||
minNotional: float
|
||||
maxNotional: float | None
|
||||
maintenanceMarginRate: float
|
||||
maxLeverage: float
|
||||
maintAmt: float | None
|
||||
|
||||
|
||||
# pair, timeframe, candleType, OHLCV, drop last?,
|
||||
OHLCVResponse = tuple[str, str, CandleType, list, bool]
|
||||
|
||||
@@ -182,7 +182,10 @@ class Okx(Exchange):
|
||||
return float("inf")
|
||||
|
||||
pair_tiers = self._leverage_tiers[pair]
|
||||
return pair_tiers[-1]["maxNotional"] / leverage
|
||||
last_max_notional = pair_tiers[-1]["maxNotional"]
|
||||
if last_max_notional is None:
|
||||
return float("inf")
|
||||
return last_max_notional / leverage
|
||||
|
||||
def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> dict:
|
||||
params = super()._get_stop_params(side, ordertype, stop_price)
|
||||
|
||||
Reference in New Issue
Block a user