freqtrade_origin/freqtrade/pairlist/pairlistmanager.py

96 lines
2.9 KiB
Python
Raw Normal View History

2019-11-09 05:55:16 +00:00
"""
Static List provider
Provides lists as configured in config.json
"""
2019-11-09 18:45:09 +00:00
from cachetools import TTLCache, cached
2019-11-09 05:55:16 +00:00
import logging
2019-11-09 08:07:46 +00:00
from typing import Dict, List
2019-11-09 05:55:16 +00:00
2019-11-09 13:00:32 +00:00
from freqtrade import OperationalException
2019-11-09 05:55:16 +00:00
from freqtrade.pairlist.IPairList import IPairList
from freqtrade.resolvers import PairListResolver
logger = logging.getLogger(__name__)
class PairListManager():
def __init__(self, exchange, config: dict) -> None:
self._exchange = exchange
self._config = config
self._whitelist = self._config['exchange'].get('pair_whitelist')
self._blacklist = self._config['exchange'].get('pair_blacklist', [])
self._pairlists: List[IPairList] = []
self._tickers_needed = False
2019-11-09 13:49:25 +00:00
for pl in self._config.get('pairlists', None):
if 'method' not in pl:
logger.warning(f"No method in {pl}")
continue
2019-11-09 05:55:16 +00:00
pairl = PairListResolver(pl.get('method'),
exchange=exchange,
pairlistmanager=self,
config=config,
2019-11-19 05:34:54 +00:00
pairlistconfig=pl,
pairlist_pos=len(self._pairlists)
).pairlist
self._tickers_needed = pairl.needstickers or self._tickers_needed
2019-11-09 05:55:16 +00:00
self._pairlists.append(pairl)
2019-11-09 13:49:25 +00:00
2019-11-09 13:00:32 +00:00
if not self._pairlists:
2019-11-09 13:49:25 +00:00
raise OperationalException("No Pairlist defined!")
2019-11-09 05:55:16 +00:00
@property
def whitelist(self) -> List[str]:
"""
Has the current whitelist
"""
return self._whitelist
@property
def blacklist(self) -> List[str]:
"""
Has the current blacklist
-> no need to overwrite in subclasses
"""
return self._blacklist
2019-11-09 08:07:46 +00:00
@property
2019-11-09 13:00:32 +00:00
def name_list(self) -> List[str]:
2019-11-09 08:07:46 +00:00
"""
2019-11-09 13:00:32 +00:00
Get list of loaded pairlists names
2019-11-09 08:07:46 +00:00
"""
2019-11-09 13:00:32 +00:00
return [p.name for p in self._pairlists]
2019-11-09 08:07:46 +00:00
def short_desc(self) -> List[Dict]:
"""
List of short_desc for each pairlist
"""
return [{p.name: p.short_desc()} for p in self._pairlists]
2019-11-09 18:45:09 +00:00
@cached(TTLCache(maxsize=1, ttl=1800))
def _get_cached_tickers(self):
return self._exchange.get_tickers()
2019-11-09 05:55:16 +00:00
def refresh_pairlist(self) -> None:
"""
Run pairlist through all configured pairlists.
2019-11-09 05:55:16 +00:00
"""
pairlist = self._whitelist.copy()
# tickers should be cached to avoid calling the exchange on each call.
2019-11-09 12:40:36 +00:00
tickers: Dict = {}
if self._tickers_needed:
2019-11-09 18:45:09 +00:00
tickers = self._get_cached_tickers()
# Process all pairlists in chain
2019-11-09 05:55:16 +00:00
for pl in self._pairlists:
pairlist = pl.filter_pairlist(pairlist, tickers)
2019-11-09 05:55:16 +00:00
# Validation against blacklist happens after the pairlists to ensure blacklist is respected.
2019-11-09 06:23:34 +00:00
pairlist = IPairList.verify_blacklist(pairlist, self.blacklist)
2019-11-09 05:55:16 +00:00
self._whitelist = pairlist