Don't refresh tickers if they are not needed

This commit is contained in:
Matthias 2019-11-09 07:05:17 +01:00
parent e632720c02
commit b610e8c7e6
6 changed files with 57 additions and 7 deletions

View File

@ -5,7 +5,7 @@ Provides lists as configured in config.json
""" """
import logging import logging
from abc import ABC, abstractmethod from abc import ABC, abstractmethod, abstractproperty
from typing import Dict, List from typing import Dict, List
from freqtrade.exchange import market_is_active from freqtrade.exchange import market_is_active
@ -28,6 +28,14 @@ class IPairList(ABC):
""" """
return self.__class__.__name__ return self.__class__.__name__
@abstractproperty
def needstickers(self) -> bool:
"""
Boolean property defining if tickers are necessary.
If no Pairlist requries tickers, an empty List is passed
as tickers argument to filter_pairlist
"""
@abstractmethod @abstractmethod
def short_desc(self) -> str: def short_desc(self) -> str:
""" """

View File

@ -14,6 +14,15 @@ class LowPriceFilter(IPairList):
self._low_price_percent = pairlistconfig.get('low_price_percent', 0) self._low_price_percent = pairlistconfig.get('low_price_percent', 0)
@property
def needstickers(self) -> bool:
"""
Boolean property defining if tickers are necessary.
If no Pairlist requries tickers, an empty List is passed
as tickers argument to filter_pairlist
"""
return True
def short_desc(self) -> str: def short_desc(self) -> str:
""" """
Short whitelist method description - used for startup-messages Short whitelist method description - used for startup-messages

View File

@ -9,6 +9,15 @@ logger = logging.getLogger(__name__)
class PrecisionFilter(IPairList): class PrecisionFilter(IPairList):
@property
def needstickers(self) -> bool:
"""
Boolean property defining if tickers are necessary.
If no Pairlist requries tickers, an empty List is passed
as tickers argument to filter_pairlist
"""
return True
def short_desc(self) -> str: def short_desc(self) -> str:
""" """
Short whitelist method description - used for startup-messages Short whitelist method description - used for startup-messages

View File

@ -17,6 +17,15 @@ class StaticPairList(IPairList):
def __init__(self, exchange, config, pairlistconfig: dict) -> None: def __init__(self, exchange, config, pairlistconfig: dict) -> None:
super().__init__(exchange, config, pairlistconfig) super().__init__(exchange, config, pairlistconfig)
@property
def needstickers(self) -> bool:
"""
Boolean property defining if tickers are necessary.
If no Pairlist requries tickers, an empty List is passed
as tickers argument to filter_pairlist
"""
return False
def short_desc(self) -> str: def short_desc(self) -> str:
""" """
Short whitelist method description - used for startup-messages Short whitelist method description - used for startup-messages
@ -32,4 +41,4 @@ class StaticPairList(IPairList):
:param tickers: Tickers (from exchange.get_tickers()). May be cached. :param tickers: Tickers (from exchange.get_tickers()). May be cached.
:return: new whitelist :return: new whitelist
""" """
return self.validate_whitelist(self._config['exchange']['pair_whitelist']) return self._config['exchange']['pair_whitelist']

View File

@ -38,6 +38,15 @@ class VolumePairList(IPairList):
raise OperationalException( raise OperationalException(
f'key {self._sort_key} not in {SORT_VALUES}') f'key {self._sort_key} not in {SORT_VALUES}')
@property
def needstickers(self) -> bool:
"""
Boolean property defining if tickers are necessary.
If no Pairlist requries tickers, an empty List is passed
as tickers argument to filter_pairlist
"""
return True
def _validate_keys(self, key): def _validate_keys(self, key):
return key in SORT_VALUES return key in SORT_VALUES

View File

@ -22,11 +22,12 @@ class PairListManager():
self._whitelist = self._config['exchange'].get('pair_whitelist') self._whitelist = self._config['exchange'].get('pair_whitelist')
self._blacklist = self._config['exchange'].get('pair_blacklist', []) self._blacklist = self._config['exchange'].get('pair_blacklist', [])
self._pairlists: List[IPairList] = [] self._pairlists: List[IPairList] = []
self._tickers_needed = False
for pl in self._config.get('pairlists', [{'method': "StaticPairList"}]): for pl in self._config.get('pairlists', [{'method': "StaticPairList"}]):
pairl = PairListResolver(pl.get('method'), pairl = PairListResolver(pl.get('method'),
exchange, config, exchange, config,
pl.get('config')).pairlist pl.get('config')).pairlist
self._tickers_needed = pairl.needstickers or self._tickers_needed
self._pairlists.append(pairl) self._pairlists.append(pairl)
@property @property
@ -52,17 +53,22 @@ class PairListManager():
pairlist = self._whitelist.copy() pairlist = self._whitelist.copy()
# tickers should be cached to avoid calling the exchange on each call. # tickers should be cached to avoid calling the exchange on each call.
tickers = []
if self._tickers_needed:
tickers = self._exchange.get_tickers() tickers = self._exchange.get_tickers()
for pl in self._pairlists: for pl in self._pairlists:
pl.filter_pairlist(pairlist, tickers) pl.filter_pairlist(pairlist, tickers)
pairlist = self._verify_blacklist(pairlist) # Validation against blacklist happens after the pairlists to ensure blacklist is respected.
pairlist = self.verify_blacklist(pairlist, self.blacklist)
self._whitelist = pairlist self._whitelist = pairlist
def _verify_blacklist(self, pairlist: List[str]) -> List[str]: @staticmethod
def verify_blacklist(pairlist: List[str], blacklist: List[str]) -> List[str]:
for pair in deepcopy(pairlist): for pair in deepcopy(pairlist):
if pair in self.blacklist: if pair in blacklist:
logger.warning(f"Pair {pair} in your blacklist. Removing it from whitelist...") logger.warning(f"Pair {pair} in your blacklist. Removing it from whitelist...")
pairlist.remove(pair) pairlist.remove(pair)
return pairlist return pairlist