Repository: freqtrade/freqtrade

Issue:
Bittrex is not working for PriceFilter
## Describe your environment

  * Operating system: Ubuntu Server
  * Python Version: 3.8.2 (`python -V`)
  * CCXT version: 1.30.48 (`pip freeze | grep ccxt`)
  * Freqtrade Version: 2020.6 (`freqtrade -V` or `docker-compose run --rm freqtrade -V` for Freqtrade running in docker)
  
Note: All issues other than enhancement requests will be closed without further comment if the above template is deleted or not filled out.

## Describe the problem:

I have the following config file:

```
{
  "max_open_trades": 10,
  "stake_currency": "USDT",
  "stake_amount": "unlimited",
  "amend_last_stake_amount": true,
  "tradable_balance_ratio": 0.99,
  "fiat_display_currency": "USD",
  "dry_run": true,
  "dry_run_wallet": 200,
  "unfilledtimeout": {
    "buy": 10,
    "sell": 30
  },
  "order_types": {
    "buy": "limit",
    "sell": "limit",
    "stoploss": "limit",
    "stoploss_on_exchange": false,
    "stoploss_on_exchange_interval": 60
  },
  "bid_strategy": {
    "ask_last_balance": 0.0,
    "use_order_book": false,
    "order_book_top": 1,
    "check_depth_of_market": {
      "enabled": false,
      "bids_to_ask_delta": 1
    }
  },
  "ask_strategy": {
    "use_order_book": false,
    "order_book_min": 1,
    "order_book_max": 9,
    "use_sell_signal": true,
    "sell_profit_only": false,
    "ignore_roi_if_buy_signal": false
  },
  "exchange": {
    "name": "bittrex",
    "key": "",
    "secret": "",
    "ccxt_config": {
      "enableRateLimit": true
    },
    "ccxt_async_config": {
      "enableRateLimit": true,
      "rateLimit": 500
    },
    "pair_blacklist": [
      "BUSD/USDT",
      "TUSD/USDT",
      "USDC/USDT",
      "PAX/USDT",
      "BKRW/USDT",
      "EUR/USDT",
      "IDRT/USDT",
      "NGN/USDT",
      "RUB/USDT",
      "TRY/USDT",
      "ZAR/USDT"
    ]
  },
  "pairlists": [
    {
        "method": "VolumePairList",
        "number_assets": 200,
        "sort_key": "quoteVolume",
        "refresh_period": 1800
    },
    {"method": "PrecisionFilter"},
    {"method": "PriceFilter", "low_price_ratio": 0.02},
    {"method": "SpreadFilter", "max_spread_ratio": 0.01},
    {"method": "ShuffleFilter", "seed": 42},
    {"method": "AgeFilter", "min_days_listed": 20}

  ],
  "edge": {
    "enabled": false,
    "process_throttle_secs": 3600,
    "calculate_since_number_of_days": 7,
    "allowed_risk": 0.01,
    "stoploss_range_min": -0.01,
    "stoploss_range_max": -0.1,
    "stoploss_range_step": -0.01,
    "minimum_winrate": 0.60,
    "minimum_expectancy": 0.20,
    "min_trade_number": 10,
    "max_trade_duration_minute": 1440,
    "remove_pumps": false
  },
 "telegram": {
   "enabled": true,
   "token": "",
   "chat_id": ""
 },
  "initial_state": "running",
  "forcebuy_enable": false,
  "internals": {
    "process_throttle_secs": 5
  }
}
```

If I'm trying to run this configuration with **Bittrex** as exchanger I'm going to receive the following error.

```
2020-07-21 01:27:44,324 - freqtrade.commands.trade_commands - ERROR - float division by zero
2020-07-21 01:27:44,324 - freqtrade.commands.trade_commands - ERROR - Fatal exception!
Traceback (most recent call last):
  File "/home/vlad/freqtrade/freqtrade/commands/trade_commands.py", line 19, in start_trading
    worker = Worker(args)
  File "/home/vlad/freqtrade/freqtrade/worker.py", line 34, in __init__
    self._init(False)
  File "/home/vlad/freqtrade/freqtrade/worker.py", line 51, in _init
    self.freqtrade = FreqtradeBot(self._config)
  File "/home/vlad/freqtrade/freqtrade/freqtradebot.py", line 87, in __init__
    self.active_pair_whitelist = self._refresh_active_whitelist()
  File "/home/vlad/freqtrade/freqtrade/freqtradebot.py", line 184, in _refresh_active_whitelist
    self.pairlists.refresh_pairlist()
  File "/home/vlad/freqtrade/freqtrade/pairlist/pairlistmanager.py", line 95, in refresh_pairlist
    pairlist = pairlist_handler.filter_pairlist(pairlist, tickers)
  File "/home/vlad/freqtrade/freqtrade/pairlist/IPairList.py", line 131, in filter_pairlist
    if not self._validate_pair(tickers[p]):
  File "/home/vlad/freqtrade/freqtrade/pairlist/PriceFilter.py", line 50, in _validate_pair
    changeperc = compare / ticker['last']
ZeroDivisionError: float division by zero
```


The interesting part is that if I'm running the same configuration but on **Binance** instead of **Bittrex** everything is going to work properly as expected. Just on **Bittrex** so far I'm getting this error message.


Discussion:
i wonder which pair causes this - it's obviously a pair that didn't have a trade yet...

i assume it's a new pair (most likely with (almost) no volume so far) - and no trade in the last 24h.

maybe try lowering the amount of VolumePairlist - i don't think bittrex has 200 pairs of the same stake currency ... 
I've tried to lower the number of pairs by more than half, and now it stays at 75 where it's working. But I've obtained a new error now.

```
Traceback (most recent call last):
  File "/home/vlad/freqtrade/freqtrade/commands/trade_commands.py", line 19, in start_trading
    worker = Worker(args)
  File "/home/vlad/freqtrade/freqtrade/worker.py", line 34, in __init__
    self._init(False)
  File "/home/vlad/freqtrade/freqtrade/worker.py", line 51, in _init
    self.freqtrade = FreqtradeBot(self._config)
  File "/home/vlad/freqtrade/freqtrade/freqtradebot.py", line 87, in __init__
    self.active_pair_whitelist = self._refresh_active_whitelist()
  File "/home/vlad/freqtrade/freqtrade/freqtradebot.py", line 184, in _refresh_active_whitelist
    self.pairlists.refresh_pairlist()
  File "/home/vlad/freqtrade/freqtrade/pairlist/pairlistmanager.py", line 95, in refresh_pairlist
    pairlist = pairlist_handler.filter_pairlist(pairlist, tickers)
  File "/home/vlad/freqtrade/freqtrade/pairlist/IPairList.py", line 131, in filter_pairlist
    if not self._validate_pair(tickers[p]):
  File "/home/vlad/freqtrade/freqtrade/pairlist/AgeFilter.py", line 60, in _validate_pair
    daily_candles = self._exchange.get_historic_ohlcv(pair=ticker['symbol'],
  File "/home/vlad/freqtrade/freqtrade/exchange/exchange.py", line 653, in get_historic_ohlcv
    return asyncio.get_event_loop().run_until_complete(
  File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/home/vlad/freqtrade/freqtrade/exchange/exchange.py", line 675, in _async_get_historic_ohlcv
    for p, timeframe, res in results:
TypeError: cannot unpack non-iterable TemporaryError object
```

What's should be the reason for this one?
I ran into this error first: https://github.com/ccxt/ccxt/issues/7317

Looking at it, it seems like bittrex just changed their API in a breaking way without any grace period.

Personally, these constant issues with Bittrex (in combination with the constant low volume on most pairs) had me give up on bittrex and move to kraken / binance.
I see... well thx for the help :D , and in this case, I'm going to check Kraken in comparison with Binance.

Resolving patch:
diff --git a/freqtrade/pairlist/PriceFilter.py b/freqtrade/pairlist/PriceFilter.py
--- a/freqtrade/pairlist/PriceFilter.py
+++ b/freqtrade/pairlist/PriceFilter.py
@@ -56,7 +56,7 @@ def _validate_pair(self, ticker) -> bool:
         :param ticker: ticker dict as returned from ccxt.load_markets()
         :return: True if the pair can stay, false if it should be removed
         """
-        if ticker['last'] is None:
+        if ticker['last'] is None or ticker['last'] == 0:
             self.log_on_refresh(logger.info,
                                 f"Removed {ticker['symbol']} from whitelist, because "
                                 "ticker['last'] is empty (Usually no trade in the last 24h).")


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -661,7 +661,8 @@ def shitcoinmarkets(markets):
     Fixture with shitcoin markets - used to test filters in pairlists
     """
     shitmarkets = deepcopy(markets)
-    shitmarkets.update({'HOT/BTC': {
+    shitmarkets.update({
+        'HOT/BTC': {
             'id': 'HOTBTC',
             'symbol': 'HOT/BTC',
             'base': 'HOT',
@@ -766,7 +767,32 @@ def shitcoinmarkets(markets):
             "spot": True,
             "future": False,
             "active": True
-    },
+        },
+        'ADADOUBLE/USDT': {
+            "percentage": True,
+            "tierBased": False,
+            "taker": 0.001,
+            "maker": 0.001,
+            "precision": {
+                "base": 8,
+                "quote": 8,
+                "amount": 2,
+                "price": 4
+            },
+            "limits": {
+            },
+            "id": "ADADOUBLEUSDT",
+            "symbol": "ADADOUBLE/USDT",
+            "base": "ADADOUBLE",
+            "quote": "USDT",
+            "baseId": "ADADOUBLE",
+            "quoteId": "USDT",
+            "info": {},
+            "type": "spot",
+            "spot": True,
+            "future": False,
+            "active": True
+        },
         })
     return shitmarkets
 
@@ -1388,6 +1414,28 @@ def tickers():
             "quoteVolume": 0.0,
             "info": {}
         },
+        "ADADOUBLE/USDT": {
+            "symbol": "ADADOUBLE/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": 0,
+            "previousClose": None,
+            "change": None,
+            "percentage": 2.628,
+            "average": None,
+            "baseVolume": 0.0,
+            "quoteVolume": 0.0,
+            "info": {}
+        },
     })
 
 
diff --git a/tests/pairlist/test_pairlist.py b/tests/pairlist/test_pairlist.py
--- a/tests/pairlist/test_pairlist.py
+++ b/tests/pairlist/test_pairlist.py
@@ -235,7 +235,7 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
     ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "bidVolume"}],
      "BTC",  ['HOT/BTC', 'FUEL/BTC', 'XRP/BTC', 'LTC/BTC', 'TKN/BTC']),
     ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}],
-     "USDT", ['ETH/USDT', 'NANO/USDT', 'ADAHALF/USDT']),
+     "USDT", ['ETH/USDT', 'NANO/USDT', 'ADAHALF/USDT', 'ADADOUBLE/USDT']),
     # No pair for ETH, VolumePairList
     ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"}],
      "ETH", []),
@@ -303,11 +303,11 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
     # ShuffleFilter
     ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"},
       {"method": "ShuffleFilter", "seed": 77}],
-     "USDT", ['ETH/USDT', 'ADAHALF/USDT', 'NANO/USDT']),
+     "USDT", ['ADADOUBLE/USDT', 'ETH/USDT', 'NANO/USDT', 'ADAHALF/USDT']),
     # ShuffleFilter, other seed
     ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"},
       {"method": "ShuffleFilter", "seed": 42}],
-     "USDT", ['NANO/USDT', 'ETH/USDT', 'ADAHALF/USDT']),
+     "USDT", ['ADAHALF/USDT', 'NANO/USDT', 'ADADOUBLE/USDT', 'ETH/USDT']),
     # ShuffleFilter, no seed
     ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "quoteVolume"},
       {"method": "ShuffleFilter"}],
@@ -347,6 +347,9 @@ def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
     ([{"method": "VolumePairList", "number_assets": 5, "sort_key": "bidVolume"},
       {"method": "StaticPairList"}],
      "BTC", 'static_in_the_middle'),
+    ([{"method": "VolumePairList", "number_assets": 20, "sort_key": "quoteVolume"},
+      {"method": "PriceFilter", "low_price_ratio": 0.02}],
+        "USDT", ['ETH/USDT', 'NANO/USDT']),
 ])
 def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, tickers,
                                       ohlcv_history_list, pairlists, base_currency,