mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-03-05 13:24:20 +00:00
change into pairlist plugin
This commit is contained in:
@@ -2,11 +2,11 @@
|
||||
|
||||
Pairlist Handlers define the list of pairs (pairlist) that the bot should trade. They are configured in the `pairlists` section of the configuration settings.
|
||||
|
||||
In your configuration, you can use Static Pairlist (defined by the [`StaticPairList`](#static-pair-list) Pairlist Handler) and Dynamic Pairlist (defined by the [`VolumePairList`](#volume-pair-list) and [`PercentChangePairList`](#percent-change-pair-list) Pairlist Handlers).
|
||||
In your configuration, you can use Static Pairlist (defined by the [`StaticPairList`](#static-pair-list) Pairlist Handler) and Dynamic Pairlist (defined by the [`VolumePairList`](#volume-pair-list), [`CrossMarketPairlist`](#crossmarketpairlist), [`MarketCapPairlist`](#marketcappairlist) and [`PercentChangePairList`](#percent-change-pair-list) Pairlist Handlers).
|
||||
|
||||
Additionally, [`AgeFilter`](#agefilter), [`CrossMarketFilter`](#crossmarketfilter), [`DelistFilter`](#delistfilter), [`PrecisionFilter`](#precisionfilter), [`PriceFilter`](#pricefilter), [`ShuffleFilter`](#shufflefilter), [`SpreadFilter`](#spreadfilter) and [`VolatilityFilter`](#volatilityfilter) act as Pairlist Filters, removing certain pairs and/or moving their positions in the pairlist.
|
||||
Additionally, [`AgeFilter`](#agefilter), [`DelistFilter`](#delistfilter), [`PrecisionFilter`](#precisionfilter), [`PriceFilter`](#pricefilter), [`ShuffleFilter`](#shufflefilter), [`SpreadFilter`](#spreadfilter) and [`VolatilityFilter`](#volatilityfilter) act as Pairlist Filters, removing certain pairs and/or moving their positions in the pairlist.
|
||||
|
||||
If multiple Pairlist Handlers are used, they are chained and a combination of all Pairlist Handlers forms the resulting pairlist the bot uses for trading and backtesting. Pairlist Handlers are executed in the sequence they are configured. You can define either `StaticPairList`, `VolumePairList`, `ProducerPairList`, `RemotePairList`, `MarketCapPairList` or `PercentChangePairList` as the starting Pairlist Handler.
|
||||
If multiple Pairlist Handlers are used, they are chained and a combination of all Pairlist Handlers forms the resulting pairlist the bot uses for trading and backtesting. Pairlist Handlers are executed in the sequence they are configured. You can define either `StaticPairList`, `VolumePairList`, `ProducerPairList`, `RemotePairList`, `MarketCapPairList`, `PercentChangePairList` or `CrossMarketPairList` as the starting Pairlist Handler.
|
||||
|
||||
Inactive markets are always removed from the resulting pairlist. Explicitly blacklisted pairs (those in the `pair_blacklist` configuration setting) are also always removed from the resulting pairlist.
|
||||
|
||||
@@ -26,8 +26,8 @@ You may also use something like `.*DOWN/BTC` or `.*UP/BTC` to exclude leveraged
|
||||
* [`ProducerPairList`](#producerpairlist)
|
||||
* [`RemotePairList`](#remotepairlist)
|
||||
* [`MarketCapPairList`](#marketcappairlist)
|
||||
* [`CrossMarketPairlist`](#crossmarketpairlist)
|
||||
* [`AgeFilter`](#agefilter)
|
||||
* [`CrossMarketFilter`](#crossmarketfilter)
|
||||
* [`DelistFilter`](#delistfilter)
|
||||
* [`FullTradesFilter`](#fulltradesfilter)
|
||||
* [`OffsetFilter`](#offsetfilter)
|
||||
@@ -403,6 +403,12 @@ Coins like 1000PEPE/USDT or KPEPE/USDT:USDT are detected on a best effort basis,
|
||||
!!! Danger "Duplicate symbols in coingecko"
|
||||
Coingecko often has duplicate symbols, where the same symbol is used for different coins. Freqtrade will use the symbol as is and try to search for it on the exchange. If the symbol exists - it will be used. Freqtrade will however not check if the _intended_ symbol is the one coingecko meant. This can sometimes lead to unexpected results, especially on low volume coins or with meme coin categories.
|
||||
|
||||
#### CrossMarketPairlist
|
||||
|
||||
Generate or filter pairs based of their availability on the opposite market. So for spot pairs, it will be checked against futures market, and vice versa.
|
||||
|
||||
The `mode` setting defines whether the plugin will filters in (whitelist `mode`) or filters out (blacklist `mode`) pairs if they are active on opposite market. By default, the plugin will be in whitelist mode.
|
||||
|
||||
#### AgeFilter
|
||||
|
||||
Removes pairs that have been listed on the exchange for less than `min_days_listed` days (defaults to `10`) or more than `max_days_listed` days (defaults `None` mean infinity).
|
||||
@@ -413,12 +419,6 @@ be caught out buying before the pair has finished dropping in price.
|
||||
|
||||
This filter allows freqtrade to ignore pairs until they have been listed for at least `min_days_listed` days and listed before `max_days_listed`.
|
||||
|
||||
#### CrossMarketFilter
|
||||
|
||||
Filter pairs based of their availability on the opposite market. So for spot pairs, it will be checked against futures market, and vice versa.
|
||||
|
||||
The `mode` setting defines whether the plugin will filters in (whitelist `mode`) or filters out (blacklist `mode`) based of the availability on the opposite market. By default, the plugin will be in whitelist mode.
|
||||
|
||||
#### DelistFilter
|
||||
|
||||
Removes pairs that will be delisted on the exchange maximum `max_days_from_now` days from now (defaults to `0` which remove all future delisted pairs no matter how far from now). Currently this filter only supports following exchanges:
|
||||
|
||||
@@ -61,8 +61,8 @@ AVAILABLE_PAIRLISTS = [
|
||||
"ProducerPairList",
|
||||
"RemotePairList",
|
||||
"MarketCapPairList",
|
||||
"CrossMarketPairlist",
|
||||
"AgeFilter",
|
||||
"CrossMarketFilter",
|
||||
"DelistFilter",
|
||||
"FullTradesFilter",
|
||||
"OffsetFilter",
|
||||
|
||||
@@ -4,17 +4,15 @@ Price pair list filter
|
||||
|
||||
import logging
|
||||
|
||||
import ccxt.pro as ccxt_pro
|
||||
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange.exchange_types import Tickers
|
||||
from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting
|
||||
from freqtrade.util import FtTTLCache
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CrossMarketFilter(IPairList):
|
||||
class CrossMarketPairlist(IPairList):
|
||||
supports_backtesting = SupportsBacktesting.BIASED
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
@@ -24,6 +22,8 @@ class CrossMarketFilter(IPairList):
|
||||
self._trading_mode: str = self._config["trading_mode"]
|
||||
self._stake_currency: str = self._config["stake_currency"]
|
||||
self._target_mode = "futures" if self._trading_mode == "spot" else "spot"
|
||||
self._refresh_period = self._pairlistconfig.get("refresh_period", 1800)
|
||||
self._pair_cache: FtTTLCache = FtTTLCache(maxsize=1, ttl=self._refresh_period)
|
||||
|
||||
@property
|
||||
def needstickers(self) -> bool:
|
||||
@@ -57,6 +57,7 @@ class CrossMarketFilter(IPairList):
|
||||
"description": "Mode of operation",
|
||||
"help": "Mode of operation (whitelist/blacklist)",
|
||||
},
|
||||
**IPairList.refresh_period_parameter(),
|
||||
}
|
||||
|
||||
def get_base_list(self):
|
||||
@@ -77,6 +78,35 @@ class CrossMarketFilter(IPairList):
|
||||
|
||||
prefixes = ("1000", "1000000", "1M", "K", "M")
|
||||
|
||||
def gen_pairlist(self, tickers: Tickers) -> list[str]:
|
||||
"""
|
||||
Generate the pairlist
|
||||
:param tickers: Tickers (from exchange.get_tickers). May be cached.
|
||||
:return: List of pairs
|
||||
"""
|
||||
# Generate dynamic whitelist
|
||||
# Must always run if this pairlist is the first in the list.
|
||||
pairlist = self._pair_cache.get("pairlist")
|
||||
if pairlist:
|
||||
# Item found - no refresh necessary
|
||||
return pairlist.copy()
|
||||
else:
|
||||
# Use fresh pairlist
|
||||
# Check if pair quote currency equals to the stake currency.
|
||||
_pairlist = [
|
||||
k
|
||||
for k in self._exchange.get_markets(
|
||||
quote_currencies=[self._stake_currency], tradable_only=True, active_only=True
|
||||
).keys()
|
||||
]
|
||||
|
||||
_pairlist = self.verify_blacklist(_pairlist, logger.info)
|
||||
|
||||
pairlist = self.filter_pairlist(_pairlist, tickers)
|
||||
self._pair_cache["pairlist"] = pairlist.copy()
|
||||
|
||||
return pairlist
|
||||
|
||||
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
|
||||
bases = self.get_base_list()
|
||||
is_whitelist_mode = self._mode == "whitelist"
|
||||
@@ -88,10 +118,18 @@ class CrossMarketFilter(IPairList):
|
||||
found_in_bases = base in bases
|
||||
if not found_in_bases:
|
||||
for prefix in self.prefixes:
|
||||
# Check in case of PEPE needs to be changed to 1000PEPE for example
|
||||
test_prefix = f"{prefix}{base}"
|
||||
if test_prefix in bases:
|
||||
found_in_bases = True
|
||||
found_in_bases = test_prefix in bases
|
||||
if found_in_bases:
|
||||
break
|
||||
|
||||
# Check in case of 1000PEPE needs to be changed to PEPE for example
|
||||
if base.startswith(prefix):
|
||||
temp_base = base.removeprefix(prefix)
|
||||
found_in_bases = temp_base in bases
|
||||
if found_in_bases:
|
||||
break
|
||||
if found_in_bases:
|
||||
whitelisted_pairlist.append(pair)
|
||||
filtered_pairlist.remove(pair)
|
||||
Reference in New Issue
Block a user