Merge branch 'develop' into pr/mkavinkumar1/6545
This commit is contained in:
commit
f98d3d86e0
@ -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()
|
||||||
|
|
||||||
|
@ -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'])
|
||||||
|
|
||||||
|
@ -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'):
|
||||||
|
@ -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.")
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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',
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user