Merge pull request #3205 from freqtrade/fix/ftx_dynamic_crash
fix crash with Dynamic whitelist with pairfilter on FTX
This commit is contained in:
commit
c5b204ea87
@ -37,6 +37,12 @@ class PriceFilter(IPairList):
|
|||||||
:param ticker: ticker dict as returned from ccxt.load_markets()
|
:param ticker: ticker dict as returned from ccxt.load_markets()
|
||||||
: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['last'] is None:
|
||||||
|
|
||||||
|
self.log_on_refresh(logger.info,
|
||||||
|
f"Removed {ticker['symbol']} from whitelist, because "
|
||||||
|
"ticker['last'] is empty (Usually no trade in the last 24h).")
|
||||||
|
return False
|
||||||
compare = ticker['last'] + self._exchange.price_get_one_pip(ticker['symbol'],
|
compare = ticker['last'] + self._exchange.price_get_one_pip(ticker['symbol'],
|
||||||
ticker['last'])
|
ticker['last'])
|
||||||
changeperc = (compare - ticker['last']) / ticker['last']
|
changeperc = (compare - ticker['last']) / ticker['last']
|
||||||
@ -47,7 +53,6 @@ class PriceFilter(IPairList):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]:
|
def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> 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
|
||||||
|
@ -739,6 +739,31 @@ def shitcoinmarkets(markets):
|
|||||||
"future": False,
|
"future": False,
|
||||||
"active": True
|
"active": True
|
||||||
},
|
},
|
||||||
|
'ADAHALF/USDT': {
|
||||||
|
"percentage": True,
|
||||||
|
"tierBased": False,
|
||||||
|
"taker": 0.001,
|
||||||
|
"maker": 0.001,
|
||||||
|
"precision": {
|
||||||
|
"base": 8,
|
||||||
|
"quote": 8,
|
||||||
|
"amount": 2,
|
||||||
|
"price": 4
|
||||||
|
},
|
||||||
|
"limits": {
|
||||||
|
},
|
||||||
|
"id": "ADAHALFUSDT",
|
||||||
|
"symbol": "ADAHALF/USDT",
|
||||||
|
"base": "ADAHALF",
|
||||||
|
"quote": "USDT",
|
||||||
|
"baseId": "ADAHALF",
|
||||||
|
"quoteId": "USDT",
|
||||||
|
"info": {},
|
||||||
|
"type": "spot",
|
||||||
|
"spot": True,
|
||||||
|
"future": False,
|
||||||
|
"active": True
|
||||||
|
},
|
||||||
})
|
})
|
||||||
return shitmarkets
|
return shitmarkets
|
||||||
|
|
||||||
@ -1243,6 +1268,29 @@ def tickers():
|
|||||||
"quoteVolume": 323652.075405,
|
"quoteVolume": 323652.075405,
|
||||||
"info": {}
|
"info": {}
|
||||||
},
|
},
|
||||||
|
# Example of leveraged pair with incomplete info
|
||||||
|
"ADAHALF/USDT": {
|
||||||
|
"symbol": "ADAHALF/USDT",
|
||||||
|
"timestamp": 1580469388244,
|
||||||
|
"datetime": "2020-01-31T11:16:28.244Z",
|
||||||
|
"high": None,
|
||||||
|
"low": None,
|
||||||
|
"bid": 0.7305,
|
||||||
|
"bidVolume": None,
|
||||||
|
"ask": 0.7342,
|
||||||
|
"askVolume": None,
|
||||||
|
"vwap": None,
|
||||||
|
"open": None,
|
||||||
|
"close": None,
|
||||||
|
"last": None,
|
||||||
|
"previousClose": None,
|
||||||
|
"change": None,
|
||||||
|
"percentage": 2.628,
|
||||||
|
"average": None,
|
||||||
|
"baseVolume": 0.0,
|
||||||
|
"quoteVolume": 0.0,
|
||||||
|
"info": {}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
|
|||||||
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "bidVolume"}],
|
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "bidVolume"}],
|
||||||
"BTC", ['HOT/BTC', 'FUEL/BTC', 'XRP/BTC', 'LTC/BTC', 'TKN/BTC']),
|
"BTC", ['HOT/BTC', 'FUEL/BTC', 'XRP/BTC', 'LTC/BTC', 'TKN/BTC']),
|
||||||
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}],
|
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}],
|
||||||
"USDT", ['ETH/USDT', 'NANO/USDT']),
|
"USDT", ['ETH/USDT', 'NANO/USDT', 'ADAHALF/USDT']),
|
||||||
# No pair for ETH ...
|
# No pair for ETH ...
|
||||||
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}],
|
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}],
|
||||||
"ETH", []),
|
"ETH", []),
|
||||||
@ -177,6 +177,10 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
|
|||||||
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"},
|
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"},
|
||||||
{"method": "PriceFilter", "low_price_ratio": 0.03}],
|
{"method": "PriceFilter", "low_price_ratio": 0.03}],
|
||||||
"BTC", ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC']),
|
"BTC", ['ETH/BTC', 'TKN/BTC', 'LTC/BTC', 'XRP/BTC']),
|
||||||
|
# PriceFilter and VolumePairList
|
||||||
|
([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"},
|
||||||
|
{"method": "PriceFilter", "low_price_ratio": 0.03}],
|
||||||
|
"USDT", ['ETH/USDT', 'NANO/USDT']),
|
||||||
# Hot is removed by precision_filter, Fuel by low_price_filter.
|
# Hot is removed by precision_filter, Fuel by low_price_filter.
|
||||||
([{"method": "VolumePairList", "number_assets": 6, "sort_key": "quoteVolume"},
|
([{"method": "VolumePairList", "number_assets": 6, "sort_key": "quoteVolume"},
|
||||||
{"method": "PrecisionFilter"},
|
{"method": "PrecisionFilter"},
|
||||||
@ -221,7 +225,9 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t
|
|||||||
assert log_has_re(r'^Removed .* from whitelist, because stop price .* '
|
assert log_has_re(r'^Removed .* from whitelist, because stop price .* '
|
||||||
r'would be <= stop limit.*', caplog)
|
r'would be <= stop limit.*', caplog)
|
||||||
if pairlist['method'] == 'PriceFilter':
|
if pairlist['method'] == 'PriceFilter':
|
||||||
assert log_has_re(r'^Removed .* from whitelist, because 1 unit is .*%$', caplog)
|
assert (log_has_re(r'^Removed .* from whitelist, because 1 unit is .*%$', caplog) or
|
||||||
|
log_has_re(r"^Removed .* from whitelist, because ticker\['last'\] is empty.*",
|
||||||
|
caplog))
|
||||||
|
|
||||||
|
|
||||||
def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None:
|
def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user