Repository: freqtrade/freqtrade

Issue:
Error when running the FreqAI example in the documentation
## Describe your environment

  * Operating system: `MacOS Ventura 13.2.1`
  * Python Version: `Python 3.10.10`
  * CCXT version: `ccxt==2.9.12`
  * Freqtrade Version: `freqtrade 2023.3.dev-8f29312c9`

## Describe the problem:

When running the FreqAI example on the documentation, the following error occurs: 
`AttributeError: 'LightGBMRegressor' object has no attribute 'model'`.
This also happens for `XGBoostRegressor`.

### Steps to reproduce:

  1. Run: `freqtrade backtesting --strategy FreqaiExampleStrategy --strategy-path freqtrade/templates --config config_examples/config_freqai.example.json --freqaimodel LightGBMRegressor --timerange 20220501-20220701`

### Relevant code exceptions or logs

  ```
2023-03-14 23:46:51,543 - freqtrade.strategy.hyper - INFO - No params for protection found, using default values.
2023-03-14 23:46:51,543 - freqtrade.freqai.freqai_interface - INFO - Training 9 timeranges
2023-03-14 23:46:51,544 - freqtrade.freqai.freqai_interface - INFO - Training 1INCH/USDT:USDT, 1/2 pairs from 2022-04-16 00:00:00 to 2022-05-01 00:00:00, 1/9 trains
2023-03-14 23:46:51,544 - freqtrade.freqai.data_kitchen - INFO - Could not find backtesting prediction file at /Users/antoniodellafortuna/Documents/strategies/user_data/models/uniqe-id/backtesting_predictions/cb_1inch_1651363200_prediction.feather
2023-03-14 23:46:51,545 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:51,564 - freqtrade.data.history.idatahandler - WARNING - 1INCH/USDT:USDT, futures, 3m, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:51,624 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:51,629 - freqtrade.data.history.idatahandler - WARNING - 1INCH/USDT:USDT, futures, 15m, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:51,665 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:51,668 - freqtrade.data.history.idatahandler - WARNING - 1INCH/USDT:USDT, futures, 1h, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:51,730 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:51,748 - freqtrade.data.history.idatahandler - WARNING - BTC/USDT:USDT, futures, 3m, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:51,829 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:51,968 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:51,972 - freqtrade.data.history.idatahandler - WARNING - BTC/USDT:USDT, futures, 1h, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:52,068 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:52,085 - freqtrade.data.history.idatahandler - WARNING - ETH/USDT:USDT, futures, 3m, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:52,182 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:52,187 - freqtrade.data.history.idatahandler - WARNING - ETH/USDT:USDT, futures, 15m, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:52,280 - freqtrade.data.dataprovider - INFO - Increasing startup_candle_count for freqai to 7240
2023-03-14 23:46:52,283 - freqtrade.data.history.idatahandler - WARNING - ETH/USDT:USDT, futures, 1h, data starts at 2022-05-01 00:00:00
2023-03-14 23:46:52,462 - freqtrade.freqai.freqai_interface - INFO - Could not find model at /Users/antoniodellafortuna/Documents/strategies/user_data/models/uniqe-id/sub-train-1INCH_1651363200/cb_1inch_1651363200
2023-03-14 23:46:52,463 - freqtrade.freqai.base_models.BaseRegressionModel - INFO - -------------------- Starting training 1INCH/USDT:USDT --------------------
2023-03-14 23:46:52,464 - freqtrade.freqai.data_kitchen - INFO - dropped 0 training points due to NaNs in populated dataset 0.
2023-03-14 23:46:52,464 - freqtrade.freqai.freqai_interface - WARNING - Training 1INCH/USDT:USDT raised exception ZeroDivisionError. Message: division by zero, skipping.
2023-03-14 23:46:52,464 - freqtrade.freqai.freqai_interface - INFO - Saving backtest model to disk.
2023-03-14 23:46:52,464 - freqtrade - ERROR - Fatal exception!
Traceback (most recent call last):
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/main.py", line 42, in main
    return_code = args['func'](args)
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/commands/optimize_commands.py", line 58, in start_backtesting
    backtesting.start()
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/optimize/backtesting.py", line 1348, in start
    min_date, max_date = self.backtest_one_strategy(strat, data, timerange)
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/optimize/backtesting.py", line 1250, in backtest_one_strategy
    preprocessed = self.strategy.advise_all_indicators(data)
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/strategy/interface.py", line 1321, in advise_all_indicators
    return {pair: self.advise_indicators(pair_data.copy(), {'pair': pair}).copy()
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/strategy/interface.py", line 1321, in <dictcomp>
    return {pair: self.advise_indicators(pair_data.copy(), {'pair': pair}).copy()
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/strategy/interface.py", line 1339, in advise_indicators
    return self.populate_indicators(dataframe, metadata)
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/templates/FreqaiExampleStrategy.py", line 235, in populate_indicators
    dataframe = self.freqai.start(dataframe, metadata, self)
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/freqai/freqai_interface.py", line 153, in start
    dk = self.start_backtesting(dataframe, metadata, self.dk, strategy)
  File "/Users/antoniodellafortuna/Documents/strategies/freqtrade/freqai/freqai_interface.py", line 349, in start_backtesting
    self.dd.save_data(self.model, pair, dk)
AttributeError: 'LightGBMRegressor' object has no attribute 'model'
  ```



Discussion:
the "actual" error seems to be this: `2023-03-14 23:46:52,464 - freqtrade.freqai.freqai_interface - WARNING - Training 1INCH/USDT:USDT raised exception ZeroDivisionError. Message: division by zero, skipping.
` - which will probably be caused by the data (or absence thereof) in the selected timerange.
most likely - by not enough startup data - but that's just a guess.

Now we shouldn't attribute-fail in such a case - but the actual error comes from a different place.
Yes, the error was actually that i didn't have any downloaded candles before the backtesting timerange. Thank you! :D

Resolving patch:
diff --git a/freqtrade/freqai/freqai_interface.py b/freqtrade/freqai/freqai_interface.py
--- a/freqtrade/freqai/freqai_interface.py
+++ b/freqtrade/freqai/freqai_interface.py
@@ -104,6 +104,7 @@ def __init__(self, config: Config) -> None:
         self.data_provider: Optional[DataProvider] = None
         self.max_system_threads = max(int(psutil.cpu_count() * 2 - 2), 1)
         self.can_short = True  # overridden in start() with strategy.can_short
+        self.model: Any = None
 
         record_params(config, self.full_path)
 
@@ -338,13 +339,14 @@ def start_backtesting(
                     except Exception as msg:
                         logger.warning(
                             f"Training {pair} raised exception {msg.__class__.__name__}. "
-                            f"Message: {msg}, skipping.")
+                            f"Message: {msg}, skipping.", exc_info=True)
+                        self.model = None
 
                     self.dd.pair_dict[pair]["trained_timestamp"] = int(
                         tr_train.stopts)
-                    if self.plot_features:
+                    if self.plot_features and self.model is not None:
                         plot_feature_importance(self.model, pair, dk, self.plot_features)
-                    if self.save_backtest_models:
+                    if self.save_backtest_models and self.model is not None:
                         logger.info('Saving backtest model to disk.')
                         self.dd.save_data(self.model, pair, dk)
                     else:


Test patch: