Added some exchange leverage tier tests
This commit is contained in:
parent
98f32e8964
commit
eb72e5cc42
@ -2247,11 +2247,16 @@ class Exchange:
|
|||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
"Freqtrade only supports isolated futures for leverage trading")
|
"Freqtrade only supports isolated futures for leverage trading")
|
||||||
|
|
||||||
|
@retrier
|
||||||
def get_leverage_tiers_for_pair(self, pair: str):
|
def get_leverage_tiers_for_pair(self, pair: str):
|
||||||
# When exchanges can load all their leverage tiers at once in the constructor
|
# 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
|
# then this method does nothing, it should only be implemented when the leverage
|
||||||
# tiers requires per symbol fetching to avoid excess api calls
|
# tiers requires per symbol fetching to avoid excess api calls
|
||||||
if not self._ft_has['can_fetch_multiple_tiers']:
|
if (
|
||||||
|
self._api.has['fetchLeverageTiers'] and
|
||||||
|
not self._ft_has['can_fetch_multiple_tiers'] and
|
||||||
|
self.trading_mode == TradingMode.FUTURES
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
return self._api.fetch_leverage_tiers(pair)
|
return self._api.fetch_leverage_tiers(pair)
|
||||||
except ccxt.BadRequest:
|
except ccxt.BadRequest:
|
||||||
|
@ -628,12 +628,3 @@ def test_get_maintenance_ratio_and_amt_binance(
|
|||||||
exchange._leverage_tiers = leverage_tiers
|
exchange._leverage_tiers = leverage_tiers
|
||||||
(result_ratio, result_amt) = exchange.get_maintenance_ratio_and_amt(pair, nominal_value)
|
(result_ratio, result_amt) = exchange.get_maintenance_ratio_and_amt(pair, nominal_value)
|
||||||
assert (round(result_ratio, 8), round(result_amt, 8)) == (mm_ratio, amt)
|
assert (round(result_ratio, 8), round(result_amt, 8)) == (mm_ratio, amt)
|
||||||
|
|
||||||
|
|
||||||
def test_load_leverage_tiers_binance(mocker, default_conf, leverage_tiers):
|
|
||||||
# TODO-lev
|
|
||||||
api_mock = MagicMock()
|
|
||||||
default_conf['trading_mode'] = 'futures'
|
|
||||||
default_conf['margin_mode'] = 'isolated'
|
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
|
||||||
assert exchange
|
|
||||||
|
@ -3560,8 +3560,7 @@ def test__ccxt_config(
|
|||||||
("LTC/BTC", 0.0, 1.0),
|
("LTC/BTC", 0.0, 1.0),
|
||||||
("TKN/USDT", 210.30, 1.0),
|
("TKN/USDT", 210.30, 1.0),
|
||||||
])
|
])
|
||||||
def test_get_max_leverage(default_conf, mocker, pair, nominal_value, max_lev):
|
def test_get_max_leverage_from_markets(default_conf, mocker, pair, nominal_value, max_lev):
|
||||||
# TODO-lev: Branch coverage
|
|
||||||
default_conf['trading_mode'] = 'futures'
|
default_conf['trading_mode'] = 'futures'
|
||||||
default_conf['margin_mode'] = 'isolated'
|
default_conf['margin_mode'] = 'isolated'
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
@ -3570,6 +3569,11 @@ def test_get_max_leverage(default_conf, mocker, pair, nominal_value, max_lev):
|
|||||||
assert exchange.get_max_leverage(pair, nominal_value) == max_lev
|
assert exchange.get_max_leverage(pair, nominal_value) == max_lev
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_max_leverage_from_tiers(default_conf, mocker):
|
||||||
|
# TODO-lev:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'size,funding_rate,mark_price,time_in_ratio,funding_fee,kraken_fee', [
|
'size,funding_rate,mark_price,time_in_ratio,funding_fee,kraken_fee', [
|
||||||
(10, 0.0001, 2.0, 1.0, 0.002, 0.002),
|
(10, 0.0001, 2.0, 1.0, 0.002, 0.002),
|
||||||
@ -4227,45 +4231,123 @@ def test_get_max_pair_stake_amount(
|
|||||||
|
|
||||||
|
|
||||||
def test_load_leverage_tiers(mocker, default_conf, leverage_tiers):
|
def test_load_leverage_tiers(mocker, default_conf, leverage_tiers):
|
||||||
# TODO-lev
|
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
default_conf['trading_mode'] = 'futures'
|
api_mock.fetch_leverage_tiers = MagicMock()
|
||||||
default_conf['margin_mode'] = 'isolated'
|
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
|
||||||
|
|
||||||
api_mock = MagicMock()
|
|
||||||
api_mock.set_margin_mode = MagicMock()
|
|
||||||
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': True})
|
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': True})
|
||||||
default_conf['dry_run'] = False
|
default_conf['dry_run'] = False
|
||||||
|
default_conf['trading_mode'] = 'futures'
|
||||||
|
default_conf['margin_mode'] = 'isolated'
|
||||||
|
|
||||||
ccxt_exceptionhandlers(
|
ccxt_exceptionhandlers(
|
||||||
mocker,
|
mocker,
|
||||||
default_conf,
|
default_conf,
|
||||||
api_mock,
|
api_mock,
|
||||||
"binance",
|
"binance",
|
||||||
"set_margin_mode",
|
"load_leverage_tiers",
|
||||||
"set_margin_mode",
|
"fetch_leverage_tiers",
|
||||||
pair="XRP/USDT",
|
|
||||||
margin_mode=margin_mode
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_parse_leverage_tier(mocker, default_conf, leverage_tiers):
|
def test_parse_leverage_tier(mocker, default_conf):
|
||||||
# TODO-lev
|
exchange = get_patched_exchange(mocker, default_conf)
|
||||||
api_mock = MagicMock()
|
|
||||||
default_conf['trading_mode'] = 'futures'
|
tier = {
|
||||||
default_conf['margin_mode'] = 'isolated'
|
"tier": 1,
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
"notionalFloor": 0,
|
||||||
assert exchange
|
"notionalCap": 100000,
|
||||||
|
"maintenanceMarginRatio": 0.025,
|
||||||
|
"maxLeverage": 20,
|
||||||
|
"info": {
|
||||||
|
"bracket": "1",
|
||||||
|
"initialLeverage": "20",
|
||||||
|
"notionalCap": "100000",
|
||||||
|
"notionalFloor": "0",
|
||||||
|
"maintMarginRatio": "0.025",
|
||||||
|
"cum": "0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert exchange.parse_leverage_tier(tier) == {
|
||||||
|
"min": 0,
|
||||||
|
"max": 100000,
|
||||||
|
"mmr": 0.025,
|
||||||
|
"lev": 20,
|
||||||
|
"maintAmt": 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
tier2 = {
|
||||||
|
'tier': 1,
|
||||||
|
'notionalFloor': 0,
|
||||||
|
'notionalCap': 2000,
|
||||||
|
'maintenanceMarginRatio': 0.01,
|
||||||
|
'maxLeverage': 75,
|
||||||
|
'info': {
|
||||||
|
'baseMaxLoan': '',
|
||||||
|
'imr': '0.013',
|
||||||
|
'instId': '',
|
||||||
|
'maxLever': '75',
|
||||||
|
'maxSz': '2000',
|
||||||
|
'minSz': '0',
|
||||||
|
'mmr': '0.01',
|
||||||
|
'optMgnFactor': '0',
|
||||||
|
'quoteMaxLoan': '',
|
||||||
|
'tier': '1',
|
||||||
|
'uly': 'SHIB-USDT'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert exchange.parse_leverage_tier(tier2) == {
|
||||||
|
'min': 0,
|
||||||
|
'max': 2000,
|
||||||
|
'mmr': 0.01,
|
||||||
|
'lev': 75,
|
||||||
|
"maintAmt": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_get_leverage_tiers_for_pair(mocker, default_conf, leverage_tiers):
|
def test_get_leverage_tiers_for_pair(mocker, default_conf, leverage_tiers):
|
||||||
# TODO-lev
|
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
|
api_mock.fetch_leverage_tiers = MagicMock()
|
||||||
|
# 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('ADA/USDT') is None
|
||||||
|
|
||||||
|
# 'can_fetch_multiple_tiers': True
|
||||||
default_conf['trading_mode'] = 'futures'
|
default_conf['trading_mode'] = 'futures'
|
||||||
default_conf['margin_mode'] = 'isolated'
|
default_conf['margin_mode'] = 'isolated'
|
||||||
|
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': True})
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
exchange = get_patched_exchange(mocker, default_conf, api_mock)
|
||||||
assert exchange
|
exchange._ft_has['can_fetch_multiple_tiers'] = True
|
||||||
|
assert exchange.get_leverage_tiers_for_pair('ADA/USDT:USDT') is None
|
||||||
|
|
||||||
|
# '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('ADA/USDT:USDT') is None
|
||||||
|
|
||||||
|
# 'fetchLeverageTiers': False
|
||||||
|
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('ADA/USDT:USDT') is not None
|
||||||
|
|
||||||
|
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='ETH/USDT:USDT',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_get_maintenance_ratio_and_amt(mocker, default_conf, leverage_tiers):
|
def test_get_maintenance_ratio_and_amt(mocker, default_conf, leverage_tiers):
|
||||||
|
Loading…
Reference in New Issue
Block a user