Fix RPC methods to allow wildcards (and validate wildcards)

This commit is contained in:
Matthias 2020-12-30 09:57:31 +01:00
parent 704cf14383
commit 9feabe707f
4 changed files with 39 additions and 17 deletions

View File

@ -20,6 +20,7 @@ from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs
from freqtrade.loggers import bufferHandler from freqtrade.loggers import bufferHandler
from freqtrade.misc import shorten_date from freqtrade.misc import shorten_date
from freqtrade.persistence import PairLocks, Trade from freqtrade.persistence import PairLocks, Trade
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
from freqtrade.state import State from freqtrade.state import State
from freqtrade.strategy.interface import SellType from freqtrade.strategy.interface import SellType
@ -673,23 +674,23 @@ class RPC:
""" Returns the currently active blacklist""" """ Returns the currently active blacklist"""
errors = {} errors = {}
if add: if add:
stake_currency = self._freqtrade.config.get('stake_currency')
for pair in add: for pair in add:
if self._freqtrade.exchange.get_pair_quote_currency(pair) == stake_currency: if pair not in self._freqtrade.pairlists.blacklist:
if pair not in self._freqtrade.pairlists.blacklist: try:
expand_pairlist([pair], self._freqtrade.exchange.get_markets().keys())
self._freqtrade.pairlists.blacklist.append(pair) self._freqtrade.pairlists.blacklist.append(pair)
else:
errors[pair] = {
'error_msg': f'Pair {pair} already in pairlist.'}
except ValueError:
errors[pair] = {
'error_msg': f'Pair {pair} is not a valid wildcard.'}
else: else:
errors[pair] = { errors[pair] = {
'error_msg': f"Pair {pair} does not match stake currency." 'error_msg': f'Pair {pair} already in pairlist.'}
}
res = {'method': self._freqtrade.pairlists.name_list, res = {'method': self._freqtrade.pairlists.name_list,
'length': len(self._freqtrade.pairlists.blacklist), 'length': len(self._freqtrade.pairlists.blacklist),
'blacklist': self._freqtrade.pairlists.blacklist, 'blacklist': self._freqtrade.pairlists.blacklist,
'blacklist_expanded': self._freqtrade.pairlists.expanded_blacklist,
'errors': errors, 'errors': errors,
} }
return res return res

View File

@ -957,14 +957,24 @@ def test_rpc_blacklist(mocker, default_conf) -> None:
assert isinstance(ret['errors'], dict) assert isinstance(ret['errors'], dict)
assert ret['errors']['ETH/BTC']['error_msg'] == 'Pair ETH/BTC already in pairlist.' assert ret['errors']['ETH/BTC']['error_msg'] == 'Pair ETH/BTC already in pairlist.'
ret = rpc._rpc_blacklist(["ETH/ETH"]) ret = rpc._rpc_blacklist(["*/BTC"])
assert 'StaticPairList' in ret['method'] assert 'StaticPairList' in ret['method']
assert len(ret['blacklist']) == 3 assert len(ret['blacklist']) == 3
assert ret['blacklist'] == default_conf['exchange']['pair_blacklist'] assert ret['blacklist'] == default_conf['exchange']['pair_blacklist']
assert ret['blacklist'] == ['DOGE/BTC', 'HOT/BTC', 'ETH/BTC'] assert ret['blacklist'] == ['DOGE/BTC', 'HOT/BTC', 'ETH/BTC']
assert ret['blacklist_expanded'] == ['ETH/BTC']
assert 'errors' in ret
assert isinstance(ret['errors'], dict)
assert ret['errors'] == {'*/BTC': {'error_msg': 'Pair */BTC is not a valid wildcard.'}}
ret = rpc._rpc_blacklist(["XRP/.*"])
assert 'StaticPairList' in ret['method']
assert len(ret['blacklist']) == 4
assert ret['blacklist'] == default_conf['exchange']['pair_blacklist']
assert ret['blacklist'] == ['DOGE/BTC', 'HOT/BTC', 'ETH/BTC', 'XRP/.*']
assert ret['blacklist_expanded'] == ['ETH/BTC', 'XRP/BTC']
assert 'errors' in ret assert 'errors' in ret
assert isinstance(ret['errors'], dict) assert isinstance(ret['errors'], dict)
assert ret['errors']['ETH/ETH']['error_msg'] == 'Pair ETH/ETH does not match stake currency.'
def test_rpc_edge_disabled(mocker, default_conf) -> None: def test_rpc_edge_disabled(mocker, default_conf) -> None:

View File

@ -730,7 +730,9 @@ def test_api_blacklist(botclient, mocker):
rc = client_get(client, f"{BASE_URI}/blacklist") rc = client_get(client, f"{BASE_URI}/blacklist")
assert_response(rc) assert_response(rc)
# DOGE and HOT are not in the markets mock!
assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC"], assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC"],
"blacklist_expanded": [],
"length": 2, "length": 2,
"method": ["StaticPairList"], "method": ["StaticPairList"],
"errors": {}, "errors": {},
@ -741,11 +743,22 @@ def test_api_blacklist(botclient, mocker):
data='{"blacklist": ["ETH/BTC"]}') data='{"blacklist": ["ETH/BTC"]}')
assert_response(rc) assert_response(rc)
assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC", "ETH/BTC"], assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC", "ETH/BTC"],
"blacklist_expanded": ["ETH/BTC"],
"length": 3, "length": 3,
"method": ["StaticPairList"], "method": ["StaticPairList"],
"errors": {}, "errors": {},
} }
rc = client_post(client, f"{BASE_URI}/blacklist",
data='{"blacklist": ["XRP/.*"]}')
assert_response(rc)
assert rc.json == {"blacklist": ["DOGE/BTC", "HOT/BTC", "ETH/BTC", "XRP/.*"],
"blacklist_expanded": ["ETH/BTC", "XRP/BTC"],
"length": 4,
"method": ["StaticPairList"],
"errors": {},
}
def test_api_whitelist(botclient): def test_api_whitelist(botclient):
ftbot, client = botclient ftbot, client = botclient

View File

@ -1011,15 +1011,13 @@ def test_blacklist_static(default_conf, update, mocker) -> None:
msg_mock.reset_mock() msg_mock.reset_mock()
context = MagicMock() context = MagicMock()
context.args = ["ETH/ETH"] context.args = ["XRP/.*"]
telegram._blacklist(update=update, context=context) telegram._blacklist(update=update, context=context)
assert msg_mock.call_count == 2 assert msg_mock.call_count == 1
assert ("Error adding `ETH/ETH` to blacklist: `Pair ETH/ETH does not match stake currency.`"
in msg_mock.call_args_list[0][0][0])
assert ("Blacklist contains 3 pairs\n`DOGE/BTC, HOT/BTC, ETH/BTC`" assert ("Blacklist contains 4 pairs\n`DOGE/BTC, HOT/BTC, ETH/BTC, XRP/.*`"
in msg_mock.call_args_list[1][0][0]) in msg_mock.call_args_list[0][0][0])
assert freqtradebot.pairlists.blacklist == ["DOGE/BTC", "HOT/BTC", "ETH/BTC"] assert freqtradebot.pairlists.blacklist == ["DOGE/BTC", "HOT/BTC", "ETH/BTC", "XRP/.*"]
def test_telegram_logs(default_conf, update, mocker) -> None: def test_telegram_logs(default_conf, update, mocker) -> None: