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,
|
CcxtPosition,
|
||||||
FtHas,
|
FtHas,
|
||||||
FundingRate,
|
FundingRate,
|
||||||
|
LeverageTier,
|
||||||
OHLCVResponse,
|
OHLCVResponse,
|
||||||
OrderBook,
|
OrderBook,
|
||||||
Ticker,
|
Ticker,
|
||||||
@@ -194,7 +195,7 @@ class Exchange:
|
|||||||
self._exchange_ws: ExchangeWS | None = None
|
self._exchange_ws: ExchangeWS | None = None
|
||||||
self._markets: dict = {}
|
self._markets: dict = {}
|
||||||
self._trading_fees: dict[str, Any] = {}
|
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
|
# Lock event loop. This is necessary to avoid race-conditions when using force* commands
|
||||||
# Due to funding fee fetching.
|
# Due to funding fee fetching.
|
||||||
self._loop_lock = Lock()
|
self._loop_lock = Lock()
|
||||||
@@ -3621,7 +3622,7 @@ class Exchange:
|
|||||||
pair_tiers.append(self.parse_leverage_tier(tier))
|
pair_tiers.append(self.parse_leverage_tier(tier))
|
||||||
self._leverage_tiers[pair] = pair_tiers
|
self._leverage_tiers[pair] = pair_tiers
|
||||||
|
|
||||||
def parse_leverage_tier(self, tier) -> dict:
|
def parse_leverage_tier(self, tier) -> LeverageTier:
|
||||||
info = tier.get("info", {})
|
info = tier.get("info", {})
|
||||||
return {
|
return {
|
||||||
"minNotional": tier["minNotional"],
|
"minNotional": tier["minNotional"],
|
||||||
@@ -3662,7 +3663,11 @@ class Exchange:
|
|||||||
for tier in pair_tiers:
|
for tier in pair_tiers:
|
||||||
# Adjust notional by leverage to do a proper comparison
|
# Adjust notional by leverage to do a proper comparison
|
||||||
min_stake = tier["minNotional"] / (prior_max_lev or tier["maxLeverage"])
|
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"]
|
prior_max_lev = tier["maxLeverage"]
|
||||||
if min_stake <= stake_amount <= max_stake:
|
if min_stake <= stake_amount <= max_stake:
|
||||||
return tier["maxLeverage"]
|
return tier["maxLeverage"]
|
||||||
|
|||||||
@@ -115,5 +115,27 @@ class CcxtPosition(TypedDict):
|
|||||||
|
|
||||||
CcxtOrder = dict[str, Any]
|
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?,
|
# pair, timeframe, candleType, OHLCV, drop last?,
|
||||||
OHLCVResponse = tuple[str, str, CandleType, list, bool]
|
OHLCVResponse = tuple[str, str, CandleType, list, bool]
|
||||||
|
|||||||
@@ -182,7 +182,10 @@ class Okx(Exchange):
|
|||||||
return float("inf")
|
return float("inf")
|
||||||
|
|
||||||
pair_tiers = self._leverage_tiers[pair]
|
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:
|
def _get_stop_params(self, side: BuySell, ordertype: str, stop_price: float) -> dict:
|
||||||
params = super()._get_stop_params(side, ordertype, stop_price)
|
params = super()._get_stop_params(side, ordertype, stop_price)
|
||||||
|
|||||||
Reference in New Issue
Block a user