Added ability to keep invalid pairs while expanding expand_pairlist
This commit is contained in:
@@ -124,19 +124,21 @@ class IPairList(LoggingMixin, ABC):
|
||||
"""
|
||||
return self._pairlistmanager.verify_blacklist(pairlist, logmethod)
|
||||
|
||||
def verify_whitelist(self, pairlist: List[str], logmethod) -> List[str]:
|
||||
def verify_whitelist(self, pairlist: List[str], logmethod,
|
||||
keep_invalid: bool = False) -> List[str]:
|
||||
"""
|
||||
Proxy method to verify_whitelist for easy access for child classes.
|
||||
:param pairlist: Pairlist to validate
|
||||
:param logmethod: Function that'll be called, `logger.info` or `logger.warning`.
|
||||
:param logmethod: Function that'll be called, `logger.info` or `logger.warning`
|
||||
:param keep_invalid: If sets to True, drops invalid pairs silently while expanding regexes.
|
||||
:return: pairlist - whitelisted pairs
|
||||
"""
|
||||
return self._pairlistmanager.verify_whitelist(pairlist, logmethod)
|
||||
return self._pairlistmanager.verify_whitelist(pairlist, logmethod, keep_invalid)
|
||||
|
||||
def _whitelist_for_active_markets(self, pairlist: List[str]) -> List[str]:
|
||||
"""
|
||||
Check available markets and remove pair from whitelist if necessary
|
||||
:param whitelist: the sorted list of pairs the user might want to trade
|
||||
:param pairlist: the sorted list of pairs the user might want to trade
|
||||
:return: the list of pairs the user wants to trade without those unavailable or
|
||||
black_listed
|
||||
"""
|
||||
|
@@ -50,7 +50,9 @@ class StaticPairList(IPairList):
|
||||
:return: List of pairs
|
||||
"""
|
||||
if self._allow_inactive:
|
||||
return self.verify_whitelist(self._config['exchange']['pair_whitelist'], logger.info)
|
||||
return self.verify_whitelist(
|
||||
self._config['exchange']['pair_whitelist'], logger.info, keep_invalid=True
|
||||
)
|
||||
else:
|
||||
return self._whitelist_for_active_markets(
|
||||
self.verify_whitelist(self._config['exchange']['pair_whitelist'], logger.info))
|
||||
|
@@ -2,22 +2,41 @@ import re
|
||||
from typing import List
|
||||
|
||||
|
||||
def expand_pairlist(wildcardpl: List[str], available_pairs: List[str]) -> List[str]:
|
||||
def expand_pairlist(wildcardpl: List[str], available_pairs: List[str],
|
||||
keep_invalid: bool = False) -> List[str]:
|
||||
"""
|
||||
Expand pairlist potentially containing wildcards based on available markets.
|
||||
This will implicitly filter all pairs in the wildcard-list which are not in available_pairs.
|
||||
:param wildcardpl: List of Pairlists, which may contain regex
|
||||
:param available_pairs: List of all available pairs (`exchange.get_markets().keys()`)
|
||||
:param keep_invalid: If sets to True, drops invalid pairs silently while expanding regexes
|
||||
:return expanded pairlist, with Regexes from wildcardpl applied to match all available pairs.
|
||||
:raises: ValueError if a wildcard is invalid (like '*/BTC' - which should be `.*/BTC`)
|
||||
"""
|
||||
result = []
|
||||
for pair_wc in wildcardpl:
|
||||
try:
|
||||
comp = re.compile(pair_wc)
|
||||
result += [
|
||||
pair for pair in available_pairs if re.match(comp, pair)
|
||||
]
|
||||
except re.error as err:
|
||||
raise ValueError(f"Wildcard error in {pair_wc}, {err}")
|
||||
if keep_invalid:
|
||||
for pair_wc in wildcardpl:
|
||||
try:
|
||||
comp = re.compile(pair_wc)
|
||||
result_partial = [
|
||||
pair for pair in available_pairs if re.match(comp, pair)
|
||||
]
|
||||
# Add all matching pairs.
|
||||
# If there are no matching pairs (Pair not on exchange) keep it.
|
||||
result += result_partial or [pair_wc]
|
||||
except re.error as err:
|
||||
raise ValueError(f"Wildcard error in {pair_wc}, {err}")
|
||||
|
||||
for element in result:
|
||||
if not re.fullmatch(r'^[A-Za-z0-9/-]+$', element):
|
||||
result.remove(element)
|
||||
else:
|
||||
for pair_wc in wildcardpl:
|
||||
try:
|
||||
comp = re.compile(pair_wc)
|
||||
result += [
|
||||
pair for pair in available_pairs if re.match(comp, pair)
|
||||
]
|
||||
except re.error as err:
|
||||
raise ValueError(f"Wildcard error in {pair_wc}, {err}")
|
||||
return result
|
||||
|
@@ -59,9 +59,15 @@ class PairListManager():
|
||||
"""The expanded blacklist (including wildcard expansion)"""
|
||||
return expand_pairlist(self._blacklist, self._exchange.get_markets().keys())
|
||||
|
||||
@property
|
||||
def expanded_whitelist_keep_invalid(self) -> List[str]:
|
||||
"""The expanded whitelist (including wildcard expansion), maintaining invalid pairs"""
|
||||
return expand_pairlist(self._whitelist, self._exchange.get_markets().keys(),
|
||||
keep_invalid=True)
|
||||
|
||||
@property
|
||||
def expanded_whitelist(self) -> List[str]:
|
||||
"""The expanded whitelist (including wildcard expansion)"""
|
||||
"""The expanded whitelist (including wildcard expansion), filtering invalid pairs"""
|
||||
return expand_pairlist(self._whitelist, self._exchange.get_markets().keys())
|
||||
|
||||
@property
|
||||
@@ -134,19 +140,30 @@ class PairListManager():
|
||||
pairlist.remove(pair)
|
||||
return pairlist
|
||||
|
||||
def verify_whitelist(self, pairlist: List[str], logmethod) -> List[str]:
|
||||
def verify_whitelist(self, pairlist: List[str], logmethod,
|
||||
keep_invalid: bool = False) -> List[str]:
|
||||
"""
|
||||
Verify and remove items from pairlist - returning a filtered pairlist.
|
||||
Logs a warning or info depending on `aswarning`.
|
||||
Pairlist Handlers explicitly using this method shall use
|
||||
`logmethod=logger.info` to avoid spamming with warning messages
|
||||
:return: pairlist - blacklisted pairs
|
||||
:param pairlist: Pairlist to validate
|
||||
:param logmethod: Function that'll be called, `logger.info` or `logger.warning`
|
||||
:param keep_invalid: If sets to True, drops invalid pairs silently while expanding regexes.
|
||||
:return: pairlist - whitelisted pairs
|
||||
"""
|
||||
try:
|
||||
whitelist = self.expanded_whitelist
|
||||
except ValueError as err:
|
||||
logger.error(f"Pair blacklist contains an invalid Wildcard: {err}")
|
||||
return []
|
||||
if keep_invalid:
|
||||
try:
|
||||
whitelist = self.expanded_whitelist_keep_invalid
|
||||
except ValueError as err:
|
||||
logger.error(f"Pair blacklist contains an invalid Wildcard: {err}")
|
||||
return []
|
||||
else:
|
||||
try:
|
||||
whitelist = self.expanded_whitelist
|
||||
except ValueError as err:
|
||||
logger.error(f"Pair blacklist contains an invalid Wildcard: {err}")
|
||||
return []
|
||||
return whitelist
|
||||
|
||||
def create_pair_list(self, pairs: List[str], timeframe: str = None) -> ListPairsWithTimeframes:
|
||||
|
Reference in New Issue
Block a user