mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-03-05 13:24:20 +00:00
add tests
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
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), [`CrossMarketPairlist`](#crossmarketpairlist), [`MarketCapPairlist`](#marketcappairlist) 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), [`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.
|
||||
|
||||
@@ -26,7 +26,7 @@ You may also use something like `.*DOWN/BTC` or `.*UP/BTC` to exclude leveraged
|
||||
* [`ProducerPairList`](#producerpairlist)
|
||||
* [`RemotePairList`](#remotepairlist)
|
||||
* [`MarketCapPairList`](#marketcappairlist)
|
||||
* [`CrossMarketPairlist`](#crossmarketpairlist)
|
||||
* [`CrossMarketPairList`](#CrossMarketPairList)
|
||||
* [`AgeFilter`](#agefilter)
|
||||
* [`DelistFilter`](#delistfilter)
|
||||
* [`FullTradesFilter`](#fulltradesfilter)
|
||||
@@ -403,7 +403,7 @@ 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
|
||||
#### 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.
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ AVAILABLE_PAIRLISTS = [
|
||||
"ProducerPairList",
|
||||
"RemotePairList",
|
||||
"MarketCapPairList",
|
||||
"CrossMarketPairlist",
|
||||
"CrossMarketPairList",
|
||||
"AgeFilter",
|
||||
"DelistFilter",
|
||||
"FullTradesFilter",
|
||||
|
||||
@@ -4,6 +4,7 @@ Price pair list filter
|
||||
|
||||
import logging
|
||||
|
||||
from freqtrade.constants import PairPrefixes
|
||||
from freqtrade.exchange.exchange_types import Tickers
|
||||
from freqtrade.plugins.pairlist.IPairList import IPairList, PairlistParameter, SupportsBacktesting
|
||||
from freqtrade.util import FtTTLCache
|
||||
@@ -12,7 +13,7 @@ from freqtrade.util import FtTTLCache
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CrossMarketPairlist(IPairList):
|
||||
class CrossMarketPairList(IPairList):
|
||||
supports_backtesting = SupportsBacktesting.BIASED
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
@@ -76,8 +77,6 @@ class CrossMarketPairlist(IPairList):
|
||||
]
|
||||
return bases
|
||||
|
||||
prefixes = ("1000", "1000000", "1M", "K", "M")
|
||||
|
||||
def gen_pairlist(self, tickers: Tickers) -> list[str]:
|
||||
"""
|
||||
Generate the pairlist
|
||||
@@ -115,21 +114,26 @@ class CrossMarketPairlist(IPairList):
|
||||
|
||||
for pair in pairlist:
|
||||
base = self._exchange.get_pair_base_currency(pair)
|
||||
if not base:
|
||||
filtered_pairlist.remove(pair)
|
||||
continue
|
||||
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
|
||||
for prefix in PairPrefixes:
|
||||
# Check in case of PEPE needs to be changed into 1000PEPE for example
|
||||
test_prefix = f"{prefix}{base}"
|
||||
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
|
||||
# Avoid false positive since there are KAVA and AVA pairs, which aren't related
|
||||
if prefix != "K":
|
||||
# Check in case of 1000PEPE needs to be changed into 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)
|
||||
@@ -2584,6 +2584,107 @@ def test_MarketCapPairList_exceptions(mocker, default_conf_usdt, caplog):
|
||||
PairListManager(exchange, default_conf_usdt)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"pairlists,trade_mode,result",
|
||||
[
|
||||
(
|
||||
[
|
||||
# Whitelist mode on spot
|
||||
{"method": "StaticPairList", "allow_inactive": True},
|
||||
{"method": "CrossMarketPairList", "mode": "whitelist"},
|
||||
],
|
||||
"spot",
|
||||
["ETH/USDT"],
|
||||
),
|
||||
(
|
||||
[
|
||||
# Blacklist mode on spot
|
||||
{"method": "StaticPairList", "allow_inactive": True},
|
||||
{"method": "CrossMarketPairList", "mode": "blacklist"},
|
||||
],
|
||||
"spot",
|
||||
["LTC/USDT", "XRP/USDT", "NEO/USDT", "TKN/USDT", "BTC/USDT"],
|
||||
),
|
||||
(
|
||||
[
|
||||
# Whitelist mode on futures
|
||||
{"method": "StaticPairList", "allow_inactive": True},
|
||||
{"method": "CrossMarketPairList", "mode": "whitelist"},
|
||||
],
|
||||
"futures",
|
||||
["ETH/USDT:USDT"],
|
||||
),
|
||||
(
|
||||
[
|
||||
# Blacklist mode on futures
|
||||
{"method": "StaticPairList", "allow_inactive": True},
|
||||
{"method": "CrossMarketPairList", "mode": "blacklist"},
|
||||
],
|
||||
"futures",
|
||||
["ADA/USDT:USDT"],
|
||||
),
|
||||
(
|
||||
[
|
||||
# CrossMarketPairList as generator, whitelist mode, spot market
|
||||
{"method": "CrossMarketPairList", "mode": "whitelist"},
|
||||
],
|
||||
"spot",
|
||||
["ETH/USDT"],
|
||||
),
|
||||
(
|
||||
[
|
||||
# CrossMarketPairList as generator, blacklist mode, spot market
|
||||
{"method": "CrossMarketPairList", "mode": "blacklist"},
|
||||
],
|
||||
"spot",
|
||||
["BTC/USDT", "XRP/USDT", "NEO/USDT", "TKN/USDT"],
|
||||
),
|
||||
(
|
||||
[
|
||||
# CrossMarketPairList as generator, whitelist mode, futures market
|
||||
{"method": "CrossMarketPairList", "mode": "whitelist"},
|
||||
],
|
||||
"futures",
|
||||
["ETH/USDT:USDT"],
|
||||
),
|
||||
(
|
||||
[
|
||||
# CrossMarketPairList as generator, blacklist mode, futures market
|
||||
{"method": "CrossMarketPairList", "mode": "blacklist"},
|
||||
],
|
||||
"futures",
|
||||
["ADA/USDT:USDT"],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_CrossMarketPairlist_filter(
|
||||
mocker, default_conf_usdt, trade_mode, markets, pairlists, result
|
||||
):
|
||||
default_conf_usdt["trading_mode"] = trade_mode
|
||||
if trade_mode == "spot":
|
||||
default_conf_usdt["exchange"]["pair_whitelist"].extend(["BTC/USDT", "ETC/USDT", "ADA/USDT"])
|
||||
else:
|
||||
default_conf_usdt["exchange"]["pair_whitelist"] = [
|
||||
"BTC/USDT:USDT",
|
||||
"ETH/USDT:USDT",
|
||||
"ETC/USDT:USDT",
|
||||
"ADA/USDT:USDT",
|
||||
]
|
||||
default_conf_usdt["pairlists"] = pairlists
|
||||
mocker.patch.multiple(
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf_usdt)
|
||||
|
||||
pm = PairListManager(exchange, default_conf_usdt)
|
||||
pm.refresh_pairlist()
|
||||
|
||||
assert pm.whitelist == result
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"pairlists,expected_error,expected_warning",
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user