Merge branch 'leverage-tiers' of https://github.com/samgermain/freqtrade into leverage-tiers
This commit is contained in:
commit
dbd2df6406
@ -246,6 +246,7 @@ class Binance(Exchange):
|
|||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
"Freqtrade only supports isolated futures for leverage trading")
|
"Freqtrade only supports isolated futures for leverage trading")
|
||||||
|
|
||||||
|
@retrier
|
||||||
def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
|
def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
|
||||||
if self._config['dry_run']:
|
if self._config['dry_run']:
|
||||||
leverage_tiers_path = (
|
leverage_tiers_path = (
|
||||||
|
@ -1858,6 +1858,7 @@ class Exchange:
|
|||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e) from e
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
|
@retrier
|
||||||
def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
|
def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
|
||||||
if self.trading_mode == TradingMode.FUTURES and self.exchange_has('fetchLeverageTiers'):
|
if self.trading_mode == TradingMode.FUTURES and self.exchange_has('fetchLeverageTiers'):
|
||||||
try:
|
try:
|
||||||
@ -1874,7 +1875,6 @@ class Exchange:
|
|||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@retrier
|
|
||||||
def fill_leverage_tiers(self) -> None:
|
def fill_leverage_tiers(self) -> None:
|
||||||
"""
|
"""
|
||||||
Assigns property _leverage_tiers to a dictionary of information about the leverage
|
Assigns property _leverage_tiers to a dictionary of information about the leverage
|
||||||
@ -1888,7 +1888,7 @@ class Exchange:
|
|||||||
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) -> Dict:
|
||||||
info = tier['info']
|
info = tier.get('info', {})
|
||||||
return {
|
return {
|
||||||
'min': tier['notionalFloor'],
|
'min': tier['notionalFloor'],
|
||||||
'max': tier['notionalCap'],
|
'max': tier['notionalCap'],
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import logging
|
import logging
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
|
import ccxt
|
||||||
|
|
||||||
from freqtrade.enums import MarginMode, TradingMode
|
from freqtrade.enums import MarginMode, TradingMode
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import DDosProtection, OperationalException, TemporaryError
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
|
from freqtrade.exchange.common import retrier
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -29,6 +32,25 @@ class Okx(Exchange):
|
|||||||
(TradingMode.FUTURES, MarginMode.ISOLATED),
|
(TradingMode.FUTURES, MarginMode.ISOLATED),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def _get_params(
|
||||||
|
self,
|
||||||
|
ordertype: str,
|
||||||
|
leverage: float,
|
||||||
|
reduceOnly: bool,
|
||||||
|
time_in_force: str = 'gtc',
|
||||||
|
) -> Dict:
|
||||||
|
# TODO-lev: Test me
|
||||||
|
params = super()._get_params(
|
||||||
|
ordertype=ordertype,
|
||||||
|
leverage=leverage,
|
||||||
|
reduceOnly=reduceOnly,
|
||||||
|
time_in_force=time_in_force,
|
||||||
|
)
|
||||||
|
if self.trading_mode == TradingMode.FUTURES and self.margin_mode:
|
||||||
|
params['tdMode'] = self.margin_mode.value
|
||||||
|
return params
|
||||||
|
|
||||||
|
@retrier
|
||||||
def _lev_prep(
|
def _lev_prep(
|
||||||
self,
|
self,
|
||||||
pair: str,
|
pair: str,
|
||||||
@ -40,13 +62,22 @@ class Okx(Exchange):
|
|||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f"{self.name}.margin_mode must be set for {self.trading_mode.value}"
|
f"{self.name}.margin_mode must be set for {self.trading_mode.value}"
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
# TODO-lev: Test me properly (check mgnMode passed)
|
||||||
self._api.set_leverage(
|
self._api.set_leverage(
|
||||||
leverage,
|
leverage=leverage,
|
||||||
pair,
|
symbol=pair,
|
||||||
params={
|
params={
|
||||||
"mgnMode": self.margin_mode.value,
|
"mgnMode": self.margin_mode.value,
|
||||||
"posSide": "long" if side == "buy" else "short",
|
# "posSide": "net"",
|
||||||
})
|
})
|
||||||
|
except ccxt.DDoSProtection as e:
|
||||||
|
raise DDosProtection(e) from e
|
||||||
|
except (ccxt.NetworkError, ccxt.ExchangeError) as e:
|
||||||
|
raise TemporaryError(
|
||||||
|
f'Could not set leverage due to {e.__class__.__name__}. Message: {e}') from e
|
||||||
|
except ccxt.BaseError as e:
|
||||||
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
def get_max_pair_stake_amount(
|
def get_max_pair_stake_amount(
|
||||||
self,
|
self,
|
||||||
@ -64,6 +95,7 @@ class Okx(Exchange):
|
|||||||
pair_tiers = self._leverage_tiers[pair]
|
pair_tiers = self._leverage_tiers[pair]
|
||||||
return pair_tiers[-1]['max'] / leverage
|
return pair_tiers[-1]['max'] / leverage
|
||||||
|
|
||||||
|
@retrier
|
||||||
def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
|
def load_leverage_tiers(self) -> Dict[str, List[Dict]]:
|
||||||
# * This is slow(~45s) on Okex, must make 90-some api calls to load all linear swap markets
|
# * This is slow(~45s) on Okex, must make 90-some api calls to load all linear swap markets
|
||||||
if self.trading_mode == TradingMode.FUTURES:
|
if self.trading_mode == TradingMode.FUTURES:
|
||||||
@ -82,11 +114,9 @@ class Okx(Exchange):
|
|||||||
f"Initializing leverage_tiers for {len(symbols)} markets. "
|
f"Initializing leverage_tiers for {len(symbols)} markets. "
|
||||||
"This will take about a minute.")
|
"This will take about a minute.")
|
||||||
|
|
||||||
for symbol in symbols:
|
for symbol in sorted(symbols):
|
||||||
res = self._api.fetchLeverageTiers(symbol)
|
res = self._api.fetch_leverage_tiers(symbol)
|
||||||
tiers[symbol] = []
|
tiers[symbol] = res[symbol]
|
||||||
for tier in res[symbol]:
|
|
||||||
tiers[symbol].append(self.parse_leverage_tier(tier))
|
|
||||||
logger.info(f"Done initializing {len(symbols)} markets.")
|
logger.info(f"Done initializing {len(symbols)} markets.")
|
||||||
|
|
||||||
return tiers
|
return tiers
|
||||||
|
@ -231,9 +231,9 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 10 active markets: "
|
assert ("Exchange Bittrex has 12 active markets: "
|
||||||
"BLK/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, NEO/BTC, "
|
"ADA/USDT:USDT, BLK/BTC, ETH/BTC, ETH/USDT, ETH/USDT:USDT, LTC/BTC, "
|
||||||
"TKN/BTC, XLTCUSDT, XRP/BTC.\n"
|
"LTC/ETH, LTC/USD, NEO/BTC, TKN/BTC, XLTCUSDT, XRP/BTC.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
patch_exchange(mocker, api_mock=api_mock, id="binance", mock_markets=markets_static)
|
patch_exchange(mocker, api_mock=api_mock, id="binance", mock_markets=markets_static)
|
||||||
@ -246,7 +246,7 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
pargs['config'] = None
|
pargs['config'] = None
|
||||||
start_list_markets(pargs, False)
|
start_list_markets(pargs, False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert re.match("\nExchange Binance has 10 active markets:\n",
|
assert re.match("\nExchange Binance has 12 active markets:\n",
|
||||||
captured.out)
|
captured.out)
|
||||||
|
|
||||||
patch_exchange(mocker, api_mock=api_mock, id="bittrex", mock_markets=markets_static)
|
patch_exchange(mocker, api_mock=api_mock, id="bittrex", mock_markets=markets_static)
|
||||||
@ -258,9 +258,9 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 12 markets: "
|
assert ("Exchange Bittrex has 14 markets: "
|
||||||
"BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, "
|
"ADA/USDT:USDT, BLK/BTC, BTT/BTC, ETH/BTC, ETH/USDT, ETH/USDT:USDT, "
|
||||||
"TKN/BTC, XLTCUSDT, XRP/BTC.\n"
|
"LTC/BTC, LTC/ETH, LTC/USD, LTC/USDT, NEO/BTC, TKN/BTC, XLTCUSDT, XRP/BTC.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# Test list-pairs subcommand: active pairs
|
# Test list-pairs subcommand: active pairs
|
||||||
@ -297,8 +297,8 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 6 active markets with ETH, LTC as base currencies: "
|
assert ("Exchange Bittrex has 7 active markets with ETH, LTC as base currencies: "
|
||||||
"ETH/BTC, ETH/USDT, LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n"
|
"ETH/BTC, ETH/USDT, ETH/USDT:USDT, LTC/BTC, LTC/ETH, LTC/USD, XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, base=LTC
|
# active markets, base=LTC
|
||||||
@ -323,8 +323,8 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 3 active markets with USDT, USD as quote currencies: "
|
assert ("Exchange Bittrex has 5 active markets with USDT, USD as quote currencies: "
|
||||||
"ETH/USDT, LTC/USD, XLTCUSDT.\n"
|
"ADA/USDT:USDT, ETH/USDT, ETH/USDT:USDT, LTC/USD, XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, quote=USDT
|
# active markets, quote=USDT
|
||||||
@ -336,8 +336,8 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 2 active markets with USDT as quote currency: "
|
assert ("Exchange Bittrex has 4 active markets with USDT as quote currency: "
|
||||||
"ETH/USDT, XLTCUSDT.\n"
|
"ADA/USDT:USDT, ETH/USDT, ETH/USDT:USDT, XLTCUSDT.\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# active markets, base=LTC, quote=USDT
|
# active markets, base=LTC, quote=USDT
|
||||||
@ -399,7 +399,7 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ("Exchange Bittrex has 10 active markets:\n"
|
assert ("Exchange Bittrex has 12 active markets:\n"
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# Test tabular output, no markets found
|
# Test tabular output, no markets found
|
||||||
@ -422,8 +422,8 @@ def test_list_markets(mocker, markets_static, capsys):
|
|||||||
]
|
]
|
||||||
start_list_markets(get_args(args), False)
|
start_list_markets(get_args(args), False)
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert ('["BLK/BTC","ETH/BTC","ETH/USDT","LTC/BTC","LTC/ETH","LTC/USD","NEO/BTC",'
|
assert ('["ADA/USDT:USDT","BLK/BTC","ETH/BTC","ETH/USDT","ETH/USDT:USDT",'
|
||||||
'"TKN/BTC","XLTCUSDT","XRP/BTC"]'
|
'"LTC/BTC","LTC/ETH","LTC/USD","NEO/BTC","TKN/BTC","XLTCUSDT","XRP/BTC"]'
|
||||||
in captured.out)
|
in captured.out)
|
||||||
|
|
||||||
# Test --print-csv
|
# Test --print-csv
|
||||||
|
@ -891,8 +891,8 @@ def get_markets():
|
|||||||
'future': True,
|
'future': True,
|
||||||
'swap': True,
|
'swap': True,
|
||||||
'margin': True,
|
'margin': True,
|
||||||
'linear': False,
|
'linear': None,
|
||||||
'inverse': True,
|
'inverse': False,
|
||||||
'type': 'spot',
|
'type': 'spot',
|
||||||
'contractSize': None,
|
'contractSize': None,
|
||||||
'taker': 0.0006,
|
'taker': 0.0006,
|
||||||
@ -1398,7 +1398,9 @@ def markets_static():
|
|||||||
# market list. Do not modify this list without a good reason! Do not modify market parameters
|
# market list. Do not modify this list without a good reason! Do not modify market parameters
|
||||||
# of listed pairs in get_markets() without a good reason either!
|
# of listed pairs in get_markets() without a good reason either!
|
||||||
static_markets = ['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD',
|
static_markets = ['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD',
|
||||||
'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC']
|
'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC',
|
||||||
|
'ADA/USDT:USDT', 'ETH/USDT:USDT',
|
||||||
|
]
|
||||||
all_markets = get_markets()
|
all_markets = get_markets()
|
||||||
return {m: all_markets[m] for m in static_markets}
|
return {m: all_markets[m] for m in static_markets}
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ def test_fill_leverage_tiers_binance(default_conf, mocker):
|
|||||||
api_mock,
|
api_mock,
|
||||||
"binance",
|
"binance",
|
||||||
"fill_leverage_tiers",
|
"fill_leverage_tiers",
|
||||||
"fetch_leverage_tiers"
|
"fetch_leverage_tiers",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -341,9 +341,9 @@ class TestCCXTExchange():
|
|||||||
|
|
||||||
def test_ccxt_get_max_leverage_futures(self, exchange_futures):
|
def test_ccxt_get_max_leverage_futures(self, exchange_futures):
|
||||||
futures, futures_name = exchange_futures
|
futures, futures_name = exchange_futures
|
||||||
# TODO-lev: binance, gateio, and okx test
|
|
||||||
if futures:
|
if futures:
|
||||||
leverage_in_market_futures = EXCHANGES[futures_name]['leverage_in_market']['futures']
|
leverage_in_market_futures = EXCHANGES[futures_name]['leverage_in_market']['futures']
|
||||||
|
# TODO-lev: binance, gateio, and okx don't have leverage_in_market
|
||||||
if leverage_in_market_futures:
|
if leverage_in_market_futures:
|
||||||
futures_pair = EXCHANGES[futures_name].get(
|
futures_pair = EXCHANGES[futures_name].get(
|
||||||
'futures_pair',
|
'futures_pair',
|
||||||
|
@ -3003,8 +3003,9 @@ def test_get_valid_pair_combination(default_conf, mocker, markets):
|
|||||||
# 'XLTCUSDT': 'active': True, not a pair
|
# 'XLTCUSDT': 'active': True, not a pair
|
||||||
# 'XRP/BTC': 'active': False
|
# 'XRP/BTC': 'active': False
|
||||||
([], [], False, False, False, False,
|
([], [], False, False, False, False,
|
||||||
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD',
|
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT',
|
||||||
'LTC/USDT', 'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC'],
|
'NEO/BTC', 'TKN/BTC', 'XLTCUSDT', 'XRP/BTC', 'ADA/USDT:USDT',
|
||||||
|
'ETH/USDT:USDT'],
|
||||||
'all markets'),
|
'all markets'),
|
||||||
([], [], False, False, True, False,
|
([], [], False, False, True, False,
|
||||||
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD',
|
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD',
|
||||||
@ -3012,7 +3013,7 @@ def test_get_valid_pair_combination(default_conf, mocker, markets):
|
|||||||
'all markets, only spot pairs'),
|
'all markets, only spot pairs'),
|
||||||
([], [], False, True, False, False,
|
([], [], False, True, False, False,
|
||||||
['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'NEO/BTC',
|
['BLK/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'NEO/BTC',
|
||||||
'TKN/BTC', 'XLTCUSDT', 'XRP/BTC'],
|
'TKN/BTC', 'XLTCUSDT', 'XRP/BTC', 'ADA/USDT:USDT', 'ETH/USDT:USDT'],
|
||||||
'active markets'),
|
'active markets'),
|
||||||
([], [], True, False, False, False,
|
([], [], True, False, False, False,
|
||||||
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD',
|
['BLK/BTC', 'BTT/BTC', 'ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD',
|
||||||
@ -3023,7 +3024,8 @@ def test_get_valid_pair_combination(default_conf, mocker, markets):
|
|||||||
'TKN/BTC', 'XRP/BTC'],
|
'TKN/BTC', 'XRP/BTC'],
|
||||||
'active pairs'),
|
'active pairs'),
|
||||||
(['ETH', 'LTC'], [], False, False, False, False,
|
(['ETH', 'LTC'], [], False, False, False, False,
|
||||||
['ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT'],
|
['ETH/BTC', 'ETH/USDT', 'LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT',
|
||||||
|
'ETH/USDT:USDT'],
|
||||||
'all markets, base=ETH, LTC'),
|
'all markets, base=ETH, LTC'),
|
||||||
(['LTC'], [], False, False, False, False,
|
(['LTC'], [], False, False, False, False,
|
||||||
['LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT'],
|
['LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT'],
|
||||||
@ -3032,13 +3034,13 @@ def test_get_valid_pair_combination(default_conf, mocker, markets):
|
|||||||
['LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT'],
|
['LTC/BTC', 'LTC/ETH', 'LTC/USD', 'LTC/USDT'],
|
||||||
'spot markets, base=LTC'),
|
'spot markets, base=LTC'),
|
||||||
([], ['USDT'], False, False, False, False,
|
([], ['USDT'], False, False, False, False,
|
||||||
['ETH/USDT', 'LTC/USDT', 'XLTCUSDT'],
|
['ETH/USDT', 'LTC/USDT', 'XLTCUSDT', 'ADA/USDT:USDT', 'ETH/USDT:USDT'],
|
||||||
'all markets, quote=USDT'),
|
'all markets, quote=USDT'),
|
||||||
([], ['USDT'], False, False, False, True,
|
([], ['USDT'], False, False, False, True,
|
||||||
['ETH/USDT', 'LTC/USDT'],
|
['ADA/USDT:USDT', 'ETH/USDT:USDT'],
|
||||||
'Futures markets, quote=USDT'),
|
'Futures markets, quote=USDT'),
|
||||||
([], ['USDT', 'USD'], False, False, False, False,
|
([], ['USDT', 'USD'], False, False, False, False,
|
||||||
['ETH/USDT', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT'],
|
['ETH/USDT', 'LTC/USD', 'LTC/USDT', 'XLTCUSDT', 'ADA/USDT:USDT', 'ETH/USDT:USDT'],
|
||||||
'all markets, quote=USDT, USD'),
|
'all markets, quote=USDT, USD'),
|
||||||
([], ['USDT', 'USD'], False, False, True, False,
|
([], ['USDT', 'USD'], False, False, True, False,
|
||||||
['ETH/USDT', 'LTC/USD', 'LTC/USDT'],
|
['ETH/USDT', 'LTC/USD', 'LTC/USDT'],
|
||||||
@ -4247,7 +4249,7 @@ def test_load_leverage_tiers(mocker, default_conf, leverage_tiers):
|
|||||||
mocker,
|
mocker,
|
||||||
default_conf,
|
default_conf,
|
||||||
api_mock,
|
api_mock,
|
||||||
"binance",
|
"ftx",
|
||||||
"load_leverage_tiers",
|
"load_leverage_tiers",
|
||||||
"fetch_leverage_tiers",
|
"fetch_leverage_tiers",
|
||||||
)
|
)
|
||||||
|
@ -309,7 +309,8 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets):
|
|||||||
exchange.trading_mode = TradingMode.FUTURES
|
exchange.trading_mode = TradingMode.FUTURES
|
||||||
exchange.margin_mode = MarginMode.ISOLATED
|
exchange.margin_mode = MarginMode.ISOLATED
|
||||||
exchange.markets = markets
|
exchange.markets = markets
|
||||||
assert exchange.load_leverage_tiers() == {
|
# Initialization of load_leverage_tiers happens as part of exchange init.
|
||||||
|
exchange._leverage_tiers == {
|
||||||
'ADA/USDT:USDT': [
|
'ADA/USDT:USDT': [
|
||||||
{
|
{
|
||||||
'tier': 1,
|
'tier': 1,
|
||||||
|
Loading…
Reference in New Issue
Block a user