Repository: freqtrade/freqtrade

Issue:
TypeError: object of type 'NoneType' has no len()
## Step 2: Describe your environment

  * Operating system: ____ windows 10
  * Python Version: _____ python 3
  * CCXT version: _____ (`pip freeze | grep ccxt`)
  * Branch: Master | Develop
  * Last Commit ID: _____ (`git log --format="%H" -n 1`)
  
## Step 3: Describe the problem:

when i wants to use informative pair i got this weird error but admin in slack help me to figure out what it says the log is:
```

2019-12-03 21:11:32,009 - freqtrade - ERROR - Fatal exception!
Traceback (most recent call last):
  File "c:\users\test\desktop\freqtrade-develop1\freqtrade\main.py", line 39, in main
    args['func'](args)
  File "c:\users\test\desktop\freqtrade-develop1\freqtrade\optimize\__init__.py", line 44, in start_backtesting
    backtesting.start()
  File "c:\users\test\desktop\freqtrade-develop1\freqtrade\optimize\backtesting.py", line 453, in start
    preprocessed = self.strategy.tickerdata_to_dataframe(data)
  File "c:\users\test\desktop\freqtrade-develop1\freqtrade\strategy\interface.py", line 429, in tickerdata_to_dataframe
    for pair, pair_data in tickerdata.items()}
  File "c:\users\test\desktop\freqtrade-develop1\freqtrade\strategy\interface.py", line 429, in <dictcomp>
    for pair, pair_data in tickerdata.items()}
  File "c:\users\test\desktop\freqtrade-develop1\freqtrade\strategy\interface.py", line 445, in advise_indicators
    return self.populate_indicators(dataframe, metadata)
  File "C:\Users\test\Desktop\freqtrade-develop1\freqtrade\strategy\default_strategy.py", line 71, in populate_indicators
    data = self.dp.get_pair_dataframe("BTC/USDT", ticker_interval="1h")
  File "c:\users\test\desktop\freqtrade-develop1\freqtrade\data\dataprovider.py", line 84, in get_pair_dataframe
    if len(data) == 0:
TypeError: object of type 'NoneType' has no len()
```
it just need a btc data to use that so plz change this log error


Discussion:
The only thing we can change in this case is to return None (or an empty DataFrame) instead of an error (which will be correct, anyway) - since this occurs only if no data can be found for the pair you're requesting.

This however means that the case of no data being returned must be handled by the strategy (which it should be, anyway) - otherwise the error will simply be moved from the dataprovider file to your strategy.

Resolving patch:
diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py
--- a/freqtrade/data/history.py
+++ b/freqtrade/data/history.py
@@ -146,7 +146,7 @@ def load_pair_history(pair: str,
     :param fill_up_missing: Fill missing values with "No action"-candles
     :param drop_incomplete: Drop last candle assuming it may be incomplete.
     :param startup_candles: Additional candles to load at the start of the period
-    :return: DataFrame with ohlcv data
+    :return: DataFrame with ohlcv data, or empty DataFrame
     """
 
     timerange_startup = deepcopy(timerange)
@@ -174,7 +174,7 @@ def load_pair_history(pair: str,
             f'No history data for pair: "{pair}", timeframe: {timeframe}. '
             'Use `freqtrade download-data` to download the data'
         )
-        return None
+        return DataFrame()
 
 
 def load_data(datadir: Path,
@@ -216,7 +216,7 @@ def load_data(datadir: Path,
                                  exchange=exchange,
                                  fill_up_missing=fill_up_missing,
                                  startup_candles=startup_candles)
-        if hist is not None:
+        if not hist.empty:
             result[pair] = hist
 
     if fail_without_data and not result:


Test patch:
diff --git a/tests/data/test_history.py b/tests/data/test_history.py
--- a/tests/data/test_history.py
+++ b/tests/data/test_history.py
@@ -74,8 +74,8 @@ def test_load_data_30min_ticker(mocker, caplog, default_conf, testdatadir) -> No
 
 def test_load_data_7min_ticker(mocker, caplog, default_conf, testdatadir) -> None:
     ld = history.load_pair_history(pair='UNITTEST/BTC', timeframe='7m', datadir=testdatadir)
-    assert not isinstance(ld, DataFrame)
-    assert ld is None
+    assert isinstance(ld, DataFrame)
+    assert ld.empty
     assert log_has(
         'No history data for pair: "UNITTEST/BTC", timeframe: 7m. '
         'Use `freqtrade download-data` to download the data', caplog
diff --git a/tests/optimize/test_backtesting.py b/tests/optimize/test_backtesting.py
--- a/tests/optimize/test_backtesting.py
+++ b/tests/optimize/test_backtesting.py
@@ -494,7 +494,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) ->
     def get_timeframe(input1):
         return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59)
 
-    mocker.patch('freqtrade.data.history.load_pair_history', MagicMock(return_value=None))
+    mocker.patch('freqtrade.data.history.load_pair_history', MagicMock(return_value=pd.DataFrame()))
     mocker.patch('freqtrade.data.history.get_timeframe', get_timeframe)
     mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock())
     patch_exchange(mocker)
diff --git a/tests/optimize/test_hyperopt.py b/tests/optimize/test_hyperopt.py
--- a/tests/optimize/test_hyperopt.py
+++ b/tests/optimize/test_hyperopt.py
@@ -249,7 +249,7 @@ def test_start(mocker, default_conf, caplog) -> None:
 
 def test_start_no_data(mocker, default_conf, caplog) -> None:
     patched_configuration_load_config_file(mocker, default_conf)
-    mocker.patch('freqtrade.data.history.load_pair_history', MagicMock(return_value=None))
+    mocker.patch('freqtrade.data.history.load_pair_history', MagicMock(return_value=pd.DataFrame))
     mocker.patch(
         'freqtrade.optimize.hyperopt.get_timeframe',
         MagicMock(return_value=(datetime(2017, 12, 10), datetime(2017, 12, 13)))