mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 10:21:59 +00:00
okex loads all leverage tiers at beginning, removed get tiers for pair
This commit is contained in:
parent
8657e99c26
commit
7a0f7da128
|
@ -1894,28 +1894,6 @@ class Exchange:
|
|||
'maintAmt': float(info['cum']) if 'cum' in info else None,
|
||||
}
|
||||
|
||||
@retrier
|
||||
def get_leverage_tiers_for_pair(self, pair: str) -> List:
|
||||
# When exchanges can load all their leverage tiers at once in the constructor
|
||||
# then this method does nothing, it should only be implemented when the leverage
|
||||
# tiers requires per symbol fetching to avoid excess api calls
|
||||
if pair not in self._leverage_tiers:
|
||||
self._leverage_tiers[pair] = []
|
||||
if (
|
||||
self._api.has['fetchLeverageTiers'] and
|
||||
not self._ft_has['can_fetch_multiple_tiers'] and
|
||||
self.trading_mode == TradingMode.FUTURES
|
||||
):
|
||||
try:
|
||||
tiers = self._api.fetch_leverage_tiers(pair)
|
||||
for tier in tiers[pair]:
|
||||
self._leverage_tiers[pair].append(self.parse_leverage_tier(tier))
|
||||
|
||||
except ccxt.BadRequest:
|
||||
return []
|
||||
|
||||
return self._leverage_tiers[pair]
|
||||
|
||||
def get_max_leverage(self, pair: str, stake_amount: Optional[float]) -> float:
|
||||
"""
|
||||
Returns the maximum leverage that a pair can be traded at
|
||||
|
@ -1926,7 +1904,7 @@ class Exchange:
|
|||
if self.trading_mode == TradingMode.SPOT:
|
||||
return 1.0
|
||||
|
||||
if self._api.has['fetchLeverageTiers']:
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
|
||||
# Checks and edge cases
|
||||
if stake_amount is None:
|
||||
|
@ -1934,20 +1912,21 @@ class Exchange:
|
|||
f'{self.name}.get_max_leverage requires argument stake_amount'
|
||||
)
|
||||
|
||||
pair_tiers = self.get_leverage_tiers_for_pair(pair)
|
||||
num_tiers = len(pair_tiers)
|
||||
if num_tiers < 1:
|
||||
if pair not in self._leverage_tiers:
|
||||
# Maybe raise exception because it can't be traded on futures?
|
||||
return 1.0
|
||||
|
||||
pair_tiers = self._leverage_tiers[pair]
|
||||
|
||||
if stake_amount == 0:
|
||||
return self._leverage_tiers[pair][0]['lev'] # Max lev for lowest amount
|
||||
|
||||
for tier_index in range(num_tiers):
|
||||
for tier_index in range(len(pair_tiers)):
|
||||
|
||||
tier = pair_tiers[tier_index]
|
||||
lev = tier['lev']
|
||||
|
||||
if tier_index < num_tiers - 1:
|
||||
if tier_index < len(pair_tiers) - 1:
|
||||
next_tier = pair_tiers[tier_index+1]
|
||||
next_floor = next_tier['min'] / next_tier['lev']
|
||||
if next_floor > stake_amount: # Next tier min too high for stake amount
|
||||
|
@ -2280,13 +2259,13 @@ class Exchange:
|
|||
|
||||
if self._api.has['fetchLeverageTiers']:
|
||||
|
||||
pair_tiers = self.get_leverage_tiers_for_pair(pair)
|
||||
|
||||
if len(pair_tiers) < 1:
|
||||
if pair not in self._leverage_tiers:
|
||||
raise InvalidOrderException(
|
||||
f"Maintenance margin rate for {pair} is unavailable for {self.name}"
|
||||
)
|
||||
|
||||
pair_tiers = self._leverage_tiers[pair]
|
||||
|
||||
for tier in reversed(pair_tiers):
|
||||
if nominal_value >= tier['min']:
|
||||
return (tier['mmr'], tier['maintAmt'])
|
||||
|
|
|
@ -59,14 +59,25 @@ class Okx(Exchange):
|
|||
return float('inf') # Not actually inf, but this probably won't matter for SPOT
|
||||
|
||||
if pair not in self._leverage_tiers:
|
||||
tiers = self.get_leverage_tiers_for_pair(pair)
|
||||
if not tiers: # Not a leveraged market
|
||||
return float('inf')
|
||||
else:
|
||||
self._leverage_tiers[pair] = tiers
|
||||
return float('inf')
|
||||
|
||||
pair_tiers = self._leverage_tiers[pair]
|
||||
return pair_tiers[-1]['max'] / leverage
|
||||
|
||||
def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
|
||||
return {}
|
||||
if self.trading_mode == TradingMode.FUTURES:
|
||||
markets = self.markets
|
||||
symbols = []
|
||||
|
||||
for symbol, market in markets.items():
|
||||
if (market["swap"] and market["linear"]):
|
||||
symbols.append(market["symbol"])
|
||||
|
||||
tiers = {}
|
||||
for symbol in symbols:
|
||||
res = self._api.fetchLeverageTiers(symbol)
|
||||
tiers[symbol] = res[symbol]
|
||||
|
||||
return tiers
|
||||
else:
|
||||
return {}
|
||||
|
|
|
@ -4300,115 +4300,6 @@ def test_parse_leverage_tier(mocker, default_conf):
|
|||
}
|
||||
|
||||
|
||||
def test_get_leverage_tiers_for_pair(
|
||||
mocker,
|
||||
default_conf,
|
||||
leverage_tiers,
|
||||
):
|
||||
|
||||
api_mock = MagicMock()
|
||||
api_mock.fetch_leverage_tiers = MagicMock(return_value={
|
||||
'DOGE/USDT:USDT': [
|
||||
{
|
||||
'tier': 1,
|
||||
'notionalFloor': 0,
|
||||
'notionalCap': 500,
|
||||
'maintenanceMarginRatio': 0.02,
|
||||
'maxLeverage': 75,
|
||||
'info': {
|
||||
'baseMaxLoan': '',
|
||||
'imr': '0.013',
|
||||
'instId': '',
|
||||
'maxLever': '75',
|
||||
'maxSz': '500',
|
||||
'minSz': '0',
|
||||
'mmr': '0.01',
|
||||
'optMgnFactor': '0',
|
||||
'quoteMaxLoan': '',
|
||||
'tier': '1',
|
||||
'uly': 'DOGE-USDT'
|
||||
}
|
||||
},
|
||||
{
|
||||
'tier': 2,
|
||||
'notionalFloor': 501,
|
||||
'notionalCap': 1000,
|
||||
'maintenanceMarginRatio': 0.025,
|
||||
'maxLeverage': 50,
|
||||
'info': {
|
||||
'baseMaxLoan': '',
|
||||
'imr': '0.02',
|
||||
'instId': '',
|
||||
'maxLever': '50',
|
||||
'maxSz': '1000',
|
||||
'minSz': '501',
|
||||
'mmr': '0.015',
|
||||
'optMgnFactor': '0',
|
||||
'quoteMaxLoan': '',
|
||||
'tier': '2',
|
||||
'uly': 'DOGE-USDT'
|
||||
}
|
||||
}
|
||||
],
|
||||
})
|
||||
|
||||
# Spot
|
||||
type(api_mock)._ft_has = PropertyMock(return_value={'fetchLeverageTiers': True})
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange._ft_has['can_fetch_multiple_tiers'] = False
|
||||
assert exchange.get_leverage_tiers_for_pair('DOGE/USDT:USDT') == []
|
||||
|
||||
# 'can_fetch_multiple_tiers': True
|
||||
default_conf['trading_mode'] = 'futures'
|
||||
default_conf['margin_mode'] = 'isolated'
|
||||
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': True})
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange._ft_has['can_fetch_multiple_tiers'] = True
|
||||
assert exchange.get_leverage_tiers_for_pair('DOGE/USDT:USDT') == []
|
||||
|
||||
# 'fetchLeverageTiers': False
|
||||
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': False})
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange._ft_has['can_fetch_multiple_tiers'] = False
|
||||
assert exchange.get_leverage_tiers_for_pair('DOGE/USDT:USDT') == []
|
||||
|
||||
# 'fetchLeverageTiers': True
|
||||
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': True})
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
exchange._ft_has['can_fetch_multiple_tiers'] = False
|
||||
assert exchange.get_leverage_tiers_for_pair('DOGE/USDT:USDT') == [
|
||||
{
|
||||
'min': 0,
|
||||
'max': 500,
|
||||
'mmr': 0.02,
|
||||
'lev': 75,
|
||||
'maintAmt': None
|
||||
},
|
||||
{
|
||||
'min': 501,
|
||||
'max': 1000,
|
||||
'mmr': 0.025,
|
||||
'lev': 50,
|
||||
'maintAmt': None
|
||||
}
|
||||
]
|
||||
|
||||
# exception_handlers
|
||||
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': True})
|
||||
default_conf['dry_run'] = False
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||
|
||||
ccxt_exceptionhandlers(
|
||||
mocker,
|
||||
default_conf,
|
||||
api_mock,
|
||||
"binance",
|
||||
"get_leverage_tiers_for_pair",
|
||||
"fetch_leverage_tiers",
|
||||
pair='DOGE/USDT:USDT',
|
||||
)
|
||||
|
||||
|
||||
def test_get_maintenance_ratio_and_amt_exceptions(mocker, default_conf, leverage_tiers):
|
||||
api_mock = MagicMock()
|
||||
default_conf['trading_mode'] = 'futures'
|
||||
|
@ -4423,7 +4314,6 @@ def test_get_maintenance_ratio_and_amt_exceptions(mocker, default_conf, leverage
|
|||
exchange.get_maintenance_ratio_and_amt('1000SHIB/USDT', -1)
|
||||
|
||||
exchange._leverage_tiers = {}
|
||||
exchange.get_leverage_tiers_for_pair = MagicMock(return_value=[])
|
||||
|
||||
with pytest.raises(
|
||||
InvalidOrderException,
|
||||
|
|
|
@ -162,5 +162,4 @@ def test_get_max_pair_stake_amount_okex(default_conf, mocker, leverage_tiers):
|
|||
assert exchange.get_max_pair_stake_amount('BTC/USDT', 1.0) == 1000000000
|
||||
assert exchange.get_max_pair_stake_amount('BTC/USDT', 1.0, 10.0) == 100000000
|
||||
|
||||
exchange.get_leverage_tiers_for_pair = MagicMock(return_value=None)
|
||||
assert exchange.get_max_pair_stake_amount('TTT/USDT', 1.0) == float('inf') # Not in tiers
|
||||
|
|
Loading…
Reference in New Issue
Block a user