from freqtrade.strategy.interface import IStrategy from pandas import DataFrame # -------------------------------- import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib import numpy as np # noqa def activate(x): return np.tanh(x) # tanh params = { '0-0-0-w': -0.53814, '0-0-bias': -0.96407, '1-0-0-w': -0.49249, '10-0-0-w': 0.08845, '11-0-0-w': -0.14317, '12-0-0-w': 0.00923, '13-0-0-w': 0.30464, '14-0-0-w': -0.35835, '15-0-0-w': -0.49712, '16-0-0-w': 0.76135, '17-0-0-w': -0.75257, '18-0-0-w': -0.04622, '19-0-0-w': 0.10012, '2-0-0-w': -0.23534, '20-0-0-w': -0.04553, '21-0-0-w': -0.35334, '22-0-0-w': 0.17952, '23-0-0-w': 0.44446, '24-0-0-w': -0.15875, '25-0-0-w': 0.97565, '26-0-0-w': -0.89948, '27-0-0-w': 0.61777, '28-0-0-w': -0.60204, '29-0-0-w': -0.85229, '3-0-0-w': 0.47262, '30-0-0-w': -0.52791, '31-0-0-w': 0.98494, '4-0-0-w': -0.54942, '5-0-0-w': 0.40523, '6-0-0-w': 0.4723, '7-0-0-w': 0.63297, '8-0-0-w': 0.07159, '9-0-0-w': -0.86791, 'adx-bias': -0.48719, 'ao-bias': -0.87518, 'aroonosc-bias': -0.56096, 'bb_percent-bias': -0.98703, 'bb_width-bias': -0.73742, 'cci-bias': 0.47039, 'end-0-w': -0.81658, 'end-bias': 0.74656, 'fastd-bias': -0.2793, 'fisher_rsi_norm-bias': -0.36065, 'kc_percent-bias': 0.76707, 'kc_width-bias': 0.5489, 'macd-bias': 0.55448, 'macdhist-bias': -0.83133, 'macdsignal-bias': 0.30828, 'mfi-bias': -0.13097, 'roc-bias': -0.78885, 'rsi-bias': 0.9856, 'sar-bias': 0.43812, 'sma10-bias': -0.39019, 'sma100-bias': 0.03558, 'sma21-bias': 0.07457, 'sma3-bias': 0.93633, 'sma5-bias': -0.93329, 'sma50-bias': -0.60637, 'tema10-bias': -0.45946, 'tema100-bias': 0.1662, 'tema21-bias': 0.68466, 'tema3-bias': 0.25368, 'tema5-bias': -0.88818, 'tema50-bias': 0.3019, 'uo-bias': 0.71019, 'wbb_percent-bias': -0.55964, 'wbb_width-bias': 0.23523, 's-0-0-0-w': 0.85409, 's-0-0-bias': -0.04613, 's-1-0-0-w': -0.14997, 's-10-0-0-w': -0.67008, 's-11-0-0-w': -0.40221, 's-12-0-0-w': 0.64553, 's-13-0-0-w': 0.22838, 's-14-0-0-w': 0.99977, 's-15-0-0-w': 0.89363, 's-16-0-0-w': -0.88212, 's-17-0-0-w': -0.71813, 's-18-0-0-w': 0.41602, 's-19-0-0-w': -0.48389, 's-2-0-0-w': 0.09649, 's-20-0-0-w': 0.64273, 's-21-0-0-w': -0.31671, 's-22-0-0-w': 0.9663, 's-23-0-0-w': 0.00229, 's-24-0-0-w': 0.96244, 's-25-0-0-w': -0.24513, 's-26-0-0-w': 0.52312, 's-27-0-0-w': 0.44742, 's-28-0-0-w': -0.03916, 's-29-0-0-w': 0.88882, 's-3-0-0-w': -0.32112, 's-30-0-0-w': -0.70886, 's-31-0-0-w': -0.42672, 's-4-0-0-w': -0.55265, 's-5-0-0-w': 0.56105, 's-6-0-0-w': 0.47436, 's-7-0-0-w': 0.58136, 's-8-0-0-w': -0.48308, 's-9-0-0-w': -0.16024, 's-adx-bias': -0.4091, 's-ao-bias': 0.76889, 's-aroonosc-bias': 0.16228, 's-bb_percent-bias': 0.19407, 's-bb_width-bias': 0.11795, 's-cci-bias': 0.8379, 's-end-0-w': -0.14648, 's-end-bias': -0.85697, 's-fastd-bias': -0.00581, 's-fisher_rsi_norm-bias': -0.05253, 's-kc_percent-bias': -0.3562, 's-kc_width-bias': 0.67451, 's-macd-bias': -0.17742, 's-macdhist-bias': -0.58328, 's-macdsignal-bias': -0.79847, 's-mfi-bias': -0.48236, 's-roc-bias': -0.5914, 's-rsi-bias': -0.9618, 's-sar-bias': 0.57033, 's-sma10-bias': 0.14349, 's-sma100-bias': 0.02401, 's-sma21-bias': 0.78191, 's-sma3-bias': 0.72279, 's-sma5-bias': -0.19383, 's-sma50-bias': 0.63697, 's-tema10-bias': 0.96837, 's-tema100-bias': 0.77171, 's-tema21-bias': 0.67279, 's-tema3-bias': -0.24583, 's-tema5-bias': -0.08997, 's-tema50-bias': 0.65532, 's-uo-bias': 0.67701, 's-wbb_percent-bias': -0.658, 's-wbb_width-bias': -0.71056 } network_shape = [1] class Genetic(IStrategy): # ROI table: minimal_roi = { "0": 0.21029, "11": 0.05876, "57": 0.02191, "281": 0 } # Stoploss: stoploss = -1 # Optimal ticker interval for the strategy ticker_interval = '2h' # Trailing stop: trailing_only_offset_is_reached = False trailing_stop = True trailing_stop_positive = 0.01019 trailing_stop_positive_offset = 0.01164 # run "populate_indicators" only for new candle process_only_new_candles = True # Experimental settings (configuration will overide these if set) use_sell_signal = True sell_profit_only = True ignore_roi_if_buy_signal = True startup_candle_count = 100 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. """ # Momentum Indicators # ------------------------------------ # ADX dataframe['adx'] = ta.ADX(dataframe) / 100 # # 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) / 100 # # Awesome Oscillator dataframe['ao'] = ((qtpylib.awesome_oscillator(dataframe) > 0).astype(int) - 0.5) * 2 # # 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) / 100 # # Commodity Channel Index: values [Oversold:-100, Overbought:100] dataframe['cci'] = ta.CCI(dataframe) / 200 # RSI dataframe['rsi'] = ta.RSI(dataframe) / 100 # # Inverse Fisher transform on RSI: values [-1.0, 1.0] (https://goo.gl/2JGGoy) rsi = 0.1 * (dataframe['rsi'] * 100 - 50) 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_norm'] = 50 * (fisher_rsi + 1) / 100 # # 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'] / 100 # # 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) / 100 # # ROC dataframe['roc'] = ta.ROC(dataframe) / 100 # 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"] ) # # SMA - Simple Moving Average dataframe['sma3'] = dataframe['close'] / ta.SMA(dataframe, timeperiod=3) - 1 dataframe['sma5'] = dataframe['close'] / ta.SMA(dataframe, timeperiod=5) - 1 dataframe['sma10'] = dataframe['close'] / ta.SMA(dataframe, timeperiod=10) - 1 dataframe['sma21'] = dataframe['close'] / ta.SMA(dataframe, timeperiod=21) - 1 dataframe['sma50'] = dataframe['close'] / ta.SMA(dataframe, timeperiod=50) - 1 dataframe['sma100'] = dataframe['close'] / ta.SMA(dataframe, timeperiod=100) - 1 # Parabolic SAR dataframe['sar'] = dataframe['close'] / ta.SAR(dataframe) - 1 # TEMA - Triple Exponential Moving Average dataframe['tema3'] = dataframe['close'] / ta.TEMA(dataframe, timeperiod=3) - 1 dataframe['tema5'] = dataframe['close'] / ta.TEMA(dataframe, timeperiod=5) - 1 dataframe['tema10'] = dataframe['close'] / ta.TEMA(dataframe, timeperiod=10) - 1 dataframe['tema21'] = dataframe['close'] / ta.TEMA(dataframe, timeperiod=21) - 1 dataframe['tema50'] = dataframe['close'] / ta.TEMA(dataframe, timeperiod=50) - 1 dataframe['tema100'] = dataframe['close'] / ta.TEMA(dataframe, timeperiod=100) - 1 return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Based on TA indicators, populates the buy signal for the given dataframe :param dataframe: DataFrame :return: DataFrame with buy column """ indicators = ['aroonosc', 'ao', 'uo', 'cci', 'rsi', 'fisher_rsi_norm', 'sar', 'sma3', 'sma5', 'sma10', 'sma21', 'sma50', 'sma100', 'tema3', 'tema5', 'tema10', 'tema21', 'tema50', 'tema100', 'fastd', 'adx', 'bb_percent', 'bb_width', 'macd', 'macdsignal', 'macdhist', 'mfi', 'wbb_percent', 'wbb_width', 'roc', 'kc_percent', 'kc_width'] inputs = [] for indicator in indicators: inputs.append(dataframe[indicator] + params[indicator + '-bias']) for index, layer_size in enumerate(network_shape): outputs = [] for n in range(layer_size): weight = 0 for i, input in enumerate(inputs): weight += params['{}-{}-{}-w'.format(i, index, n)] * input weight += params['{}-{}-bias'.format(index, n)] outputs.append(activate(weight)) inputs = outputs weight = 0 for i, input in enumerate(inputs): weight += params['end-{}-w'.format(i)] * input weight += params['end-bias'] dataframe.loc[activate(weight) > 0, 'buy'] = 1 # Check that the candle had volume dataframe.loc[dataframe['volume'] <= 0, 'buy'] = 0 return dataframe def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: return dataframe