attached pairlist manager onto dataprovider init for unified access to dynamic whitelist
This commit is contained in:
		| @@ -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: Optional = 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.") | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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,29 @@ 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) as e: | ||||||
|  |         dp = DataProvider(default_conf, exchange) | ||||||
|  |         dp.current_whitelist() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user