Simplify rangeStability Filter

This commit is contained in:
Matthias
2024-02-24 13:50:54 +01:00
parent 88a2995b4c
commit 7af46628f8
@@ -2,9 +2,8 @@
Rate of change pairlist filter Rate of change pairlist filter
""" """
import logging import logging
from copy import deepcopy
from datetime import timedelta from datetime import timedelta
from typing import Any, Dict, List, Optional from typing import Any, Dict, List
from cachetools import TTLCache from cachetools import TTLCache
from pandas import DataFrame from pandas import DataFrame
@@ -103,45 +102,55 @@ class RangeStabilityFilter(IPairList):
since_ms = dt_ts(dt_floor_day(dt_now()) - timedelta(days=self._days + 1)) since_ms = dt_ts(dt_floor_day(dt_now()) - timedelta(days=self._days + 1))
candles = self._exchange.refresh_ohlcv_with_cache(needed_pairs, since_ms=since_ms) candles = self._exchange.refresh_ohlcv_with_cache(needed_pairs, since_ms=since_ms)
if self._enabled: resulting_pairlist: List[str] = []
for p in deepcopy(pairlist):
daily_candles = candles[(p, '1d', self._def_candletype)] if (
p, '1d', self._def_candletype) in candles else None
if not self._validate_pair_loc(p, daily_candles):
pairlist.remove(p)
return pairlist
def _validate_pair_loc(self, pair: str, daily_candles: Optional[DataFrame]) -> bool: for p in pairlist:
""" daily_candles = candles.get((p, '1d', self._def_candletype), None)
Validate trading range
:param pair: Pair that's currently validated pct_change = self._calculate_rate_of_change(p, daily_candles)
:param daily_candles: Downloaded daily candles
:return: True if the pair can stay, false if it should be removed if pct_change is not None and self._validate_pair_loc(p, pct_change):
""" resulting_pairlist.append(p)
else:
self.log_once(f"Removed {p} from whitelist, no candles found.", logger.info)
return resulting_pairlist
def _calculate_rate_of_change(self, pair: str, daily_candles: DataFrame) -> float:
# Check symbol in cache # Check symbol in cache
if (cached_res := self._pair_cache.get(pair, None)) is not None: if (pct_change := self._pair_cache.get(pair, None)) is not None:
return cached_res return pct_change
result = True
if daily_candles is not None and not daily_candles.empty: if daily_candles is not None and not daily_candles.empty:
highest_high = daily_candles['high'].max() highest_high = daily_candles['high'].max()
lowest_low = daily_candles['low'].min() lowest_low = daily_candles['low'].min()
pct_change = ((highest_high - lowest_low) / lowest_low) if lowest_low > 0 else 0 pct_change = ((highest_high - lowest_low) / lowest_low) if lowest_low > 0 else 0
if pct_change < self._min_rate_of_change: self._pair_cache[pair] = pct_change
self.log_once(f"Removed {pair} from whitelist, because rate of change " return pct_change
f"over {self._days} {plural(self._days, 'day')} is {pct_change:.3f}, "
f"which is below the threshold of {self._min_rate_of_change}.",
logger.info)
result = False
if self._max_rate_of_change:
if pct_change > self._max_rate_of_change:
self.log_once(
f"Removed {pair} from whitelist, because rate of change "
f"over {self._days} {plural(self._days, 'day')} is {pct_change:.3f}, "
f"which is above the threshold of {self._max_rate_of_change}.",
logger.info)
result = False
self._pair_cache[pair] = result
else: else:
self.log_once(f"Removed {pair} from whitelist, no candles found.", logger.info) return None
def _validate_pair_loc(self, pair: str, pct_change: float) -> bool:
"""
Validate trading range
:param pair: Pair that's currently validated
:param pct_change: Rate of change
:return: True if the pair can stay, false if it should be removed
"""
result = True
if pct_change < self._min_rate_of_change:
self.log_once(f"Removed {pair} from whitelist, because rate of change "
f"over {self._days} {plural(self._days, 'day')} is {pct_change:.3f}, "
f"which is below the threshold of {self._min_rate_of_change}.",
logger.info)
result = False
if self._max_rate_of_change:
if pct_change > self._max_rate_of_change:
self.log_once(
f"Removed {pair} from whitelist, because rate of change "
f"over {self._days} {plural(self._days, 'day')} is {pct_change:.3f}, "
f"which is above the threshold of {self._max_rate_of_change}.",
logger.info)
result = False
return result return result