use Type Alias for Ticker result to improve keyerror resiliancy
This commit is contained in:
parent
8ab600f7b2
commit
afaca2167c
@ -31,6 +31,7 @@ from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFun
|
|||||||
from freqtrade.exchange.common import (API_FETCH_ORDER_RETRY_COUNT, BAD_EXCHANGES,
|
from freqtrade.exchange.common import (API_FETCH_ORDER_RETRY_COUNT, BAD_EXCHANGES,
|
||||||
EXCHANGE_HAS_OPTIONAL, EXCHANGE_HAS_REQUIRED,
|
EXCHANGE_HAS_OPTIONAL, EXCHANGE_HAS_REQUIRED,
|
||||||
remove_credentials, retrier, retrier_async)
|
remove_credentials, retrier, retrier_async)
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.misc import (chunks, deep_merge_dicts, file_dump_json, file_load_json,
|
from freqtrade.misc import (chunks, deep_merge_dicts, file_dump_json, file_load_json,
|
||||||
safe_value_fallback2)
|
safe_value_fallback2)
|
||||||
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
||||||
@ -1420,14 +1421,15 @@ class Exchange:
|
|||||||
raise OperationalException(e) from e
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict:
|
def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Tickers:
|
||||||
"""
|
"""
|
||||||
:param cached: Allow cached result
|
:param cached: Allow cached result
|
||||||
:return: fetch_tickers result
|
:return: fetch_tickers result
|
||||||
"""
|
"""
|
||||||
|
tickers: Tickers
|
||||||
if cached:
|
if cached:
|
||||||
with self._cache_lock:
|
with self._cache_lock:
|
||||||
tickers = self._fetch_tickers_cache.get('fetch_tickers')
|
tickers = self._fetch_tickers_cache.get('fetch_tickers') # type: ignore
|
||||||
if tickers:
|
if tickers:
|
||||||
return tickers
|
return tickers
|
||||||
try:
|
try:
|
||||||
|
@ -12,6 +12,7 @@ from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, Invali
|
|||||||
OperationalException, TemporaryError)
|
OperationalException, TemporaryError)
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.exchange.common import retrier
|
from freqtrade.exchange.common import retrier
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -45,7 +46,7 @@ class Kraken(Exchange):
|
|||||||
return (parent_check and
|
return (parent_check and
|
||||||
market.get('darkpool', False) is False)
|
market.get('darkpool', False) is False)
|
||||||
|
|
||||||
def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Dict:
|
def get_tickers(self, symbols: Optional[List[str]] = None, cached: bool = False) -> Tickers:
|
||||||
# Only fetch tickers for current stake currency
|
# Only fetch tickers for current stake currency
|
||||||
# Otherwise the request for kraken becomes too large.
|
# Otherwise the request for kraken becomes too large.
|
||||||
symbols = list(self.get_markets(quote_currencies=[self._config['stake_currency']]))
|
symbols = list(self.get_markets(quote_currencies=[self._config['stake_currency']]))
|
||||||
|
5
freqtrade/exchange/types.py
Normal file
5
freqtrade/exchange/types.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
|
||||||
|
Ticker = Dict[str, Any]
|
||||||
|
Tickers = Dict[str, Ticker]
|
@ -10,6 +10,7 @@ from pandas import DataFrame
|
|||||||
|
|
||||||
from freqtrade.constants import Config, ListPairsWithTimeframes
|
from freqtrade.constants import Config, ListPairsWithTimeframes
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.misc import plural
|
from freqtrade.misc import plural
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
from freqtrade.util import PeriodicCache
|
from freqtrade.util import PeriodicCache
|
||||||
@ -67,7 +68,7 @@ class AgeFilter(IPairList):
|
|||||||
f"{self._max_days_listed} {plural(self._max_days_listed, 'day')}"
|
f"{self._max_days_listed} {plural(self._max_days_listed, 'day')}"
|
||||||
) if self._max_days_listed else '')
|
) if self._max_days_listed else '')
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
:param pairlist: pairlist to filter or sort
|
:param pairlist: pairlist to filter or sort
|
||||||
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
||||||
|
@ -4,11 +4,12 @@ PairList Handler base class
|
|||||||
import logging
|
import logging
|
||||||
from abc import ABC, abstractmethod, abstractproperty
|
from abc import ABC, abstractmethod, abstractproperty
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.exchange import Exchange, market_is_active
|
from freqtrade.exchange import Exchange, market_is_active
|
||||||
|
from freqtrade.exchange.types import Ticker, Tickers
|
||||||
from freqtrade.mixins import LoggingMixin
|
from freqtrade.mixins import LoggingMixin
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ class IPairList(LoggingMixin, ABC):
|
|||||||
-> Please overwrite in subclasses
|
-> Please overwrite in subclasses
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _validate_pair(self, pair: str, ticker: Dict[str, Any]) -> bool:
|
def _validate_pair(self, pair: str, ticker: Optional[Ticker]) -> bool:
|
||||||
"""
|
"""
|
||||||
Check one pair against Pairlist Handler's specific conditions.
|
Check one pair against Pairlist Handler's specific conditions.
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ class IPairList(LoggingMixin, ABC):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def gen_pairlist(self, tickers: Dict) -> List[str]:
|
def gen_pairlist(self, tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Generate the pairlist.
|
Generate the pairlist.
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ class IPairList(LoggingMixin, ABC):
|
|||||||
raise OperationalException("This Pairlist Handler should not be used "
|
raise OperationalException("This Pairlist Handler should not be used "
|
||||||
"at the first position in the list of Pairlist Handlers.")
|
"at the first position in the list of Pairlist Handlers.")
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Filters and sorts pairlist and returns the whitelist again.
|
Filters and sorts pairlist and returns the whitelist again.
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ class IPairList(LoggingMixin, ABC):
|
|||||||
# Copy list since we're modifying this list
|
# Copy list since we're modifying this list
|
||||||
for p in deepcopy(pairlist):
|
for p in deepcopy(pairlist):
|
||||||
# Filter out assets
|
# Filter out assets
|
||||||
if not self._validate_pair(p, tickers[p] if p in tickers else {}):
|
if not self._validate_pair(p, tickers[p] if p in tickers else None):
|
||||||
pairlist.remove(p)
|
pairlist.remove(p)
|
||||||
|
|
||||||
return pairlist
|
return pairlist
|
||||||
|
@ -6,6 +6,7 @@ from typing import Any, Dict, List
|
|||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ class OffsetFilter(IPairList):
|
|||||||
return f"{self.name} - Taking {self._number_pairs} Pairs, starting from {self._offset}."
|
return f"{self.name} - Taking {self._number_pairs} Pairs, starting from {self._offset}."
|
||||||
return f"{self.name} - Offsetting pairs by {self._offset}."
|
return f"{self.name} - Offsetting pairs by {self._offset}."
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Filters and sorts pairlist and returns the whitelist again.
|
Filters and sorts pairlist and returns the whitelist again.
|
||||||
Called on each bot iteration - please use internal caching if necessary
|
Called on each bot iteration - please use internal caching if necessary
|
||||||
|
@ -7,6 +7,7 @@ from typing import Any, Dict, List
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ class PerformanceFilter(IPairList):
|
|||||||
"""
|
"""
|
||||||
return f"{self.name} - Sorting pairs by performance."
|
return f"{self.name} - Sorting pairs by performance."
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Filters and sorts pairlist and returns the allowlist again.
|
Filters and sorts pairlist and returns the allowlist again.
|
||||||
Called on each bot iteration - please use internal caching if necessary
|
Called on each bot iteration - please use internal caching if necessary
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
Precision pair list filter
|
Precision pair list filter
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Ticker
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ class PrecisionFilter(IPairList):
|
|||||||
"""
|
"""
|
||||||
return f"{self.name} - Filtering untradable pairs."
|
return f"{self.name} - Filtering untradable pairs."
|
||||||
|
|
||||||
def _validate_pair(self, pair: str, ticker: Dict[str, Any]) -> bool:
|
def _validate_pair(self, pair: str, ticker: Optional[Ticker]) -> bool:
|
||||||
"""
|
"""
|
||||||
Check if pair has enough room to add a stoploss to avoid "unsellable" buys of very
|
Check if pair has enough room to add a stoploss to avoid "unsellable" buys of very
|
||||||
low value pairs.
|
low value pairs.
|
||||||
@ -52,7 +53,7 @@ class PrecisionFilter(IPairList):
|
|||||||
:param ticker: ticker dict as returned from ccxt.fetch_ticker
|
:param ticker: ticker dict as returned from ccxt.fetch_ticker
|
||||||
:return: True if the pair can stay, false if it should be removed
|
:return: True if the pair can stay, false if it should be removed
|
||||||
"""
|
"""
|
||||||
if ticker.get('last', None) is None:
|
if not ticker or ticker.get('last', None) is None:
|
||||||
self.log_once(f"Removed {pair} from whitelist, because "
|
self.log_once(f"Removed {pair} from whitelist, because "
|
||||||
"ticker['last'] is empty (Usually no trade in the last 24h).",
|
"ticker['last'] is empty (Usually no trade in the last 24h).",
|
||||||
logger.info)
|
logger.info)
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
Price pair list filter
|
Price pair list filter
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Ticker
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
@ -64,14 +65,14 @@ class PriceFilter(IPairList):
|
|||||||
|
|
||||||
return f"{self.name} - No price filters configured."
|
return f"{self.name} - No price filters configured."
|
||||||
|
|
||||||
def _validate_pair(self, pair: str, ticker: Dict[str, Any]) -> bool:
|
def _validate_pair(self, pair: str, ticker: Optional[Ticker]) -> bool:
|
||||||
"""
|
"""
|
||||||
Check if if one price-step (pip) is > than a certain barrier.
|
Check if if one price-step (pip) is > than a certain barrier.
|
||||||
:param pair: Pair that's currently validated
|
:param pair: Pair that's currently validated
|
||||||
:param ticker: ticker dict as returned from ccxt.fetch_ticker
|
:param ticker: ticker dict as returned from ccxt.fetch_ticker
|
||||||
:return: True if the pair can stay, false if it should be removed
|
:return: True if the pair can stay, false if it should be removed
|
||||||
"""
|
"""
|
||||||
if ticker.get('last', None) is None or ticker.get('last') == 0:
|
if not ticker or ticker.get('last', None) is None or ticker.get('last') == 0:
|
||||||
self.log_once(f"Removed {pair} from whitelist, because "
|
self.log_once(f"Removed {pair} from whitelist, because "
|
||||||
"ticker['last'] is empty (Usually no trade in the last 24h).",
|
"ticker['last'] is empty (Usually no trade in the last 24h).",
|
||||||
logger.info)
|
logger.info)
|
||||||
|
@ -7,6 +7,7 @@ import logging
|
|||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ class ProducerPairList(IPairList):
|
|||||||
|
|
||||||
return pairs
|
return pairs
|
||||||
|
|
||||||
def gen_pairlist(self, tickers: Dict) -> List[str]:
|
def gen_pairlist(self, tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Generate the pairlist
|
Generate the pairlist
|
||||||
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
||||||
@ -79,7 +80,7 @@ class ProducerPairList(IPairList):
|
|||||||
pairs = self._whitelist_for_active_markets(self.verify_whitelist(pairs, logger.info))
|
pairs = self._whitelist_for_active_markets(self.verify_whitelist(pairs, logger.info))
|
||||||
return pairs
|
return pairs
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Filters and sorts pairlist and returns the whitelist again.
|
Filters and sorts pairlist and returns the whitelist again.
|
||||||
Called on each bot iteration - please use internal caching if necessary
|
Called on each bot iteration - please use internal caching if necessary
|
||||||
|
@ -7,6 +7,7 @@ from typing import Any, Dict, List
|
|||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
from freqtrade.enums import RunMode
|
from freqtrade.enums import RunMode
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ class ShuffleFilter(IPairList):
|
|||||||
return (f"{self.name} - Shuffling pairs" +
|
return (f"{self.name} - Shuffling pairs" +
|
||||||
(f", seed = {self._seed}." if self._seed is not None else "."))
|
(f", seed = {self._seed}." if self._seed is not None else "."))
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Filters and sorts pairlist and returns the whitelist again.
|
Filters and sorts pairlist and returns the whitelist again.
|
||||||
Called on each bot iteration - please use internal caching if necessary
|
Called on each bot iteration - please use internal caching if necessary
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
Spread pair list filter
|
Spread pair list filter
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Ticker
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
@ -44,14 +45,14 @@ class SpreadFilter(IPairList):
|
|||||||
return (f"{self.name} - Filtering pairs with ask/bid diff above "
|
return (f"{self.name} - Filtering pairs with ask/bid diff above "
|
||||||
f"{self._max_spread_ratio:.2%}.")
|
f"{self._max_spread_ratio:.2%}.")
|
||||||
|
|
||||||
def _validate_pair(self, pair: str, ticker: Dict[str, Any]) -> bool:
|
def _validate_pair(self, pair: str, ticker: Optional[Ticker]) -> bool:
|
||||||
"""
|
"""
|
||||||
Validate spread for the ticker
|
Validate spread for the ticker
|
||||||
:param pair: Pair that's currently validated
|
:param pair: Pair that's currently validated
|
||||||
:param ticker: ticker dict as returned from ccxt.fetch_ticker
|
:param ticker: ticker dict as returned from ccxt.fetch_ticker
|
||||||
:return: True if the pair can stay, false if it should be removed
|
:return: True if the pair can stay, false if it should be removed
|
||||||
"""
|
"""
|
||||||
if 'bid' in ticker and 'ask' in ticker and ticker['ask'] and ticker['bid']:
|
if ticker and 'bid' in ticker and 'ask' in ticker and ticker['ask'] and ticker['bid']:
|
||||||
spread = 1 - ticker['bid'] / ticker['ask']
|
spread = 1 - ticker['bid'] / ticker['ask']
|
||||||
if spread > self._max_spread_ratio:
|
if spread > self._max_spread_ratio:
|
||||||
self.log_once(f"Removed {pair} from whitelist, because spread "
|
self.log_once(f"Removed {pair} from whitelist, because spread "
|
||||||
|
@ -8,6 +8,7 @@ from copy import deepcopy
|
|||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from freqtrade.constants import Config
|
from freqtrade.constants import Config
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ class StaticPairList(IPairList):
|
|||||||
"""
|
"""
|
||||||
return f"{self.name}"
|
return f"{self.name}"
|
||||||
|
|
||||||
def gen_pairlist(self, tickers: Dict) -> List[str]:
|
def gen_pairlist(self, tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Generate the pairlist
|
Generate the pairlist
|
||||||
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
||||||
@ -53,7 +54,7 @@ class StaticPairList(IPairList):
|
|||||||
return self._whitelist_for_active_markets(
|
return self._whitelist_for_active_markets(
|
||||||
self.verify_whitelist(self._config['exchange']['pair_whitelist'], logger.info))
|
self.verify_whitelist(self._config['exchange']['pair_whitelist'], logger.info))
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Filters and sorts pairlist and returns the whitelist again.
|
Filters and sorts pairlist and returns the whitelist again.
|
||||||
Called on each bot iteration - please use internal caching if necessary
|
Called on each bot iteration - please use internal caching if necessary
|
||||||
|
@ -13,6 +13,7 @@ from pandas import DataFrame
|
|||||||
|
|
||||||
from freqtrade.constants import Config, ListPairsWithTimeframes
|
from freqtrade.constants import Config, ListPairsWithTimeframes
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.misc import plural
|
from freqtrade.misc import plural
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ class VolatilityFilter(IPairList):
|
|||||||
f"{self._min_volatility}-{self._max_volatility} "
|
f"{self._min_volatility}-{self._max_volatility} "
|
||||||
f" the last {self._days} {plural(self._days, 'day')}.")
|
f" the last {self._days} {plural(self._days, 'day')}.")
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Validate trading range
|
Validate trading range
|
||||||
:param pairlist: pairlist to filter or sort
|
:param pairlist: pairlist to filter or sort
|
||||||
|
@ -5,13 +5,14 @@ Provides dynamic pair list based on trade volumes
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List, Literal
|
||||||
|
|
||||||
from cachetools import TTLCache
|
from cachetools import TTLCache
|
||||||
|
|
||||||
from freqtrade.constants import Config, ListPairsWithTimeframes
|
from freqtrade.constants import Config, ListPairsWithTimeframes
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date
|
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.misc import format_ms_time
|
from freqtrade.misc import format_ms_time
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ class VolumePairList(IPairList):
|
|||||||
|
|
||||||
self._stake_currency = config['stake_currency']
|
self._stake_currency = config['stake_currency']
|
||||||
self._number_pairs = self._pairlistconfig['number_assets']
|
self._number_pairs = self._pairlistconfig['number_assets']
|
||||||
self._sort_key = self._pairlistconfig.get('sort_key', 'quoteVolume')
|
self._sort_key: Literal['quoteVolume'] = self._pairlistconfig.get('sort_key', 'quoteVolume')
|
||||||
self._min_value = self._pairlistconfig.get('min_value', 0)
|
self._min_value = self._pairlistconfig.get('min_value', 0)
|
||||||
self._refresh_period = self._pairlistconfig.get('refresh_period', 1800)
|
self._refresh_period = self._pairlistconfig.get('refresh_period', 1800)
|
||||||
self._pair_cache: TTLCache = TTLCache(maxsize=1, ttl=self._refresh_period)
|
self._pair_cache: TTLCache = TTLCache(maxsize=1, ttl=self._refresh_period)
|
||||||
@ -110,7 +111,7 @@ class VolumePairList(IPairList):
|
|||||||
"""
|
"""
|
||||||
return f"{self.name} - top {self._pairlistconfig['number_assets']} volume pairs."
|
return f"{self.name} - top {self._pairlistconfig['number_assets']} volume pairs."
|
||||||
|
|
||||||
def gen_pairlist(self, tickers: Dict) -> List[str]:
|
def gen_pairlist(self, tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Generate the pairlist
|
Generate the pairlist
|
||||||
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
||||||
|
@ -11,6 +11,7 @@ from pandas import DataFrame
|
|||||||
|
|
||||||
from freqtrade.constants import Config, ListPairsWithTimeframes
|
from freqtrade.constants import Config, ListPairsWithTimeframes
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.misc import plural
|
from freqtrade.misc import plural
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ class RangeStabilityFilter(IPairList):
|
|||||||
f"{self._min_rate_of_change}{max_rate_desc} over the "
|
f"{self._min_rate_of_change}{max_rate_desc} over the "
|
||||||
f"last {plural(self._days, 'day')}.")
|
f"last {plural(self._days, 'day')}.")
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Tickers) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Validate trading range
|
Validate trading range
|
||||||
:param pairlist: pairlist to filter or sort
|
:param pairlist: pairlist to filter or sort
|
||||||
|
@ -11,6 +11,7 @@ from freqtrade.constants import Config, ListPairsWithTimeframes
|
|||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.enums import CandleType
|
from freqtrade.enums import CandleType
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
|
from freqtrade.exchange.types import Tickers
|
||||||
from freqtrade.mixins import LoggingMixin
|
from freqtrade.mixins import LoggingMixin
|
||||||
from freqtrade.plugins.pairlist.IPairList import IPairList
|
from freqtrade.plugins.pairlist.IPairList import IPairList
|
||||||
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist
|
||||||
@ -76,7 +77,7 @@ class PairListManager(LoggingMixin):
|
|||||||
return [{p.name: p.short_desc()} for p in self._pairlist_handlers]
|
return [{p.name: p.short_desc()} for p in self._pairlist_handlers]
|
||||||
|
|
||||||
@cached(TTLCache(maxsize=1, ttl=1800))
|
@cached(TTLCache(maxsize=1, ttl=1800))
|
||||||
def _get_cached_tickers(self):
|
def _get_cached_tickers(self) -> Tickers:
|
||||||
return self._exchange.get_tickers()
|
return self._exchange.get_tickers()
|
||||||
|
|
||||||
def refresh_pairlist(self) -> None:
|
def refresh_pairlist(self) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user