add crossmarketfilter
This commit is contained in:
@@ -4,7 +4,7 @@ Pairlist Handlers define the list of pairs (pairlist) that the bot should trade.
|
|||||||
|
|
||||||
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) and [`PercentChangePairList`](#percent-change-pair-list) Pairlist Handlers).
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
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` or `PercentChangePairList` as the starting Pairlist Handler.
|
||||||
|
|
||||||
@@ -27,6 +27,7 @@ You may also use something like `.*DOWN/BTC` or `.*UP/BTC` to exclude leveraged
|
|||||||
* [`RemotePairList`](#remotepairlist)
|
* [`RemotePairList`](#remotepairlist)
|
||||||
* [`MarketCapPairList`](#marketcappairlist)
|
* [`MarketCapPairList`](#marketcappairlist)
|
||||||
* [`AgeFilter`](#agefilter)
|
* [`AgeFilter`](#agefilter)
|
||||||
|
* [`CrossMarketFilter`](#crossmarketfilter)
|
||||||
* [`DelistFilter`](#delistfilter)
|
* [`DelistFilter`](#delistfilter)
|
||||||
* [`FullTradesFilter`](#fulltradesfilter)
|
* [`FullTradesFilter`](#fulltradesfilter)
|
||||||
* [`OffsetFilter`](#offsetfilter)
|
* [`OffsetFilter`](#offsetfilter)
|
||||||
@@ -412,6 +413,12 @@ 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`.
|
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
|
#### 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:
|
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:
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ AVAILABLE_PAIRLISTS = [
|
|||||||
"RemotePairList",
|
"RemotePairList",
|
||||||
"MarketCapPairList",
|
"MarketCapPairList",
|
||||||
"AgeFilter",
|
"AgeFilter",
|
||||||
|
"CrossMarketFilter",
|
||||||
"DelistFilter",
|
"DelistFilter",
|
||||||
"FullTradesFilter",
|
"FullTradesFilter",
|
||||||
"OffsetFilter",
|
"OffsetFilter",
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
"""
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class CrossMarketFilter(IPairList):
|
||||||
|
supports_backtesting = SupportsBacktesting.BIASED
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self._mode: str = self._pairlistconfig.get("mode", "whitelist")
|
||||||
|
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"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def needstickers(self) -> bool:
|
||||||
|
"""
|
||||||
|
Boolean property defining if tickers are necessary.
|
||||||
|
If no Pairlist requires tickers, an empty Dict is passed
|
||||||
|
as tickers argument to filter_pairlist
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
def short_desc(self) -> str:
|
||||||
|
"""
|
||||||
|
Short whitelist method description - used for startup-messages
|
||||||
|
"""
|
||||||
|
mode = self._mode
|
||||||
|
target_mode = self._target_mode
|
||||||
|
msg = f"{self.name} - {mode.capitalize()} pairs that exists on {target_mode} market."
|
||||||
|
return msg
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def description() -> str:
|
||||||
|
return "Filter pairs if they exist on another market."
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def available_parameters() -> dict[str, PairlistParameter]:
|
||||||
|
return {
|
||||||
|
"mode": {
|
||||||
|
"type": "option",
|
||||||
|
"default": "whitelist",
|
||||||
|
"options": ["whitelist", "blacklist"],
|
||||||
|
"description": "Mode of operation",
|
||||||
|
"help": "Mode of operation (whitelist/blacklist)",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_base_list(self):
|
||||||
|
target_mode = self._target_mode
|
||||||
|
spot_only = True if target_mode == "spot" else False
|
||||||
|
futures_only = True if target_mode == "futures" else False
|
||||||
|
bases = [
|
||||||
|
v.get("base", "")
|
||||||
|
for k, v in self._exchange.get_markets(
|
||||||
|
quote_currencies=[self._stake_currency],
|
||||||
|
tradable_only=False,
|
||||||
|
active_only=True,
|
||||||
|
spot_only=spot_only,
|
||||||
|
futures_only=futures_only,
|
||||||
|
).items()
|
||||||
|
]
|
||||||
|
return bases
|
||||||
|
|
||||||
|
prefixes = ("1000", "1000000", "1M", "K", "M")
|
||||||
|
|
||||||
|
def filter_pairlist(self, pairlist: list[str], tickers: Tickers) -> list[str]:
|
||||||
|
bases = self.get_base_list()
|
||||||
|
is_whitelist_mode = self._mode == "whitelist"
|
||||||
|
whitelisted_pairlist: list[str] = []
|
||||||
|
filtered_pairlist = pairlist.copy()
|
||||||
|
|
||||||
|
for pair in pairlist:
|
||||||
|
base = self._exchange.get_pair_base_currency(pair)
|
||||||
|
found_in_bases = base in bases
|
||||||
|
if not found_in_bases:
|
||||||
|
for prefix in self.prefixes:
|
||||||
|
test_prefix = f"{prefix}{base}"
|
||||||
|
if test_prefix in bases:
|
||||||
|
found_in_bases = True
|
||||||
|
break
|
||||||
|
if found_in_bases:
|
||||||
|
whitelisted_pairlist.append(pair)
|
||||||
|
filtered_pairlist.remove(pair)
|
||||||
|
|
||||||
|
return whitelisted_pairlist if is_whitelist_mode else filtered_pairlist
|
||||||
Reference in New Issue
Block a user