Fix RPC methods to allow wildcards (and validate wildcards)
This commit is contained in:
parent
704cf14383
commit
9feabe707f
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user