from datetime import datetime, timedelta, timezone from functools import reduce from typing import List, Dict import freqtrade.vendor.qtpylib.indicators as qtpylib import numpy as np import pandas as pd import pandas_ta as pta import talib.abstract as ta import technical.indicators as ftt from freqtrade.persistence import Trade, PairLocks from freqtrade.strategy import (BooleanParameter, DecimalParameter, IntParameter, merge_informative_pair) from freqtrade.strategy.interface import IStrategy from pandas import DataFrame, Series from skopt.space import Dimension, Integer import logging import time import math logger = logging.getLogger(__name__) def bollinger_bands(stock_price, window_size, num_of_std): rolling_mean = stock_price.rolling(window=window_size).mean() rolling_std = stock_price.rolling(window=window_size).std() lower_band = rolling_mean - (rolling_std * num_of_std) return np.nan_to_num(rolling_mean), np.nan_to_num(lower_band) def ha_typical_price(bars): res = (bars['ha_high'] + bars['ha_low'] + bars['ha_close']) / 3. return Series(index=bars.index, data=res) class ClucHAnix_BB_RPB(IStrategy): class HyperOpt: @staticmethod def generate_roi_table(params: dict): """ Generate the ROI table that will be used by Hyperopt This implementation generates the default legacy Freqtrade ROI tables. Change it if you need different number of steps in the generated ROI tables or other structure of the ROI tables. Please keep it aligned with parameters in the 'roi' optimization hyperspace defined by the roi_space method. """ roi_table = {} roi_table[0] = 0.05 roi_table[params['roi_t6']] = 0.04 roi_table[params['roi_t5']] = 0.03 roi_table[params['roi_t4']] = 0.02 roi_table[params['roi_t3']] = 0.01 roi_table[params['roi_t2']] = 0.0001 roi_table[params['roi_t1']] = -10 return roi_table @staticmethod def roi_space() -> List[Dimension]: """ Values to search for each ROI steps Override it if you need some different ranges for the parameters in the 'roi' optimization hyperspace. Please keep it aligned with the implementation of the generate_roi_table method. """ return [ Integer(240, 720, name='roi_t1'), Integer(120, 240, name='roi_t2'), Integer(90, 120, name='roi_t3'), Integer(60, 90, name='roi_t4'), Integer(30, 60, name='roi_t5'), Integer(1, 30, name='roi_t6'), ] # Buy hyperspace params: buy_params = { "buy_btc_safe_1d": -0.05, "antipump_threshold": 0.25, "clucha_bbdelta_close": 0.02206, "clucha_bbdelta_tail": 1.02515, "clucha_close_bblower": 0.03669, "clucha_closedelta_close": 0.04401, "clucha_enabled": True, "clucha_rocr_1h": 0.47782, "cofi_adx": 45, "cofi_ema": 1.329, "cofi_enabled": True, "cofi_ewo_high": 1.768, "cofi_fastd": 18, "cofi_fastk": 25, "ewo_1_enabled": False, "ewo_1_rsi_14": 55, "ewo_1_rsi_4": 12, "ewo_candles_buy": 29, "ewo_candles_sell": 15, "ewo_high": 2.119, "ewo_high_offset": 1.26902, "ewo_low": -16.218, "ewo_low_enabled": False, "ewo_low_offset": 0.99959, "ewo_low_rsi_4": 15, "lambo1_ema_14_factor": 0.981, "lambo1_enabled": True, "lambo1_rsi_14_limit": 52, "lambo1_rsi_4_limit": 37, "lambo2_ema_14_factor": 0.844, "lambo2_enabled": False, "lambo2_rsi_14_limit": 37, "lambo2_rsi_4_limit": 60, "local_trend_bb_factor": 1.03, "local_trend_closedelta": 25.831, "local_trend_ema_diff": 0.047, "local_trend_enabled": False, "nfi32_cti_limit": -0.27048, "nfi32_enabled": True, "nfi32_rsi_14": 75, "nfi32_rsi_4": 84, "nfi32_sma_factor": 0.7871, } # ROI table: minimal_roi = { "0": 100 } # Stoploss: stoploss = -1 # use custom stoploss # Trailing stop: trailing_stop = False trailing_stop_positive = 0.3207 trailing_stop_positive_offset = 0.3849 trailing_only_offset_is_reached = False """ END HYPEROPT """ timeframe = '1m' # Make sure these match or are not overridden in config use_sell_signal = False sell_profit_only = False ignore_roi_if_buy_signal = False # Custom stoploss use_custom_stoploss = True process_only_new_candles = True startup_candle_count = 200 order_types = { 'buy': 'market', 'sell': 'market', 'emergencysell': 'market', 'forcebuy': "market", 'forcesell': 'market', 'stoploss': 'market', 'stoploss_on_exchange': False, 'stoploss_on_exchange_interval': 60, 'stoploss_on_exchange_limit_ratio': 0.99 } # ClucHA clucha_bbdelta_close = DecimalParameter(0.01,0.05, default=buy_params['clucha_bbdelta_close'], decimals=5, space='buy', optimize=False) clucha_bbdelta_tail = DecimalParameter(0.7, 1.2, default=buy_params['clucha_bbdelta_tail'], decimals=5, space='buy', optimize=False) clucha_close_bblower = DecimalParameter(0.001, 0.05, default=buy_params['clucha_close_bblower'], decimals=5, space='buy', optimize=False) clucha_closedelta_close = DecimalParameter(0.001, 0.05, default=buy_params['clucha_closedelta_close'], decimals=5, space='buy', optimize=False) clucha_rocr_1h = DecimalParameter(0.1, 1.0, default=buy_params['clucha_rocr_1h'], decimals=5, space='buy', optimize=False) # lambo1 lambo1_ema_14_factor = DecimalParameter(0.8, 1.2, decimals=3, default=buy_params['lambo1_ema_14_factor'], space='buy', optimize=False) lambo1_rsi_4_limit = IntParameter(5, 60, default=buy_params['lambo1_rsi_4_limit'], space='buy', optimize=False) lambo1_rsi_14_limit = IntParameter(5, 60, default=buy_params['lambo1_rsi_14_limit'], space='buy', optimize=False) # lambo2 lambo2_ema_14_factor = DecimalParameter(0.8, 1.2, decimals=3, default=buy_params['lambo2_ema_14_factor'], space='buy', optimize=False) lambo2_rsi_4_limit = IntParameter(5, 60, default=buy_params['lambo2_rsi_4_limit'], space='buy', optimize=False) lambo2_rsi_14_limit = IntParameter(5, 60, default=buy_params['lambo2_rsi_14_limit'], space='buy', optimize=False) # local_uptrend local_trend_ema_diff = DecimalParameter(0, 0.2, default=buy_params['local_trend_ema_diff'], space='buy', optimize=False) local_trend_bb_factor = DecimalParameter(0.8, 1.2, default=buy_params['local_trend_bb_factor'], space='buy', optimize=False) local_trend_closedelta = DecimalParameter(5.0, 30.0, default=buy_params['local_trend_closedelta'], space='buy', optimize=False) # ewo_1 and ewo_low ewo_candles_buy = IntParameter(2, 30, default=buy_params['ewo_candles_buy'], space='buy', optimize=False) ewo_candles_sell = IntParameter(2, 35, default=buy_params['ewo_candles_sell'], space='buy', optimize=False) ewo_low_offset = DecimalParameter(0.7, 1.2, default=buy_params['ewo_low_offset'], decimals=5, space='buy', optimize=False) ewo_high_offset = DecimalParameter(0.75, 1.5, default=buy_params['ewo_high_offset'], decimals=5, space='buy', optimize=False) ewo_high = DecimalParameter(2.0, 15.0, default=buy_params['ewo_high'], space='buy', optimize=False) ewo_1_rsi_14 = IntParameter(10, 100, default=buy_params['ewo_1_rsi_14'], space='buy', optimize=False) ewo_1_rsi_4 = IntParameter(1, 50, default=buy_params['ewo_1_rsi_4'], space='buy', optimize=False) ewo_low_rsi_4 = IntParameter(1, 50, default=buy_params['ewo_low_rsi_4'], space='buy', optimize=False) ewo_low = DecimalParameter(-20.0, -8.0, default=buy_params['ewo_low'], space='buy', optimize=False) # cofi cofi_ema = DecimalParameter(0.6, 1.4, default=buy_params['cofi_ema'] , space='buy', optimize=False) cofi_fastk = IntParameter(1, 100, default=buy_params['cofi_fastk'], space='buy', optimize=False) cofi_fastd = IntParameter(1, 100, default=buy_params['cofi_fastd'], space='buy', optimize=False) cofi_adx = IntParameter(1, 100, default=buy_params['cofi_adx'], space='buy', optimize=False) cofi_ewo_high = DecimalParameter(1.0, 15.0, default=buy_params['cofi_ewo_high'], space='buy', optimize=False) # nfi32 nfi32_rsi_4 = IntParameter(1, 100, default=buy_params['nfi32_rsi_4'], space='buy', optimize=False) nfi32_rsi_14 = IntParameter(1, 100, default=buy_params['nfi32_rsi_4'], space='buy', optimize=False) nfi32_sma_factor = DecimalParameter(0.7, 1.2, default=buy_params['nfi32_sma_factor'], decimals=5, space='buy', optimize=False) nfi32_cti_limit = DecimalParameter(-1.2, 0, default=buy_params['nfi32_cti_limit'], decimals=5, space='buy', optimize=False) buy_btc_safe_1d = DecimalParameter(-0.5, -0.015, default=buy_params['buy_btc_safe_1d'], optimize=False) antipump_threshold = DecimalParameter(0, 0.4, default=buy_params['antipump_threshold'], space='buy', optimize=False) ewo_1_enabled = BooleanParameter(default=buy_params['ewo_1_enabled'], space='buy', optimize=False) ewo_low_enabled = BooleanParameter(default=buy_params['ewo_low_enabled'], space='buy', optimize=False) cofi_enabled = BooleanParameter(default=buy_params['cofi_enabled'], space='buy', optimize=False) lambo1_enabled = BooleanParameter(default=buy_params['lambo1_enabled'], space='buy', optimize=False) lambo2_enabled = BooleanParameter(default=buy_params['lambo2_enabled'], space='buy', optimize=False) local_trend_enabled = BooleanParameter(default=buy_params['local_trend_enabled'], space='buy', optimize=False) nfi32_enabled = BooleanParameter(default=buy_params['nfi32_enabled'], space='buy', optimize=False) clucha_enabled = BooleanParameter(default=buy_params['clucha_enabled'], space='buy', optimize=False) def informative_pairs(self): pairs = self.dp.current_whitelist() informative_pairs = [(pair, '1h') for pair in pairs] informative_pairs += [("BTC/USDT", "1m")] informative_pairs += [("BTC/USDT", "1d")] return informative_pairs ############################################################################ def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float: sl_new = 1 if (current_profit > 0.2): sl_new = 0.05 elif (current_profit > 0.1): sl_new = 0.03 elif (current_profit > 0.06): sl_new = 0.02 elif (current_profit > 0.03): sl_new = 0.015 elif (current_profit > 0.015): sl_new = 0.005 return sl_new ############################################################################ def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Heikin Ashi Candles heikinashi = qtpylib.heikinashi(dataframe) dataframe['ha_open'] = heikinashi['open'] dataframe['ha_close'] = heikinashi['close'] dataframe['ha_high'] = heikinashi['high'] dataframe['ha_low'] = heikinashi['low'] dataframe['ema_8'] = ta.EMA(dataframe, timeperiod=8) dataframe['ema_14'] = ta.EMA(dataframe, timeperiod=14) dataframe['ema_26'] = ta.EMA(dataframe, timeperiod=26) dataframe['sma_15'] = ta.SMA(dataframe, timeperiod=15) dataframe['rsi_4'] = ta.RSI(dataframe, timeperiod=4) dataframe['rsi_14'] = ta.RSI(dataframe, timeperiod=14) dataframe['rsi_20'] = ta.RSI(dataframe, timeperiod=20) # CTI dataframe['cti'] = pta.cti(dataframe["close"], length=20) # Cofi stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) dataframe['fastd'] = stoch_fast['fastd'] dataframe['fastk'] = stoch_fast['fastk'] dataframe['adx'] = ta.ADX(dataframe) # Set Up Bollinger Bands mid, lower = bollinger_bands(ha_typical_price(dataframe), window_size=40, num_of_std=2) dataframe['lower'] = lower dataframe['mid'] = mid bollinger2 = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) dataframe['bb_lowerband2'] = bollinger2['lower'] dataframe['bb_middleband2'] = bollinger2['mid'] dataframe['bb_upperband2'] = bollinger2['upper'] dataframe['closedelta'] = (dataframe['close'] - dataframe['close'].shift()).abs() # # ClucHA dataframe['bbdelta'] = (mid - dataframe['lower']).abs() dataframe['ha_closedelta'] = (dataframe['ha_close'] - dataframe['ha_close'].shift()).abs() dataframe['tail'] = (dataframe['ha_close'] - dataframe['ha_low']).abs() dataframe['bb_lowerband'] = dataframe['lower'] dataframe['ema_slow'] = ta.EMA(dataframe['ha_close'], timeperiod=50) dataframe['rocr'] = ta.ROCR(dataframe['ha_close'], timeperiod=28) # Elliot dataframe['EWO'] = EWO(dataframe, 50, 200) inf_tf = '1h' informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=inf_tf) inf_heikinashi = qtpylib.heikinashi(informative) informative['ha_close'] = inf_heikinashi['close'] informative['rocr'] = ta.ROCR(informative['ha_close'], timeperiod=168) dataframe = merge_informative_pair(dataframe, informative, self.timeframe, inf_tf, ffill=True) ### BTC protection dataframe['btc_1m']= self.dp.get_pair_dataframe('BTC/USDT', timeframe='1m')['close'] btc_1d = self.dp.get_pair_dataframe('BTC/USDT', timeframe='1d')[['date', 'close']].rename(columns={"close": "btc"}).shift(1) dataframe = merge_informative_pair(dataframe, btc_1d, '1m', '1d', ffill=True) # Pump strength dataframe['zema_30'] = ftt.zema(dataframe, period=30) dataframe['zema_200'] = ftt.zema(dataframe, period=200) dataframe['pump_strength'] = (dataframe['zema_30'] - dataframe['zema_200']) / dataframe['zema_30'] return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: conditions = [] dataframe.loc[:, 'buy_tag'] = '' dataframe[f'ma_buy_{self.ewo_candles_buy.value}'] = ta.EMA(dataframe, timeperiod=int(self.ewo_candles_buy.value)) dataframe[f'ma_sell_{self.ewo_candles_sell.value}'] = ta.EMA(dataframe, timeperiod=int(self.ewo_candles_sell.value)) is_btc_safe = ( (pct_change(dataframe['btc_1d'], dataframe['btc_1m']).fillna(0) > self.buy_btc_safe_1d.value) & (dataframe['volume'] > 0) # Make sure Volume is not 0 ) is_pump_safe = ( (dataframe['pump_strength'] < self.antipump_threshold.value) ) lambo1 = ( bool(self.lambo1_enabled.value) & (dataframe['close'] < (dataframe['ema_14'] * self.lambo1_ema_14_factor.value)) & (dataframe['rsi_4'] < int(self.lambo1_rsi_4_limit.value)) & (dataframe['rsi_14'] < int(self.lambo1_rsi_14_limit.value)) ) dataframe.loc[lambo1, 'buy_tag'] += 'lambo1_' conditions.append(lambo1) lambo2 = ( bool(self.lambo2_enabled.value) & (dataframe['close'] < (dataframe['ema_14'] * self.lambo2_ema_14_factor.value)) & (dataframe['rsi_4'] < int(self.lambo2_rsi_4_limit.value)) & (dataframe['rsi_14'] < int(self.lambo2_rsi_14_limit.value)) ) dataframe.loc[lambo2, 'buy_tag'] += 'lambo2_' conditions.append(lambo2) local_uptrend = ( bool(self.local_trend_enabled.value) & (dataframe['ema_26'] > dataframe['ema_14']) & (dataframe['ema_26'] - dataframe['ema_14'] > dataframe['open'] * self.local_trend_ema_diff.value) & (dataframe['ema_26'].shift() - dataframe['ema_14'].shift() > dataframe['open'] / 100) & (dataframe['close'] < dataframe['bb_lowerband2'] * self.local_trend_bb_factor.value) & (dataframe['closedelta'] > dataframe['close'] * self.local_trend_closedelta.value / 1000 ) ) dataframe.loc[local_uptrend, 'buy_tag'] += 'local_uptrend_' conditions.append(local_uptrend) nfi_32 = ( bool(self.nfi32_enabled.value) & (dataframe['rsi_20'] < dataframe['rsi_20'].shift(1)) & (dataframe['rsi_4'] < self.nfi32_rsi_4.value) & (dataframe['rsi_14'] > self.nfi32_rsi_14.value) & (dataframe['close'] < dataframe['sma_15'] * self.nfi32_sma_factor.value) & (dataframe['cti'] < self.nfi32_cti_limit.value) ) dataframe.loc[nfi_32, 'buy_tag'] += 'nfi_32_' conditions.append(nfi_32) ewo_1 = ( bool(self.ewo_1_enabled.value) & (dataframe['rsi_4'] < self.ewo_1_rsi_4.value) & (dataframe['close'] < (dataframe[f'ma_buy_{self.ewo_candles_buy.value}'] * self.ewo_low_offset.value)) & (dataframe['EWO'] > self.ewo_high.value) & (dataframe['rsi_14'] < self.ewo_1_rsi_14.value) & (dataframe['close'] < (dataframe[f'ma_sell_{self.ewo_candles_sell.value}'] * self.ewo_high_offset.value)) ) dataframe.loc[ewo_1, 'buy_tag'] += 'ewo1_' conditions.append(ewo_1) ewo_low = ( bool(self.ewo_low_enabled.value) & (dataframe['rsi_4'] < self.ewo_low_rsi_4.value) & (dataframe['close'] < (dataframe[f'ma_buy_{self.ewo_candles_buy.value}'] * self.ewo_low_offset.value)) & (dataframe['EWO'] < self.ewo_low.value) & (dataframe['close'] < (dataframe[f'ma_sell_{self.ewo_candles_sell.value}'] * self.ewo_high_offset.value)) ) dataframe.loc[ewo_low, 'buy_tag'] += 'ewo_low_' conditions.append(ewo_low) cofi = ( bool(self.cofi_enabled.value) & (dataframe['open'] < dataframe['ema_8'] * self.cofi_ema.value) & (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) & (dataframe['fastk'] < self.cofi_fastk.value) & (dataframe['fastd'] < self.cofi_fastd.value) & (dataframe['adx'] > self.cofi_adx.value) & (dataframe['EWO'] > self.cofi_ewo_high.value) ) dataframe.loc[cofi, 'buy_tag'] += 'cofi_' conditions.append(cofi) clucHA = ( bool(self.clucha_enabled.value) & (dataframe['rocr_1h'].gt(self.clucha_rocr_1h.value)) & (( (dataframe['lower'].shift().gt(0)) & (dataframe['bbdelta'].gt(dataframe['ha_close'] * self.clucha_bbdelta_close.value)) & (dataframe['ha_closedelta'].gt(dataframe['ha_close'] * self.clucha_closedelta_close.value)) & (dataframe['tail'].lt(dataframe['bbdelta'] * self.clucha_bbdelta_tail.value)) & (dataframe['ha_close'].lt(dataframe['lower'].shift())) & (dataframe['ha_close'].le(dataframe['ha_close'].shift())) ) | ( (dataframe['ha_close'] < dataframe['ema_slow']) & (dataframe['ha_close'] < self.clucha_close_bblower.value * dataframe['bb_lowerband']) )) ) dataframe.loc[clucHA, 'buy_tag'] += 'clucHA_' conditions.append(clucHA) dataframe.loc[ # is_btc_safe & # broken? # is_pump_safe & reduce(lambda x, y: x | y, conditions), 'buy' ] = 1 return dataframe def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # dataframe.loc[ # (dataframe['fisher'] > self.sell_fisher.value) & # (dataframe['ha_high'].le(dataframe['ha_high'].shift(1))) & # (dataframe['ha_high'].shift(1).le(dataframe['ha_high'].shift(2))) & # (dataframe['ha_close'].le(dataframe['ha_close'].shift(1))) & # (dataframe['ema_fast'] > dataframe['ha_close']) & # ((dataframe['ha_close'] * self.sell_bbmiddle_close.value) > dataframe['bb_middleband']) & # (dataframe['volume'] > 0) # , # 'sell' # ] = 1 return dataframe def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, rate: float, time_in_force: str, sell_reason: str, current_time: datetime, **kwargs) -> bool: trade.sell_reason = sell_reason + "_" + trade.buy_tag return True class ClucHAnix_BB_RPB_dca (ClucHAnix_BB_RPB): position_adjustment_enable = True initial_safety_order_trigger = -0.02 max_safety_orders = 3 safety_order_step_scale = 2 safety_order_volume_scale = 1.8 max_dca_multiplier = 7.04 # Let unlimited stakes leave funds open for DCA orders def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, proposed_stake: float, min_stake: float, max_stake: float, **kwargs) -> float: if self.config['stake_amount'] == 'unlimited': return proposed_stake / self.max_dca_multiplier # Use default stake amount. return proposed_stake def adjust_trade_position(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, **kwargs): if current_profit > self.initial_safety_order_trigger: return None count_of_buys = 0 for order in trade.orders: if order.ft_is_open or order.ft_order_side != 'buy': continue if order.status == "closed": count_of_buys += 1 if 1 <= count_of_buys <= self.max_safety_orders: safety_order_trigger = abs(self.initial_safety_order_trigger) + (abs(self.initial_safety_order_trigger) * self.safety_order_step_scale * (math.pow(self.safety_order_step_scale,(count_of_buys - 1)) - 1) / (self.safety_order_step_scale - 1)) if current_profit <= (-1 * abs(safety_order_trigger)): try: stake_amount = self.wallets.get_trade_stake_amount(pair, None) # This calculates base order size stake_amount = stake_amount / self.max_dca_multiplier # This then calculates current safety order size stake_amount = stake_amount * math.pow(self.safety_order_volume_scale,(count_of_buys - 1)) amount = stake_amount / current_rate logger.info(f"Initiating safety order buy #{count_of_buys} for {pair} with stake amount of {stake_amount} which equals {amount}") return stake_amount except Exception as exception: logger.info(f'Error occured while trying to get stake amount for {pair}: {str(exception)}') return None return None def pct_change(a, b): return (b - a) / a def EWO(dataframe, ema_length=5, ema2_length=35): df = dataframe.copy() ema1 = ta.SMA(df, timeperiod=ema_length) ema2 = ta.SMA(df, timeperiod=ema2_length) emadif = (ema1 - ema2) / df['low'] * 100 return emadif class ClucHAnix_BB_RPB_2(IStrategy): class HyperOpt: @staticmethod def generate_roi_table(params: dict): """ Generate the ROI table that will be used by Hyperopt This implementation generates the default legacy Freqtrade ROI tables. Change it if you need different number of steps in the generated ROI tables or other structure of the ROI tables. Please keep it aligned with parameters in the 'roi' optimization hyperspace defined by the roi_space method. """ roi_table = {} roi_table[0] = 0.05 roi_table[params['roi_t6']] = 0.04 roi_table[params['roi_t5']] = 0.03 roi_table[params['roi_t4']] = 0.02 roi_table[params['roi_t3']] = 0.01 roi_table[params['roi_t2']] = 0.0001 roi_table[params['roi_t1']] = -10 return roi_table @staticmethod def roi_space() -> List[Dimension]: """ Values to search for each ROI steps Override it if you need some different ranges for the parameters in the 'roi' optimization hyperspace. Please keep it aligned with the implementation of the generate_roi_table method. """ return [ Integer(240, 720, name='roi_t1'), Integer(120, 240, name='roi_t2'), Integer(90, 120, name='roi_t3'), Integer(60, 90, name='roi_t4'), Integer(30, 60, name='roi_t5'), Integer(1, 30, name='roi_t6'), ] # Buy hyperspace params: buy_params = { "buy_btc_safe_1d": -0.05, "antipump_threshold": 0.25, "clucha_bbdelta_close": 0.02206, "clucha_bbdelta_tail": 1.02515, "clucha_close_bblower": 0.03669, "clucha_closedelta_close": 0.04401, "clucha_enabled": True, "clucha_rocr_1h": 0.47782, "cofi_adx": 45, "cofi_ema": 1.329, "cofi_enabled": True, "cofi_ewo_high": 1.768, "cofi_fastd": 18, "cofi_fastk": 25, "ewo_1_enabled": False, "ewo_1_rsi_14": 55, "ewo_1_rsi_4": 12, "ewo_candles_buy": 29, "ewo_candles_sell": 15, "ewo_high": 2.119, "ewo_high_offset": 1.26902, "ewo_low": -16.218, "ewo_low_enabled": False, "ewo_low_offset": 0.99959, "ewo_low_rsi_4": 15, "lambo1_ema_14_factor": 0.981, "lambo1_enabled": True, "lambo1_rsi_14_limit": 52, "lambo1_rsi_4_limit": 37, "lambo1_rsi_14_5m_limit": 12, "lambo1_rsi_4_5m_limit": 23, "lambo2_ema_14_factor": 0.844, "lambo2_enabled": False, "lambo2_rsi_14_limit": 37, "lambo2_rsi_4_limit": 60, "local_trend_bb_factor": 1.03, "local_trend_closedelta": 25.831, "local_trend_ema_diff": 0.047, "local_trend_enabled": False, "nfi32_cti_limit": -0.27048, "nfi32_enabled": True, "nfi32_rsi_14": 75, "nfi32_rsi_4": 84, "nfi32_sma_factor": 0.7871, } # ROI table: minimal_roi = { "0": 100 } # Stoploss: stoploss = -1 # use custom stoploss # Trailing stop: trailing_stop = False trailing_stop_positive = 0.3207 trailing_stop_positive_offset = 0.3849 trailing_only_offset_is_reached = False """ END HYPEROPT """ timeframe = '1m' timeframe_5m = '5m' timeframe_1h = '1h' # Make sure these match or are not overridden in config use_sell_signal = False sell_profit_only = False ignore_roi_if_buy_signal = False # Custom stoploss use_custom_stoploss = True process_only_new_candles = True startup_candle_count = 200 order_types = { 'buy': 'market', 'sell': 'market', 'emergencysell': 'market', 'forcebuy': "market", 'forcesell': 'market', 'stoploss': 'market', 'stoploss_on_exchange': False, 'stoploss_on_exchange_interval': 60, 'stoploss_on_exchange_limit_ratio': 0.99 } # ClucHA clucha_bbdelta_close = DecimalParameter(0.01,0.05, default=buy_params['clucha_bbdelta_close'], decimals=5, space='buy', optimize=False) clucha_bbdelta_tail = DecimalParameter(0.7, 1.2, default=buy_params['clucha_bbdelta_tail'], decimals=5, space='buy', optimize=False) clucha_close_bblower = DecimalParameter(0.001, 0.05, default=buy_params['clucha_close_bblower'], decimals=5, space='buy', optimize=False) clucha_closedelta_close = DecimalParameter(0.001, 0.05, default=buy_params['clucha_closedelta_close'], decimals=5, space='buy', optimize=False) clucha_rocr_1h = DecimalParameter(0.1, 1.0, default=buy_params['clucha_rocr_1h'], decimals=5, space='buy', optimize=False) # lambo1 optimize_lambo_1_rsi_5m = True lambo1_ema_14_factor = DecimalParameter(0.8, 1.2, decimals=3, default=buy_params['lambo1_ema_14_factor'], space='buy', optimize=False) lambo1_rsi_4_limit = IntParameter(5, 60, default=buy_params['lambo1_rsi_4_limit'], space='buy', optimize=False) lambo1_rsi_14_limit = IntParameter(5, 60, default=buy_params['lambo1_rsi_14_limit'], space='buy', optimize=False) lambo1_rsi_4_5m_limit = IntParameter(5, 60, default=50, space='buy', optimize=optimize_lambo_1_rsi_5m) lambo1_rsi_14_5m_limit = IntParameter(5, 60, default=50, space='buy', optimize=optimize_lambo_1_rsi_5m) # lambo2 lambo2_ema_14_factor = DecimalParameter(0.8, 1.2, decimals=3, default=buy_params['lambo2_ema_14_factor'], space='buy', optimize=False) lambo2_rsi_4_limit = IntParameter(5, 60, default=buy_params['lambo2_rsi_4_limit'], space='buy', optimize=False) lambo2_rsi_14_limit = IntParameter(5, 60, default=buy_params['lambo2_rsi_14_limit'], space='buy', optimize=False) # local_uptrend local_trend_ema_diff = DecimalParameter(0, 0.2, default=buy_params['local_trend_ema_diff'], space='buy', optimize=False) local_trend_bb_factor = DecimalParameter(0.8, 1.2, default=buy_params['local_trend_bb_factor'], space='buy', optimize=False) local_trend_closedelta = DecimalParameter(5.0, 30.0, default=buy_params['local_trend_closedelta'], space='buy', optimize=False) # ewo_1 and ewo_low ewo_candles_buy = IntParameter(2, 30, default=buy_params['ewo_candles_buy'], space='buy', optimize=False) ewo_candles_sell = IntParameter(2, 35, default=buy_params['ewo_candles_sell'], space='buy', optimize=False) ewo_low_offset = DecimalParameter(0.7, 1.2, default=buy_params['ewo_low_offset'], decimals=5, space='buy', optimize=False) ewo_high_offset = DecimalParameter(0.75, 1.5, default=buy_params['ewo_high_offset'], decimals=5, space='buy', optimize=False) ewo_high = DecimalParameter(2.0, 15.0, default=buy_params['ewo_high'], space='buy', optimize=False) ewo_1_rsi_14 = IntParameter(10, 100, default=buy_params['ewo_1_rsi_14'], space='buy', optimize=False) ewo_1_rsi_4 = IntParameter(1, 50, default=buy_params['ewo_1_rsi_4'], space='buy', optimize=False) ewo_low_rsi_4 = IntParameter(1, 50, default=buy_params['ewo_low_rsi_4'], space='buy', optimize=False) ewo_low = DecimalParameter(-20.0, -8.0, default=buy_params['ewo_low'], space='buy', optimize=False) # cofi cofi_ema = DecimalParameter(0.6, 1.4, default=buy_params['cofi_ema'] , space='buy', optimize=False) cofi_fastk = IntParameter(1, 100, default=buy_params['cofi_fastk'], space='buy', optimize=False) cofi_fastd = IntParameter(1, 100, default=buy_params['cofi_fastd'], space='buy', optimize=False) cofi_adx = IntParameter(1, 100, default=buy_params['cofi_adx'], space='buy', optimize=False) cofi_ewo_high = DecimalParameter(1.0, 15.0, default=buy_params['cofi_ewo_high'], space='buy', optimize=False) # nfi32 nfi32_rsi_4 = IntParameter(1, 100, default=buy_params['nfi32_rsi_4'], space='buy', optimize=False) nfi32_rsi_14 = IntParameter(1, 100, default=buy_params['nfi32_rsi_4'], space='buy', optimize=False) nfi32_sma_factor = DecimalParameter(0.7, 1.2, default=buy_params['nfi32_sma_factor'], decimals=5, space='buy', optimize=False) nfi32_cti_limit = DecimalParameter(-1.2, 0, default=buy_params['nfi32_cti_limit'], decimals=5, space='buy', optimize=False) buy_btc_safe_1d = DecimalParameter(-0.5, -0.015, default=buy_params['buy_btc_safe_1d'], optimize=False) antipump_threshold = DecimalParameter(0, 0.4, default=buy_params['antipump_threshold'], space='buy', optimize=False) ewo_1_enabled = BooleanParameter(default=buy_params['ewo_1_enabled'], space='buy', optimize=False) ewo_low_enabled = BooleanParameter(default=buy_params['ewo_low_enabled'], space='buy', optimize=False) cofi_enabled = BooleanParameter(default=buy_params['cofi_enabled'], space='buy', optimize=False) lambo1_enabled = BooleanParameter(default=buy_params['lambo1_enabled'], space='buy', optimize=False) lambo2_enabled = BooleanParameter(default=buy_params['lambo2_enabled'], space='buy', optimize=False) local_trend_enabled = BooleanParameter(default=buy_params['local_trend_enabled'], space='buy', optimize=False) nfi32_enabled = BooleanParameter(default=buy_params['nfi32_enabled'], space='buy', optimize=False) clucha_enabled = BooleanParameter(default=buy_params['clucha_enabled'], space='buy', optimize=False) def informative_pairs(self): pairs = self.dp.current_whitelist() informative_pairs = [(pair, self.timeframe_1h) for pair in pairs] informative_pairs.extend([(pair, self.timeframe_5m) for pair in pairs]) informative_pairs += [("BTC/USDT", "1m")] informative_pairs += [("BTC/USDT", "1d")] return informative_pairs def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float: sl_new = 1 if (current_profit > 0.2): sl_new = 0.05 elif (current_profit > 0.1): sl_new = 0.03 elif (current_profit > 0.06): sl_new = 0.02 elif (current_profit > 0.03): sl_new = 0.015 elif (current_profit > 0.015): sl_new = 0.005 return sl_new def get_informative_indicators_5m(self, metadata: dict): informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.timeframe_5m) informative['rsi_4'] = ta.RSI(informative, timeperiod=4) informative['rsi_14'] = ta.RSI(informative, timeperiod=14) return informative def get_informative_indicators_1h(self, metadata: dict): informative_1h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.timeframe_1h) inf_heikinashi = qtpylib.heikinashi(informative_1h) informative_1h['ha_close'] = inf_heikinashi['close'] informative_1h['rocr'] = ta.ROCR(informative_1h['ha_close'], timeperiod=168) return informative_1h def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: informative_5m = self.get_informative_indicators_5m(metadata) dataframe = merge_informative_pair(dataframe, informative_5m, self.timeframe, self.timeframe_5m, ffill=True) drop_columns = [(s + "_" + self.timeframe_5m) for s in ['date', 'open', 'high', 'low', 'close', 'volume']] dataframe.drop(columns=dataframe.columns.intersection(drop_columns), inplace=True) informative_1h = self.get_informative_indicators_1h(metadata) dataframe = merge_informative_pair(dataframe, informative_1h, self.timeframe, self.timeframe_1h, ffill=True) drop_columns = [(s + "_" + self.timeframe_1h) for s in ['date', 'open', 'high', 'low', 'close', 'volume']] dataframe.drop(columns=dataframe.columns.intersection(drop_columns), inplace=True) # Heikin Ashi Candles heikinashi = qtpylib.heikinashi(dataframe) dataframe['ha_open'] = heikinashi['open'] dataframe['ha_close'] = heikinashi['close'] dataframe['ha_high'] = heikinashi['high'] dataframe['ha_low'] = heikinashi['low'] dataframe['ema_8'] = ta.EMA(dataframe, timeperiod=8) dataframe['ema_14'] = ta.EMA(dataframe, timeperiod=14) dataframe['ema_26'] = ta.EMA(dataframe, timeperiod=26) dataframe['sma_15'] = ta.SMA(dataframe, timeperiod=15) dataframe['rsi_4'] = ta.RSI(dataframe, timeperiod=4) dataframe['rsi_14'] = ta.RSI(dataframe, timeperiod=14) dataframe['rsi_20'] = ta.RSI(dataframe, timeperiod=20) # CTI dataframe['cti'] = pta.cti(dataframe["close"], length=20) # Cofi stoch_fast = ta.STOCHF(dataframe, 5, 3, 0, 3, 0) dataframe['fastd'] = stoch_fast['fastd'] dataframe['fastk'] = stoch_fast['fastk'] dataframe['adx'] = ta.ADX(dataframe) # Set Up Bollinger Bands mid, lower = bollinger_bands(ha_typical_price(dataframe), window_size=40, num_of_std=2) dataframe['lower'] = lower dataframe['mid'] = mid bollinger2 = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) dataframe['bb_lowerband2'] = bollinger2['lower'] dataframe['bb_middleband2'] = bollinger2['mid'] dataframe['bb_upperband2'] = bollinger2['upper'] dataframe['closedelta'] = (dataframe['close'] - dataframe['close'].shift()).abs() # # ClucHA dataframe['bbdelta'] = (mid - dataframe['lower']).abs() dataframe['ha_closedelta'] = (dataframe['ha_close'] - dataframe['ha_close'].shift()).abs() dataframe['tail'] = (dataframe['ha_close'] - dataframe['ha_low']).abs() dataframe['bb_lowerband'] = dataframe['lower'] dataframe['ema_slow'] = ta.EMA(dataframe['ha_close'], timeperiod=50) dataframe['rocr'] = ta.ROCR(dataframe['ha_close'], timeperiod=28) # Elliot dataframe['EWO'] = EWO(dataframe, 50, 200) return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: conditions = [] dataframe.loc[:, 'buy_tag'] = '' dataframe[f'ma_buy_{self.ewo_candles_buy.value}'] = ta.EMA(dataframe, timeperiod=int(self.ewo_candles_buy.value)) dataframe[f'ma_sell_{self.ewo_candles_sell.value}'] = ta.EMA(dataframe, timeperiod=int(self.ewo_candles_sell.value)) lambo1 = ( bool(self.lambo1_enabled.value) & (dataframe['close'] < (dataframe['ema_14'] * self.lambo1_ema_14_factor.value)) & (dataframe['rsi_4'] < int(self.lambo1_rsi_4_limit.value)) & (dataframe['rsi_14'] < int(self.lambo1_rsi_14_limit.value)) & (dataframe['rsi_4_5m'] < int(self.lambo1_rsi_4_5m_limit.value)) & (dataframe['rsi_14_5m'] < int(self.lambo1_rsi_14_5m_limit.value)) ) dataframe.loc[lambo1, 'buy_tag'] += 'lambo1_' conditions.append(lambo1) lambo2 = ( bool(self.lambo2_enabled.value) & (dataframe['close'] < (dataframe['ema_14'] * self.lambo2_ema_14_factor.value)) & (dataframe['rsi_4'] < int(self.lambo2_rsi_4_limit.value)) & (dataframe['rsi_14'] < int(self.lambo2_rsi_14_limit.value)) ) dataframe.loc[lambo2, 'buy_tag'] += 'lambo2_' conditions.append(lambo2) local_uptrend = ( bool(self.local_trend_enabled.value) & (dataframe['ema_26'] > dataframe['ema_14']) & (dataframe['ema_26'] - dataframe['ema_14'] > dataframe['open'] * self.local_trend_ema_diff.value) & (dataframe['ema_26'].shift() - dataframe['ema_14'].shift() > dataframe['open'] / 100) & (dataframe['close'] < dataframe['bb_lowerband2'] * self.local_trend_bb_factor.value) & (dataframe['closedelta'] > dataframe['close'] * self.local_trend_closedelta.value / 1000 ) ) dataframe.loc[local_uptrend, 'buy_tag'] += 'local_uptrend_' conditions.append(local_uptrend) nfi_32 = ( bool(self.nfi32_enabled.value) & (dataframe['rsi_20'] < dataframe['rsi_20'].shift(1)) & (dataframe['rsi_4'] < self.nfi32_rsi_4.value) & (dataframe['rsi_14'] > self.nfi32_rsi_14.value) & (dataframe['close'] < dataframe['sma_15'] * self.nfi32_sma_factor.value) & (dataframe['cti'] < self.nfi32_cti_limit.value) ) dataframe.loc[nfi_32, 'buy_tag'] += 'nfi_32_' conditions.append(nfi_32) ewo_1 = ( bool(self.ewo_1_enabled.value) & (dataframe['rsi_4'] < self.ewo_1_rsi_4.value) & (dataframe['close'] < (dataframe[f'ma_buy_{self.ewo_candles_buy.value}'] * self.ewo_low_offset.value)) & (dataframe['EWO'] > self.ewo_high.value) & (dataframe['rsi_14'] < self.ewo_1_rsi_14.value) & (dataframe['close'] < (dataframe[f'ma_sell_{self.ewo_candles_sell.value}'] * self.ewo_high_offset.value)) ) dataframe.loc[ewo_1, 'buy_tag'] += 'ewo1_' conditions.append(ewo_1) ewo_low = ( bool(self.ewo_low_enabled.value) & (dataframe['rsi_4'] < self.ewo_low_rsi_4.value) & (dataframe['close'] < (dataframe[f'ma_buy_{self.ewo_candles_buy.value}'] * self.ewo_low_offset.value)) & (dataframe['EWO'] < self.ewo_low.value) & (dataframe['close'] < (dataframe[f'ma_sell_{self.ewo_candles_sell.value}'] * self.ewo_high_offset.value)) ) dataframe.loc[ewo_low, 'buy_tag'] += 'ewo_low_' conditions.append(ewo_low) cofi = ( bool(self.cofi_enabled.value) & (dataframe['open'] < dataframe['ema_8'] * self.cofi_ema.value) & (qtpylib.crossed_above(dataframe['fastk'], dataframe['fastd'])) & (dataframe['fastk'] < self.cofi_fastk.value) & (dataframe['fastd'] < self.cofi_fastd.value) & (dataframe['adx'] > self.cofi_adx.value) & (dataframe['EWO'] > self.cofi_ewo_high.value) ) dataframe.loc[cofi, 'buy_tag'] += 'cofi_' conditions.append(cofi) clucHA = ( bool(self.clucha_enabled.value) & (dataframe['rocr_1h'].gt(self.clucha_rocr_1h.value)) & (( (dataframe['lower'].shift().gt(0)) & (dataframe['bbdelta'].gt(dataframe['ha_close'] * self.clucha_bbdelta_close.value)) & (dataframe['ha_closedelta'].gt(dataframe['ha_close'] * self.clucha_closedelta_close.value)) & (dataframe['tail'].lt(dataframe['bbdelta'] * self.clucha_bbdelta_tail.value)) & (dataframe['ha_close'].lt(dataframe['lower'].shift())) & (dataframe['ha_close'].le(dataframe['ha_close'].shift())) ) | ( (dataframe['ha_close'] < dataframe['ema_slow']) & (dataframe['ha_close'] < self.clucha_close_bblower.value * dataframe['bb_lowerband']) )) ) dataframe.loc[clucHA, 'buy_tag'] += 'clucHA_' conditions.append(clucHA) dataframe.loc[ reduce(lambda x, y: x | y, conditions), 'buy' ] = 1 return dataframe def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # dataframe.loc[ # (dataframe['fisher'] > self.sell_fisher.value) & # (dataframe['ha_high'].le(dataframe['ha_high'].shift(1))) & # (dataframe['ha_high'].shift(1).le(dataframe['ha_high'].shift(2))) & # (dataframe['ha_close'].le(dataframe['ha_close'].shift(1))) & # (dataframe['ema_fast'] > dataframe['ha_close']) & # ((dataframe['ha_close'] * self.sell_bbmiddle_close.value) > dataframe['bb_middleband']) & # (dataframe['volume'] > 0) # , # 'sell' # ] = 1 return dataframe def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, rate: float, time_in_force: str, sell_reason: str, current_time: datetime, **kwargs) -> bool: trade.sell_reason = sell_reason + "_" + trade.buy_tag return True