Merge branch 'develop' into pr/mkavinkumar1/6545

This commit is contained in:
Matthias 2022-07-24 10:55:12 +02:00
commit f98d3d86e0
9 changed files with 61 additions and 12 deletions

View File

@ -88,7 +88,8 @@ class Exchange:
# TradingMode.SPOT always supported and not required in this list # TradingMode.SPOT always supported and not required in this list
] ]
def __init__(self, config: Dict[str, Any], validate: bool = True) -> None: def __init__(self, config: Dict[str, Any], validate: bool = True,
load_leverage_tiers: bool = False) -> None:
""" """
Initializes this module with the given config, Initializes this module with the given config,
it does basic validation whether the specified exchange and pairs are valid. it does basic validation whether the specified exchange and pairs are valid.
@ -186,7 +187,7 @@ class Exchange:
self.markets_refresh_interval: int = exchange_config.get( self.markets_refresh_interval: int = exchange_config.get(
"markets_refresh_interval", 60) * 60 "markets_refresh_interval", 60) * 60
if self.trading_mode != TradingMode.SPOT: if self.trading_mode != TradingMode.SPOT and load_leverage_tiers:
self.fill_leverage_tiers() self.fill_leverage_tiers()
self.additional_exchange_init() self.additional_exchange_init()

View File

@ -66,7 +66,8 @@ class FreqtradeBot(LoggingMixin):
# Check config consistency here since strategies can set certain options # Check config consistency here since strategies can set certain options
validate_config_consistency(config) validate_config_consistency(config)
self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) self.exchange = ExchangeResolver.load_exchange(
self.config['exchange']['name'], self.config, load_leverage_tiers=True)
init_db(self.config['db_url']) init_db(self.config['db_url'])

View File

@ -84,7 +84,8 @@ class Backtesting:
self.processed_dfs: Dict[str, Dict] = {} self.processed_dfs: Dict[str, Dict] = {}
self._exchange_name = self.config['exchange']['name'] self._exchange_name = self.config['exchange']['name']
self.exchange = ExchangeResolver.load_exchange(self._exchange_name, self.config) self.exchange = ExchangeResolver.load_exchange(
self._exchange_name, self.config, load_leverage_tiers=True)
self.dataprovider = DataProvider(self.config, self.exchange) self.dataprovider = DataProvider(self.config, self.exchange)
if self.config.get('strategy_list'): if self.config.get('strategy_list'):

View File

@ -18,7 +18,8 @@ class ExchangeResolver(IResolver):
object_type = Exchange object_type = Exchange
@staticmethod @staticmethod
def load_exchange(exchange_name: str, config: dict, validate: bool = True) -> Exchange: def load_exchange(exchange_name: str, config: dict, validate: bool = True,
load_leverage_tiers: bool = False) -> Exchange:
""" """
Load the custom class from config parameter Load the custom class from config parameter
:param exchange_name: name of the Exchange to load :param exchange_name: name of the Exchange to load
@ -29,9 +30,13 @@ class ExchangeResolver(IResolver):
exchange_name = exchange_name.title() exchange_name = exchange_name.title()
exchange = None exchange = None
try: try:
exchange = ExchangeResolver._load_exchange(exchange_name, exchange = ExchangeResolver._load_exchange(
kwargs={'config': config, exchange_name,
'validate': validate}) kwargs={
'config': config,
'validate': validate,
'load_leverage_tiers': load_leverage_tiers}
)
except ImportError: except ImportError:
logger.info( logger.info(
f"No {exchange_name} specific subclass found. Using the generic class instead.") f"No {exchange_name} specific subclass found. Using the generic class instead.")

View File

@ -37,7 +37,7 @@ def get_exchange(config=Depends(get_config)):
if not ApiServer._exchange: if not ApiServer._exchange:
from freqtrade.resolvers import ExchangeResolver from freqtrade.resolvers import ExchangeResolver
ApiServer._exchange = ExchangeResolver.load_exchange( ApiServer._exchange = ExchangeResolver.load_exchange(
config['exchange']['name'], config) config['exchange']['name'], config, load_leverage_tiers=False)
return ApiServer._exchange return ApiServer._exchange

View File

@ -148,7 +148,7 @@ def get_patched_exchange(mocker, config, api_mock=None, id='binance',
patch_exchange(mocker, api_mock, id, mock_markets, mock_supported_modes) patch_exchange(mocker, api_mock, id, mock_markets, mock_supported_modes)
config['exchange']['name'] = id config['exchange']['name'] = id
try: try:
exchange = ExchangeResolver.load_exchange(id, config) exchange = ExchangeResolver.load_exchange(id, config, load_leverage_tiers=True)
except ImportError: except ImportError:
exchange = Exchange(config) exchange = Exchange(config)
return exchange return exchange
@ -2609,7 +2609,7 @@ def open_trade_usdt():
pair='ADA/USDT', pair='ADA/USDT',
open_rate=2.0, open_rate=2.0,
exchange='binance', exchange='binance',
open_order_id='123456789', open_order_id='123456789_exit',
amount=30.0, amount=30.0,
fee_open=0.0, fee_open=0.0,
fee_close=0.0, fee_close=0.0,
@ -2634,6 +2634,23 @@ def open_trade_usdt():
cost=trade.open_rate * trade.amount, cost=trade.open_rate * trade.amount,
order_date=trade.open_date, order_date=trade.open_date,
order_filled_date=trade.open_date, order_filled_date=trade.open_date,
),
Order(
ft_order_side='exit',
ft_pair=trade.pair,
ft_is_open=True,
order_id='123456789_exit',
status="open",
symbol=trade.pair,
order_type="limit",
side="sell",
price=trade.open_rate,
average=trade.open_rate,
filled=trade.amount,
remaining=0,
cost=trade.open_rate * trade.amount,
order_date=trade.open_date,
order_filled_date=trade.open_date,
) )
] ]
return trade return trade

View File

@ -137,7 +137,8 @@ def exchange_futures(request, exchange_conf, class_mocker):
'freqtrade.exchange.binance.Binance.fill_leverage_tiers') 'freqtrade.exchange.binance.Binance.fill_leverage_tiers')
class_mocker.patch('freqtrade.exchange.exchange.Exchange.fetch_trading_fees') class_mocker.patch('freqtrade.exchange.exchange.Exchange.fetch_trading_fees')
class_mocker.patch('freqtrade.exchange.okx.Okx.additional_exchange_init') class_mocker.patch('freqtrade.exchange.okx.Okx.additional_exchange_init')
exchange = ExchangeResolver.load_exchange(request.param, exchange_conf, validate=True) exchange = ExchangeResolver.load_exchange(
request.param, exchange_conf, validate=True, load_leverage_tiers=True)
yield exchange, request.param yield exchange, request.param

View File

@ -832,6 +832,8 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
assert cancel_order_mock.call_count == 2 assert cancel_order_mock.call_count == 2
assert trade.amount == amount assert trade.amount == amount
trade = Trade.query.filter(Trade.id == '3').first()
# make an limit-sell open trade # make an limit-sell open trade
mocker.patch( mocker.patch(
'freqtrade.exchange.Exchange.fetch_order', 'freqtrade.exchange.Exchange.fetch_order',

View File

@ -2763,6 +2763,8 @@ def test_check_handle_cancelled_exit(
cancel_order_mock = MagicMock() cancel_order_mock = MagicMock()
limit_sell_order_old.update({"status": "canceled", 'filled': 0.0}) limit_sell_order_old.update({"status": "canceled", 'filled': 0.0})
limit_sell_order_old['side'] = 'buy' if is_short else 'sell' limit_sell_order_old['side'] = 'buy' if is_short else 'sell'
limit_sell_order_old['id'] = open_trade_usdt.open_order_id
patch_exchange(mocker) patch_exchange(mocker)
mocker.patch.multiple( mocker.patch.multiple(
'freqtrade.exchange.Exchange', 'freqtrade.exchange.Exchange',
@ -3102,6 +3104,25 @@ def test_handle_cancel_exit_limit(mocker, default_conf_usdt, fee) -> None:
close_date=arrow.utcnow().datetime, close_date=arrow.utcnow().datetime,
exit_reason="sell_reason_whatever", exit_reason="sell_reason_whatever",
) )
trade.orders = [
Order(
ft_order_side='buy',
ft_pair=trade.pair,
ft_is_open=True,
order_id='123456',
status="closed",
symbol=trade.pair,
order_type="market",
side="buy",
price=trade.open_rate,
average=trade.open_rate,
filled=trade.amount,
remaining=0,
cost=trade.open_rate * trade.amount,
order_date=trade.open_date,
order_filled_date=trade.open_date,
),
]
order = {'id': "123456", order = {'id': "123456",
'remaining': 1, 'remaining': 1,
'amount': 1, 'amount': 1,