Simplify rangeStability Filter

This commit is contained in:
Matthias
2024-02-24 13:50:54 +01:00
parent 88a2995b4c
commit 7af46628f8

View File

@@ -2,9 +2,8 @@
Rate of change pairlist filter
"""
import logging
from copy import deepcopy
from datetime import timedelta
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List
from cachetools import TTLCache
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))
candles = self._exchange.refresh_ohlcv_with_cache(needed_pairs, since_ms=since_ms)
if self._enabled:
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
resulting_pairlist: List[str] = []
def _validate_pair_loc(self, pair: str, daily_candles: Optional[DataFrame]) -> bool:
"""
Validate trading range
:param pair: Pair that's currently validated
:param daily_candles: Downloaded daily candles
:return: True if the pair can stay, false if it should be removed
"""
for p in pairlist:
daily_candles = candles.get((p, '1d', self._def_candletype), None)
pct_change = self._calculate_rate_of_change(p, daily_candles)
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
if (cached_res := self._pair_cache.get(pair, None)) is not None:
return cached_res
result = True
if (pct_change := self._pair_cache.get(pair, None)) is not None:
return pct_change
if daily_candles is not None and not daily_candles.empty:
highest_high = daily_candles['high'].max()
lowest_low = daily_candles['low'].min()
pct_change = ((highest_high - lowest_low) / lowest_low) if lowest_low > 0 else 0
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
self._pair_cache[pair] = result
self._pair_cache[pair] = pct_change
return pct_change
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