Warn when using restricted pairs
As noted in https://github.com/ccxt/ccxt/issues/5624, there is currently no way to detect if a user is impacted by this or not prior to creating a order.
This commit is contained in:
parent
4c005e7086
commit
bbd58e772e
@ -260,7 +260,7 @@ class Exchange(object):
|
|||||||
|
|
||||||
if not self.markets:
|
if not self.markets:
|
||||||
logger.warning('Unable to validate pairs (assuming they are correct).')
|
logger.warning('Unable to validate pairs (assuming they are correct).')
|
||||||
# return
|
return
|
||||||
|
|
||||||
for pair in pairs:
|
for pair in pairs:
|
||||||
# Note: ccxt has BaseCurrency/QuoteCurrency format for pairs
|
# Note: ccxt has BaseCurrency/QuoteCurrency format for pairs
|
||||||
@ -269,6 +269,12 @@ class Exchange(object):
|
|||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f'Pair {pair} is not available on {self.name}. '
|
f'Pair {pair} is not available on {self.name}. '
|
||||||
f'Please remove {pair} from your whitelist.')
|
f'Please remove {pair} from your whitelist.')
|
||||||
|
elif self.markets[pair].get('info', {}).get('IsRestricted', False):
|
||||||
|
# Warn users about restricted pairs in whitelist.
|
||||||
|
# We cannot determine reliably if Users are affected.
|
||||||
|
logger.warning(f"Pair {pair} is restricted for some users on this exchange."
|
||||||
|
f"Please check if you are impacted by this restriction "
|
||||||
|
f"on the exchange and eventually remove {pair} from your whitelist.")
|
||||||
|
|
||||||
def get_valid_pair_combination(self, curr_1, curr_2) -> str:
|
def get_valid_pair_combination(self, curr_1, curr_2) -> str:
|
||||||
"""
|
"""
|
||||||
|
@ -304,7 +304,7 @@ def markets():
|
|||||||
'max': 500000,
|
'max': 500000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': {},
|
||||||
},
|
},
|
||||||
'TKN/BTC': {
|
'TKN/BTC': {
|
||||||
'id': 'tknbtc',
|
'id': 'tknbtc',
|
||||||
@ -329,7 +329,7 @@ def markets():
|
|||||||
'max': 500000,
|
'max': 500000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': {},
|
||||||
},
|
},
|
||||||
'BLK/BTC': {
|
'BLK/BTC': {
|
||||||
'id': 'blkbtc',
|
'id': 'blkbtc',
|
||||||
@ -354,7 +354,7 @@ def markets():
|
|||||||
'max': 500000,
|
'max': 500000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': {},
|
||||||
},
|
},
|
||||||
'LTC/BTC': {
|
'LTC/BTC': {
|
||||||
'id': 'ltcbtc',
|
'id': 'ltcbtc',
|
||||||
@ -379,7 +379,7 @@ def markets():
|
|||||||
'max': 500000,
|
'max': 500000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': {},
|
||||||
},
|
},
|
||||||
'XRP/BTC': {
|
'XRP/BTC': {
|
||||||
'id': 'xrpbtc',
|
'id': 'xrpbtc',
|
||||||
@ -404,7 +404,7 @@ def markets():
|
|||||||
'max': 500000,
|
'max': 500000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': {},
|
||||||
},
|
},
|
||||||
'NEO/BTC': {
|
'NEO/BTC': {
|
||||||
'id': 'neobtc',
|
'id': 'neobtc',
|
||||||
@ -429,7 +429,7 @@ def markets():
|
|||||||
'max': 500000,
|
'max': 500000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'info': '',
|
'info': {},
|
||||||
},
|
},
|
||||||
'BTT/BTC': {
|
'BTT/BTC': {
|
||||||
'id': 'BTTBTC',
|
'id': 'BTTBTC',
|
||||||
@ -457,7 +457,7 @@ def markets():
|
|||||||
'max': None
|
'max': None
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'info': "",
|
'info': {},
|
||||||
},
|
},
|
||||||
'ETH/USDT': {
|
'ETH/USDT': {
|
||||||
'id': 'USDT-ETH',
|
'id': 'USDT-ETH',
|
||||||
@ -479,7 +479,7 @@ def markets():
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
'active': True,
|
'active': True,
|
||||||
'info': ""
|
'info': {},
|
||||||
},
|
},
|
||||||
'LTC/USDT': {
|
'LTC/USDT': {
|
||||||
'id': 'USDT-LTC',
|
'id': 'USDT-LTC',
|
||||||
@ -501,7 +501,7 @@ def markets():
|
|||||||
'max': None
|
'max': None
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'info': ""
|
'info': {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ def test__reload_markets_exception(default_conf, mocker, caplog):
|
|||||||
def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly
|
def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
type(api_mock).markets = PropertyMock(return_value={
|
type(api_mock).markets = PropertyMock(return_value={
|
||||||
'ETH/BTC': '', 'LTC/BTC': '', 'XRP/BTC': '', 'NEO/BTC': ''
|
'ETH/BTC': {}, 'LTC/BTC': {}, 'XRP/BTC': {}, 'NEO/BTC': {}
|
||||||
})
|
})
|
||||||
id_mock = PropertyMock(return_value='test_exchange')
|
id_mock = PropertyMock(return_value='test_exchange')
|
||||||
type(api_mock).id = id_mock
|
type(api_mock).id = id_mock
|
||||||
@ -332,7 +332,7 @@ def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs d
|
|||||||
def test_validate_pairs_not_available(default_conf, mocker):
|
def test_validate_pairs_not_available(default_conf, mocker):
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
type(api_mock).markets = PropertyMock(return_value={
|
type(api_mock).markets = PropertyMock(return_value={
|
||||||
'XRP/BTC': 'inactive'
|
'XRP/BTC': {'inactive'}
|
||||||
})
|
})
|
||||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||||
@ -361,6 +361,23 @@ def test_validate_pairs_exception(default_conf, mocker, caplog):
|
|||||||
caplog.record_tuples)
|
caplog.record_tuples)
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_pairs_restricted(default_conf, mocker, caplog):
|
||||||
|
api_mock = MagicMock()
|
||||||
|
type(api_mock).markets = PropertyMock(return_value={
|
||||||
|
'ETH/BTC': {}, 'LTC/BTC': {}, 'NEO/BTC': {},
|
||||||
|
'XRP/BTC': {'info': {'IsRestricted': True}}
|
||||||
|
})
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock())
|
||||||
|
|
||||||
|
Exchange(default_conf)
|
||||||
|
assert log_has(f"Pair XRP/BTC is restricted for some users on this exchange."
|
||||||
|
f"Please check if you are impacted by this restriction "
|
||||||
|
f"on the exchange and eventually remove XRP/BTC from your whitelist.",
|
||||||
|
caplog.record_tuples)
|
||||||
|
|
||||||
|
|
||||||
def test_validate_timeframes(default_conf, mocker):
|
def test_validate_timeframes(default_conf, mocker):
|
||||||
default_conf["ticker_interval"] = "5m"
|
default_conf["ticker_interval"] = "5m"
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
|
Loading…
Reference in New Issue
Block a user