attached pairlist manager onto dataprovider init for unified access to dynamic whitelist

This commit is contained in:
Paul D. Mendes 2020-05-11 19:32:28 +04:00
parent bc9efc31ad
commit 9fbe135790
3 changed files with 40 additions and 26 deletions

View File

@ -10,6 +10,7 @@ from typing import Any, Dict, List, Optional, Tuple
from pandas import DataFrame from pandas import DataFrame
from freqtrade.data.history import load_pair_history from freqtrade.data.history import load_pair_history
from freqtrade.exceptions import OperationalException
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.state import RunMode from freqtrade.state import RunMode
@ -18,9 +19,10 @@ logger = logging.getLogger(__name__)
class DataProvider: class DataProvider:
def __init__(self, config: dict, exchange: Exchange) -> None: def __init__(self, config: dict, exchange: Exchange, pairlists=None) -> None:
self._config = config self._config = config
self._exchange = exchange self._exchange = exchange
self._pairlists = pairlists
def refresh(self, def refresh(self,
pairlist: List[Tuple[str, str]], pairlist: List[Tuple[str, str]],
@ -125,8 +127,8 @@ class DataProvider:
As available pairs does not show whitelist until after informative pairs have been cached. As available pairs does not show whitelist until after informative pairs have been cached.
:return: list of pairs in whitelist :return: list of pairs in whitelist
""" """
from freqtrade.pairlist.pairlistmanager import PairListManager
pairlists = PairListManager(self._exchange, self._config) if self._pairlists:
pairlists.refresh_pairlist() return self._pairlists.whitelist
return pairlists.whitelist else:
raise OperationalException("Dataprovider was not initialized with a pairlist provider.")

View File

@ -71,15 +71,15 @@ class FreqtradeBot:
self.wallets = Wallets(self.config, self.exchange) self.wallets = Wallets(self.config, self.exchange)
self.dataprovider = DataProvider(self.config, self.exchange) self.pairlists = PairListManager(self.exchange, self.config)
self.dataprovider = DataProvider(self.config, self.exchange, self.pairlists)
# Attach Dataprovider to Strategy baseclass # Attach Dataprovider to Strategy baseclass
IStrategy.dp = self.dataprovider IStrategy.dp = self.dataprovider
# Attach Wallets to Strategy baseclass # Attach Wallets to Strategy baseclass
IStrategy.wallets = self.wallets IStrategy.wallets = self.wallets
self.pairlists = PairListManager(self.exchange, self.config)
# Initializing Edge only if enabled # Initializing Edge only if enabled
self.edge = Edge(self.config, self.exchange, self.strategy) if \ self.edge = Edge(self.config, self.exchange, self.strategy) if \
self.config.get('edge', {}).get('enabled', False) else None self.config.get('edge', {}).get('enabled', False) else None

View File

@ -1,10 +1,12 @@
from unittest.mock import MagicMock, PropertyMock from unittest.mock import MagicMock, patch
from pandas import DataFrame from pandas import DataFrame
import pytest
from freqtrade.data.dataprovider import DataProvider from freqtrade.data.dataprovider import DataProvider
from freqtrade.exceptions import OperationalException
from freqtrade.state import RunMode from freqtrade.state import RunMode
from tests.conftest import get_patched_exchange, get_patched_freqtradebot from tests.conftest import get_patched_exchange
def test_ohlcv(mocker, default_conf, ohlcv_history): def test_ohlcv(mocker, default_conf, ohlcv_history):
@ -151,21 +153,31 @@ def test_market(mocker, default_conf, markets):
assert res is None assert res is None
def test_current_whitelist(mocker, shitcoinmarkets, tickers, default_conf): @patch('freqtrade.pairlist.pairlistmanager.PairListManager')
default_conf.update( @patch('freqtrade.exchange.Exchange')
{"pairlists": [{"method": "VolumePairList", def test_current_whitelist(exchange, PairListManager, default_conf):
"number_assets": 10, # patch default conf to volumepairlist
"sort_key": "quoteVolume"}], }, ) default_conf['pairlists'][0] = {'method': 'VolumePairList', "number_assets": 5}
default_conf['exchange']['pair_blacklist'] = ['BLK/BTC']
mocker.patch.multiple('freqtrade.exchange.Exchange', get_tickers=tickers, pairlist = PairListManager(exchange, default_conf)
exchange_has=MagicMock(return_value=True), ) dp = DataProvider(default_conf, exchange, pairlist)
bot = get_patched_freqtradebot(mocker, default_conf)
# Remock markets with shitcoinmarkets since get_patched_freqtradebot uses the markets fixture
mocker.patch.multiple('freqtrade.exchange.Exchange',
markets=PropertyMock(return_value=shitcoinmarkets), )
# argument: use the whitelist dynamically by exchange-volume
whitelist = ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC', 'HOT/BTC', 'FUEL/BTC']
current_wl = bot.dataprovider.current_whitelist() # Simulate volumepairs from exchange.
assert whitelist == current_wl # pairlist.refresh_pairlist()
# Set the pairs manually... this would be done in refresh pairlist
# default whitelist + volumePL - blacklist
default_whitelist = default_conf['exchange']['pair_whitelist']
default_blacklist = default_conf['exchange']['pair_blacklist']
volume_pairlist = ['ETH/BTC', 'LINK/BTC', 'ZRX/BTC', 'BCH/BTC', 'XRP/BTC']
current_whitelist = list(set(volume_pairlist + default_whitelist))
for pair in default_blacklist:
if pair in current_whitelist:
current_whitelist.remove(pair)
pairlist._whitelist = current_whitelist
assert dp.current_whitelist() == pairlist._whitelist
with pytest.raises(OperationalException):
dp = DataProvider(default_conf, exchange)
dp.current_whitelist()