# Buggy code
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    """
    Adds several different TA indicators to the given DataFrame

    Performance Note: For the best performance be frugal on the number of indicators
    you are using. Let uncomment only the indicator you are using in your strategies
    or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
    :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
    :param metadata: Additional information, like the currently traded pair
    :return: a Dataframe with all mandatory indicators for the strategies
    """

    # Momentum Indicators
    # ------------------------------------

    # RSI
    dataframe["rsi"] = ta.RSI(dataframe)

    # ADX
    dataframe["adx"] = ta.ADX(dataframe)

    # # Aroon, Aroon Oscillator
    # aroon = ta.AROON(dataframe)
    # dataframe['aroonup'] = aroon['aroonup']
    # dataframe['aroondown'] = aroon['aroondown']
    # dataframe['aroonosc'] = ta.AROONOSC(dataframe)

    # # Awesome oscillator
    # dataframe['ao'] = qtpylib.awesome_oscillator(dataframe)

    # # Commodity Channel Index: values Oversold:<-100, Overbought:>100
    # dataframe['cci'] = ta.CCI(dataframe)

    # MACD
    macd = ta.MACD(dataframe)
    dataframe["macd"] = macd["macd"]
    dataframe["macdsignal"] = macd["macdsignal"]
    dataframe["macdhist"] = macd["macdhist"]

    # MFI
    dataframe["mfi"] = ta.MFI(dataframe)

    # # Minus Directional Indicator / Movement
    # dataframe['minus_dm'] = ta.MINUS_DM(dataframe)
    # dataframe['minus_di'] = ta.MINUS_DI(dataframe)

    # # Plus Directional Indicator / Movement
    # dataframe['plus_dm'] = ta.PLUS_DM(dataframe)
    # dataframe['plus_di'] = ta.PLUS_DI(dataframe)
    # dataframe['minus_di'] = ta.MINUS_DI(dataframe)

    # # ROC
    # dataframe['roc'] = ta.ROC(dataframe)

    # # Inverse Fisher transform on RSI, values [-1.0, 1.0] (https://goo.gl/2JGGoy)
    # rsi = 0.1 * (dataframe['rsi'] - 50)
    # dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1)

    # # Inverse Fisher transform on RSI normalized, value [0.0, 100.0] (https://goo.gl/2JGGoy)
    # dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1)

    # # Stoch
    # stoch = ta.STOCH(dataframe)
    # dataframe['slowd'] = stoch['slowd']
    # dataframe['slowk'] = stoch['slowk']

    # Stoch fast
    stoch_fast = ta.STOCHF(dataframe)
    dataframe["fastd"] = stoch_fast["fastd"]
    dataframe["fastk"] = stoch_fast["fastk"]

    # # Stoch RSI
    # stoch_rsi = ta.STOCHRSI(dataframe)
    # dataframe['fastd_rsi'] = stoch_rsi['fastd']
    # dataframe['fastk_rsi'] = stoch_rsi['fastk']

    # Overlap Studies
    # ------------------------------------

    # Bollinger bands
    bollinger = qtpylib.bollinger_bands(
        qtpylib.typical_price(dataframe), window=20, stds=2
    )
    dataframe["bb_lowerband"] = bollinger["lower"]
    dataframe["bb_middleband"] = bollinger["mid"]
    dataframe["bb_upperband"] = bollinger["upper"]

    # # EMA - Exponential Moving Average
    # dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3)
    # dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5)
    # dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10)
    # dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
    # dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)

    # # SMA - Simple Moving Average
    # dataframe['sma'] = ta.SMA(dataframe, timeperiod=40)

    # SAR Parabol
    dataframe["sar"] = ta.SAR(dataframe)

    # TEMA - Triple Exponential Moving Average
    dataframe["tema"] = ta.TEMA(dataframe, timeperiod=9)

    # Cycle Indicator
    # ------------------------------------
    # Hilbert Transform Indicator - SineWave
    hilbert = ta.HT_SINE(dataframe)
    dataframe["htsine"] = hilbert["sine"]
    dataframe["htleadsine"] = hilbert["leadsine"]

    # Pattern Recognition - Bullish candlestick patterns
    # ------------------------------------
    # # Hammer: values [0, 100]
    # dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe)
    # # Inverted Hammer: values [0, 100]
    # dataframe['CDLINVERTEDHAMMER'] = ta.CDLINVERTEDHAMMER(dataframe)
    # # Dragonfly Doji: values [0, 100]
    # dataframe['CDLDRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe)
    # # Piercing Line: values [0, 100]
    # dataframe['CDLPIERCING'] = ta.CDLPIERCING(dataframe) # values [0, 100]
    # # Morningstar: values [0, 100]
    # dataframe['CDLMORNINGSTAR'] = ta.CDLMORNINGSTAR(dataframe) # values [0, 100]
    # # Three White Soldiers: values [0, 100]
    # dataframe['CDL3WHITESOLDIERS'] = ta.CDL3WHITESOLDIERS(dataframe) # values [0, 100]

    # Pattern Recognition - Bearish candlestick patterns
    # ------------------------------------
    # # Hanging Man: values [0, 100]
    # dataframe['CDLHANGINGMAN'] = ta.CDLHANGINGMAN(dataframe)
    # # Shooting Star: values [0, 100]
    # dataframe['CDLSHOOTINGSTAR'] = ta.CDLSHOOTINGSTAR(dataframe)
    # # Gravestone Doji: values [0, 100]
    # dataframe['CDLGRAVESTONEDOJI'] = ta.CDLGRAVESTONEDOJI(dataframe)
    # # Dark Cloud Cover: values [0, 100]
    # dataframe['CDLDARKCLOUDCOVER'] = ta.CDLDARKCLOUDCOVER(dataframe)
    # # Evening Doji Star: values [0, 100]
    # dataframe['CDLEVENINGDOJISTAR'] = ta.CDLEVENINGDOJISTAR(dataframe)
    # # Evening Star: values [0, 100]
    # dataframe['CDLEVENINGSTAR'] = ta.CDLEVENINGSTAR(dataframe)

    # Pattern Recognition - Bullish/Bearish candlestick patterns
    # ------------------------------------
    # # Three Line Strike: values [0, -100, 100]
    # dataframe['CDL3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe)
    # # Spinning Top: values [0, -100, 100]
    # dataframe['CDLSPINNINGTOP'] = ta.CDLSPINNINGTOP(dataframe) # values [0, -100, 100]
    # # Engulfing: values [0, -100, 100]
    # dataframe['CDLENGULFING'] = ta.CDLENGULFING(dataframe) # values [0, -100, 100]
    # # Harami: values [0, -100, 100]
    # dataframe['CDLHARAMI'] = ta.CDLHARAMI(dataframe) # values [0, -100, 100]
    # # Three Outside Up/Down: values [0, -100, 100]
    # dataframe['CDL3OUTSIDE'] = ta.CDL3OUTSIDE(dataframe) # values [0, -100, 100]
    # # Three Inside Up/Down: values [0, -100, 100]
    # dataframe['CDL3INSIDE'] = ta.CDL3INSIDE(dataframe) # values [0, -100, 100]

    # # Chart type
    # # ------------------------------------
    # # Heikinashi stategy
    # heikinashi = qtpylib.heikinashi(dataframe)
    # dataframe['ha_open'] = heikinashi['open']
    # dataframe['ha_close'] = heikinashi['close']
    # dataframe['ha_high'] = heikinashi['high']
    # dataframe['ha_low'] = heikinashi['low']

    # Retrieve best bid and best ask from the orderbook
    # ------------------------------------
    """
        # first check if dataprovider is available
        if self.dp:
            if self.dp.runmode in ('live', 'dry_run'):
                ob = self.dp.orderbook(metadata['pair'], 1)
                dataframe['best_bid'] = ob['bids'][0][0]
                dataframe['best_ask'] = ob['asks'][0][0]
        """

    return dataframe


# Traceback (Exception)
2020-02-20 22:47:28,025 - freqtrade - ERROR - Fatal exception!
Traceback (most recent call last):
File "/opt/tradebot/freqtrade/.env/lib/python3.7/site-packages/talib/__init__.py", line 20, in wrapper
for arg in chain(args, kwargs.values())
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/freqtrade/freqtrade/main.py", line 36, in main
return_code = args['func'](args)
File "/freqtrade/freqtrade/commands/optimize_commands.py", line 76, in start_hyperopt
hyperopt.start()
File "/freqtrade/freqtrade/optimize/hyperopt.py", line 488, in start
preprocessed = self.backtesting.strategy.tickerdata_to_dataframe(data)
File "/freqtrade/freqtrade/strategy/interface.py", line 448, in tickerdata_to_dataframe
for pair, pair_data in tickerdata.items()}
File "/freqtrade/freqtrade/strategy/interface.py", line 448, in <dictcomp>
for pair, pair_data in tickerdata.items()}
File "/freqtrade/freqtrade/strategy/interface.py", line 464, in advise_indicators
return self.populate_indicators(dataframe, metadata)
File "/freqtrade/user_data/strategies/MyDev.py", line 205, in populate_indicators
dataframe['mfi'] = ta.MFI(dataframe)
File "talib/_abstract.pxi", line 352, in talib._ta_lib.Function.__call__
File "talib/_abstract.pxi", line 383, in talib._ta_lib.Function.__call_function
File "/opt/tradebot/freqtrade/.env/lib/python3.7/site-packages/talib/__init__.py", line 24, in wrapper
return func(*args, **kwargs)
File "talib/_func.pxi", line 8454, in talib._ta_lib.MFI
Exception: volume is not double

# Fixed code
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
    """
    Adds several different TA indicators to the given DataFrame

    Performance Note: For the best performance be frugal on the number of indicators
    you are using. Let uncomment only the indicator you are using in your strategies
    or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
    :param dataframe: Raw data from the exchange and parsed by parse_ticker_dataframe()
    :param metadata: Additional information, like the currently traded pair
    :return: a Dataframe with all mandatory indicators for the strategies
    """

    # Momentum Indicators
    # ------------------------------------

    # ADX
    dataframe["adx"] = ta.ADX(dataframe)

    # # Plus Directional Indicator / Movement
    # dataframe['plus_dm'] = ta.PLUS_DM(dataframe)
    # dataframe['plus_di'] = ta.PLUS_DI(dataframe)

    # # Minus Directional Indicator / Movement
    # dataframe['minus_dm'] = ta.MINUS_DM(dataframe)
    # dataframe['minus_di'] = ta.MINUS_DI(dataframe)

    # # Aroon, Aroon Oscillator
    # aroon = ta.AROON(dataframe)
    # dataframe['aroonup'] = aroon['aroonup']
    # dataframe['aroondown'] = aroon['aroondown']
    # dataframe['aroonosc'] = ta.AROONOSC(dataframe)

    # # Awesome Oscillator
    # dataframe['ao'] = qtpylib.awesome_oscillator(dataframe)

    # # Keltner Channel
    # keltner = qtpylib.keltner_channel(dataframe)
    # dataframe["kc_upperband"] = keltner["upper"]
    # dataframe["kc_lowerband"] = keltner["lower"]
    # dataframe["kc_middleband"] = keltner["mid"]
    # dataframe["kc_percent"] = (
    #     (dataframe["close"] - dataframe["kc_lowerband"]) /
    #     (dataframe["kc_upperband"] - dataframe["kc_lowerband"])
    # )
    # dataframe["kc_width"] = (
    #     (dataframe["kc_upperband"] - dataframe["kc_lowerband"]) / dataframe["kc_middleband"]
    # )

    # # Ultimate Oscillator
    # dataframe['uo'] = ta.ULTOSC(dataframe)

    # # Commodity Channel Index: values [Oversold:-100, Overbought:100]
    # dataframe['cci'] = ta.CCI(dataframe)

    # RSI
    dataframe["rsi"] = ta.RSI(dataframe)

    # # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy)
    # rsi = 0.1 * (dataframe['rsi'] - 50)
    # dataframe['fisher_rsi'] = (np.exp(2 * rsi) - 1) / (np.exp(2 * rsi) + 1)

    # # Inverse Fisher transform on RSI normalized: values [0.0, 100.0] (https://goo.gl/2JGGoy)
    # dataframe['fisher_rsi_norma'] = 50 * (dataframe['fisher_rsi'] + 1)

    # # Stochastic Slow
    # stoch = ta.STOCH(dataframe)
    # dataframe['slowd'] = stoch['slowd']
    # dataframe['slowk'] = stoch['slowk']

    # Stochastic Fast
    stoch_fast = ta.STOCHF(dataframe)
    dataframe["fastd"] = stoch_fast["fastd"]
    dataframe["fastk"] = stoch_fast["fastk"]

    # # Stochastic RSI
    # stoch_rsi = ta.STOCHRSI(dataframe)
    # dataframe['fastd_rsi'] = stoch_rsi['fastd']
    # dataframe['fastk_rsi'] = stoch_rsi['fastk']

    # MACD
    macd = ta.MACD(dataframe)
    dataframe["macd"] = macd["macd"]
    dataframe["macdsignal"] = macd["macdsignal"]
    dataframe["macdhist"] = macd["macdhist"]

    # MFI
    dataframe["mfi"] = ta.MFI(dataframe)

    # # ROC
    # dataframe['roc'] = ta.ROC(dataframe)

    # Overlap Studies
    # ------------------------------------

    # Bollinger Bands
    bollinger = qtpylib.bollinger_bands(
        qtpylib.typical_price(dataframe), window=20, stds=2
    )
    dataframe["bb_lowerband"] = bollinger["lower"]
    dataframe["bb_middleband"] = bollinger["mid"]
    dataframe["bb_upperband"] = bollinger["upper"]
    dataframe["bb_percent"] = (dataframe["close"] - dataframe["bb_lowerband"]) / (
        dataframe["bb_upperband"] - dataframe["bb_lowerband"]
    )
    dataframe["bb_width"] = (
        dataframe["bb_upperband"] - dataframe["bb_lowerband"]
    ) / dataframe["bb_middleband"]

    # Bollinger Bands - Weighted (EMA based instead of SMA)
    # weighted_bollinger = qtpylib.weighted_bollinger_bands(
    #     qtpylib.typical_price(dataframe), window=20, stds=2
    # )
    # dataframe["wbb_upperband"] = weighted_bollinger["upper"]
    # dataframe["wbb_lowerband"] = weighted_bollinger["lower"]
    # dataframe["wbb_middleband"] = weighted_bollinger["mid"]
    # dataframe["wbb_percent"] = (
    #     (dataframe["close"] - dataframe["wbb_lowerband"]) /
    #     (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"])
    # )
    # dataframe["wbb_width"] = (
    #     (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) /
    #     dataframe["wbb_middleband"]
    # )

    # # EMA - Exponential Moving Average
    # dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3)
    # dataframe['ema5'] = ta.EMA(dataframe, timeperiod=5)
    # dataframe['ema10'] = ta.EMA(dataframe, timeperiod=10)
    # dataframe['ema21'] = ta.EMA(dataframe, timeperiod=21)
    # dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
    # dataframe['ema100'] = ta.EMA(dataframe, timeperiod=100)

    # # SMA - Simple Moving Average
    # dataframe['sma3'] = ta.SMA(dataframe, timeperiod=3)
    # dataframe['sma5'] = ta.SMA(dataframe, timeperiod=5)
    # dataframe['sma10'] = ta.SMA(dataframe, timeperiod=10)
    # dataframe['sma21'] = ta.SMA(dataframe, timeperiod=21)
    # dataframe['sma50'] = ta.SMA(dataframe, timeperiod=50)
    # dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100)

    # Parabolic SAR
    dataframe["sar"] = ta.SAR(dataframe)

    # TEMA - Triple Exponential Moving Average
    dataframe["tema"] = ta.TEMA(dataframe, timeperiod=9)

    # Cycle Indicator
    # ------------------------------------
    # Hilbert Transform Indicator - SineWave
    hilbert = ta.HT_SINE(dataframe)
    dataframe["htsine"] = hilbert["sine"]
    dataframe["htleadsine"] = hilbert["leadsine"]

    # Pattern Recognition - Bullish candlestick patterns
    # ------------------------------------
    # # Hammer: values [0, 100]
    # dataframe['CDLHAMMER'] = ta.CDLHAMMER(dataframe)
    # # Inverted Hammer: values [0, 100]
    # dataframe['CDLINVERTEDHAMMER'] = ta.CDLINVERTEDHAMMER(dataframe)
    # # Dragonfly Doji: values [0, 100]
    # dataframe['CDLDRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe)
    # # Piercing Line: values [0, 100]
    # dataframe['CDLPIERCING'] = ta.CDLPIERCING(dataframe) # values [0, 100]
    # # Morningstar: values [0, 100]
    # dataframe['CDLMORNINGSTAR'] = ta.CDLMORNINGSTAR(dataframe) # values [0, 100]
    # # Three White Soldiers: values [0, 100]
    # dataframe['CDL3WHITESOLDIERS'] = ta.CDL3WHITESOLDIERS(dataframe) # values [0, 100]

    # Pattern Recognition - Bearish candlestick patterns
    # ------------------------------------
    # # Hanging Man: values [0, 100]
    # dataframe['CDLHANGINGMAN'] = ta.CDLHANGINGMAN(dataframe)
    # # Shooting Star: values [0, 100]
    # dataframe['CDLSHOOTINGSTAR'] = ta.CDLSHOOTINGSTAR(dataframe)
    # # Gravestone Doji: values [0, 100]
    # dataframe['CDLGRAVESTONEDOJI'] = ta.CDLGRAVESTONEDOJI(dataframe)
    # # Dark Cloud Cover: values [0, 100]
    # dataframe['CDLDARKCLOUDCOVER'] = ta.CDLDARKCLOUDCOVER(dataframe)
    # # Evening Doji Star: values [0, 100]
    # dataframe['CDLEVENINGDOJISTAR'] = ta.CDLEVENINGDOJISTAR(dataframe)
    # # Evening Star: values [0, 100]
    # dataframe['CDLEVENINGSTAR'] = ta.CDLEVENINGSTAR(dataframe)

    # Pattern Recognition - Bullish/Bearish candlestick patterns
    # ------------------------------------
    # # Three Line Strike: values [0, -100, 100]
    # dataframe['CDL3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe)
    # # Spinning Top: values [0, -100, 100]
    # dataframe['CDLSPINNINGTOP'] = ta.CDLSPINNINGTOP(dataframe) # values [0, -100, 100]
    # # Engulfing: values [0, -100, 100]
    # dataframe['CDLENGULFING'] = ta.CDLENGULFING(dataframe) # values [0, -100, 100]
    # # Harami: values [0, -100, 100]
    # dataframe['CDLHARAMI'] = ta.CDLHARAMI(dataframe) # values [0, -100, 100]
    # # Three Outside Up/Down: values [0, -100, 100]
    # dataframe['CDL3OUTSIDE'] = ta.CDL3OUTSIDE(dataframe) # values [0, -100, 100]
    # # Three Inside Up/Down: values [0, -100, 100]
    # dataframe['CDL3INSIDE'] = ta.CDL3INSIDE(dataframe) # values [0, -100, 100]

    # # Chart type
    # # ------------------------------------
    # # Heikin Ashi Strategy
    # heikinashi = qtpylib.heikinashi(dataframe)
    # dataframe['ha_open'] = heikinashi['open']
    # dataframe['ha_close'] = heikinashi['close']
    # dataframe['ha_high'] = heikinashi['high']
    # dataframe['ha_low'] = heikinashi['low']

    # Retrieve best bid and best ask from the orderbook
    # ------------------------------------
    """
        # first check if dataprovider is available
        if self.dp:
            if self.dp.runmode in ('live', 'dry_run'):
                ob = self.dp.orderbook(metadata['pair'], 1)
                dataframe['best_bid'] = ob['bids'][0][0]
                dataframe['best_ask'] = ob['asks'][0][0]
        """

    return dataframe