From 24c587518ad60775f5fa3b69ba52c438034b42b6 Mon Sep 17 00:00:00 2001 From: iuvbio Date: Sat, 2 Mar 2019 17:24:28 +0100 Subject: [PATCH] add precision_filter --- config_full.json.example | 3 ++- freqtrade/pairlist/IPairList.py | 3 ++- freqtrade/pairlist/VolumePairList.py | 32 ++++++++++++++++++++++------ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/config_full.json.example b/config_full.json.example index 23a36dd4c..0f46a62e3 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -49,7 +49,8 @@ "method": "VolumePairList", "config": { "number_assets": 20, - "sort_key": "quoteVolume" + "sort_key": "quoteVolume", + "precision_filter": false } }, "exchange": { diff --git a/freqtrade/pairlist/IPairList.py b/freqtrade/pairlist/IPairList.py index 6b5b0db4b..4e9e28b3d 100644 --- a/freqtrade/pairlist/IPairList.py +++ b/freqtrade/pairlist/IPairList.py @@ -18,6 +18,7 @@ class IPairList(ABC): self._config = config self._whitelist = self._config['exchange']['pair_whitelist'] self._blacklist = self._config['exchange'].get('pair_blacklist', []) + self._markets = self._freqtrade.exchange.markets @property def name(self) -> str: @@ -66,7 +67,7 @@ class IPairList(ABC): black_listed """ sanitized_whitelist = whitelist - markets = self._freqtrade.exchange.get_markets() + markets = list(self._markets.values()) # Filter to markets in stake currency markets = [m for m in markets if m['quote'] == self._config['stake_currency']] diff --git a/freqtrade/pairlist/VolumePairList.py b/freqtrade/pairlist/VolumePairList.py index 262e4bf59..7f1985d43 100644 --- a/freqtrade/pairlist/VolumePairList.py +++ b/freqtrade/pairlist/VolumePairList.py @@ -1,5 +1,5 @@ """ -Static List provider +Volume PairList provider Provides lists as configured in config.json @@ -26,6 +26,7 @@ class VolumePairList(IPairList): 'for "pairlist.config.number_assets"') self._number_pairs = self._whitelistconf['number_assets'] self._sort_key = self._whitelistconf.get('sort_key', 'quoteVolume') + self._precision_filter = self._whitelistconf.get('precision_filter', False) if not self._freqtrade.exchange.exchange_has('fetchTickers'): raise OperationalException( @@ -52,9 +53,9 @@ class VolumePairList(IPairList): -> Please overwrite in subclasses """ # Generate dynamic whitelist - pairs = self._gen_pair_whitelist(self._config['stake_currency'], self._sort_key) - # Validate whitelist to only have active market pairs - self._whitelist = self._validate_whitelist(pairs)[:self._number_pairs] + self._whitelist = self._gen_pair_whitelist( + self._config['stake_currency'], self._sort_key)[:self._number_pairs] + logger.info(f"Searching pairs: {self._whitelist}") @cached(TTLCache(maxsize=1, ttl=1800)) def _gen_pair_whitelist(self, base_currency: str, key: str) -> List[str]: @@ -69,7 +70,26 @@ class VolumePairList(IPairList): # check length so that we make sure that '/' is actually in the string tickers = [v for k, v in tickers.items() if len(k.split('/')) == 2 and k.split('/')[1] == base_currency] - sorted_tickers = sorted(tickers, reverse=True, key=lambda t: t[key]) - pairs = [s['symbol'] for s in sorted_tickers] + # Validate whitelist to only have active market pairs + valid_pairs = self._validate_whitelist([s['symbol'] for s in sorted_tickers]) + valid_tickers = [t for t in sorted_tickers if t["symbol"] in valid_pairs] + + if self._freqtrade.strategy.stoploss is not None and self._precision_filter: + + logger.debug(f"Markets: {list(self._markets)}") + stop_prices = [self._freqtrade.get_target_bid(t["symbol"], t) + * (1 + self._freqtrade.strategy.stoploss) for t in valid_tickers] + rates = [sp * 0.99 for sp in stop_prices] + logger.debug("\n".join([f"{sp} : {r}" for sp, r in zip(stop_prices[:10], rates[:10])])) + for i, t in enumerate(valid_tickers): + sp = self._freqtrade.exchange.symbol_price_prec(t["symbol"], stop_prices[i]) + r = self._freqtrade.exchange.symbol_price_prec(t["symbol"], rates[i]) + logger.debug(f"{t['symbol']} - {sp} : {r}") + if sp <= r: + logger.info(f"Removed {t['symbol']} from whitelist, " + f"because stop price {sp} would be <= stop limit {r}") + valid_tickers.remove(t) + + pairs = [s['symbol'] for s in valid_tickers] return pairs