├── .gitattributes ├── NotAnotherSMAOffsetStrategy.py ├── NotAnotherSMAOffSetStrategy_V2.py └── RalliV1.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /NotAnotherSMAOffsetStrategy.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | import talib.abstract as ta 9 | import numpy as np 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | import datetime 12 | from technical.util import resample_to_interval, resampled_merge 13 | from datetime import datetime, timedelta 14 | from freqtrade.persistence import Trade 15 | from freqtrade.strategy import stoploss_from_open, merge_informative_pair, DecimalParameter, IntParameter, CategoricalParameter 16 | import technical.indicators as ftt 17 | 18 | # @Rallipanos 19 | 20 | # Buy hyperspace params: 21 | buy_params = { 22 | "base_nb_candles_buy": 14, 23 | "ewo_high": 2.327, 24 | "ewo_high_2": -2.327, 25 | "ewo_low": -20.988, 26 | "low_offset": 0.975, 27 | "low_offset_2": 0.955, 28 | "rsi_buy": 69 29 | } 30 | 31 | # Sell hyperspace params: 32 | sell_params = { 33 | "base_nb_candles_sell": 24, 34 | "high_offset": 0.991, 35 | "high_offset_2": 0.997 36 | } 37 | 38 | def EWO(dataframe, ema_length=5, ema2_length=35): 39 | df = dataframe.copy() 40 | ema1 = ta.EMA(df, timeperiod=ema_length) 41 | ema2 = ta.EMA(df, timeperiod=ema2_length) 42 | emadif = (ema1 - ema2) / df['low'] * 100 43 | return emadif 44 | 45 | 46 | 47 | class NotAnotherSMAOffsetStrategy(IStrategy): 48 | INTERFACE_VERSION = 2 49 | 50 | # ROI table: 51 | minimal_roi = { 52 | "0": 0.215, 53 | "40": 0.032, 54 | "87": 0.016, 55 | "201": 0 56 | } 57 | 58 | # Stoploss: 59 | stoploss = -0.35 60 | 61 | # SMAOffset 62 | base_nb_candles_buy = IntParameter( 63 | 5, 80, default=buy_params['base_nb_candles_buy'], space='buy', optimize=True) 64 | base_nb_candles_sell = IntParameter( 65 | 5, 80, default=sell_params['base_nb_candles_sell'], space='sell', optimize=True) 66 | low_offset = DecimalParameter( 67 | 0.9, 0.99, default=buy_params['low_offset'], space='buy', optimize=True) 68 | low_offset_2 = DecimalParameter( 69 | 0.9, 0.99, default=buy_params['low_offset_2'], space='buy', optimize=True) 70 | high_offset = DecimalParameter( 71 | 0.95, 1.1, default=sell_params['high_offset'], space='sell', optimize=True) 72 | high_offset_2 = DecimalParameter( 73 | 0.99, 1.5, default=sell_params['high_offset_2'], space='sell', optimize=True) 74 | 75 | # Protection 76 | fast_ewo = 50 77 | slow_ewo = 200 78 | ewo_low = DecimalParameter(-20.0, -8.0, 79 | default=buy_params['ewo_low'], space='buy', optimize=True) 80 | ewo_high = DecimalParameter( 81 | 2.0, 12.0, default=buy_params['ewo_high'], space='buy', optimize=True) 82 | 83 | ewo_high_2 = DecimalParameter( 84 | -6.0, 12.0, default=buy_params['ewo_high_2'], space='buy', optimize=True) 85 | 86 | rsi_buy = IntParameter(30, 70, default=buy_params['rsi_buy'], space='buy', optimize=True) 87 | 88 | # Trailing stop: 89 | trailing_stop = True 90 | trailing_stop_positive = 0.005 91 | trailing_stop_positive_offset = 0.03 92 | trailing_only_offset_is_reached = True 93 | 94 | # Sell signal 95 | use_sell_signal = True 96 | sell_profit_only = False 97 | sell_profit_offset = 0.01 98 | ignore_roi_if_buy_signal = False 99 | 100 | ## Optional order time in force. 101 | order_time_in_force = { 102 | 'buy': 'gtc', 103 | 'sell': 'ioc' 104 | } 105 | 106 | # Optimal timeframe for the strategy 107 | timeframe = '5m' 108 | inf_1h = '1h' 109 | 110 | process_only_new_candles = True 111 | startup_candle_count = 200 112 | 113 | plot_config = { 114 | 'main_plot': { 115 | 'ma_buy': {'color': 'orange'}, 116 | 'ma_sell': {'color': 'orange'}, 117 | }, 118 | } 119 | def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, 120 | rate: float, time_in_force: str, sell_reason: str, 121 | current_time: datetime, **kwargs) -> bool: 122 | 123 | dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) 124 | last_candle = dataframe.iloc[-1] 125 | 126 | 127 | if (last_candle is not None): 128 | if (sell_reason in ['sell_signal']): 129 | if (last_candle['hma_50']*1.149 > last_candle['ema_100']) and (last_candle['close'] < last_candle['ema_100']*0.951): #*1.2 130 | return False 131 | return True 132 | 133 | 134 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 135 | 136 | # Calculate all ma_buy values 137 | for val in self.base_nb_candles_buy.range: 138 | dataframe[f'ma_buy_{val}'] = ta.EMA(dataframe, timeperiod=val) 139 | 140 | # Calculate all ma_sell values 141 | for val in self.base_nb_candles_sell.range: 142 | dataframe[f'ma_sell_{val}'] = ta.EMA(dataframe, timeperiod=val) 143 | 144 | dataframe['hma_50'] = qtpylib.hull_moving_average(dataframe['close'], window=50) 145 | dataframe['ema_100'] = ta.EMA(dataframe, timeperiod=100) 146 | 147 | dataframe['sma_9'] = ta.SMA(dataframe, timeperiod=9) 148 | # Elliot 149 | dataframe['EWO'] = EWO(dataframe, self.fast_ewo, self.slow_ewo) 150 | 151 | # RSI 152 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 153 | dataframe['rsi_fast'] = ta.RSI(dataframe, timeperiod=4) 154 | dataframe['rsi_slow'] = ta.RSI(dataframe, timeperiod=20) 155 | 156 | 157 | return dataframe 158 | 159 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 160 | 161 | dataframe.loc[ 162 | ( 163 | (dataframe['rsi_fast'] <35)& 164 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 165 | (dataframe['EWO'] > self.ewo_high.value) & 166 | (dataframe['rsi'] < self.rsi_buy.value) & 167 | (dataframe['volume'] > 0)& 168 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 169 | ), 170 | ['buy', 'buy_tag']] = (1, 'ewo1') 171 | 172 | 173 | dataframe.loc[ 174 | ( 175 | (dataframe['rsi_fast'] <35)& 176 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset_2.value)) & 177 | (dataframe['EWO'] > self.ewo_high_2.value) & 178 | (dataframe['rsi'] < self.rsi_buy.value) & 179 | (dataframe['volume'] > 0)& 180 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value))& 181 | (dataframe['rsi']<25) 182 | ), 183 | ['buy', 'buy_tag']] = (1, 'ewo2') 184 | 185 | 186 | dataframe.loc[ 187 | ( 188 | (dataframe['rsi_fast'] < 35)& 189 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 190 | (dataframe['EWO'] < self.ewo_low.value) & 191 | (dataframe['volume'] > 0)& 192 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 193 | ), 194 | ['buy', 'buy_tag']] = (1, 'ewolow') 195 | 196 | return dataframe 197 | 198 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 199 | conditions = [] 200 | 201 | conditions.append( 202 | ( (dataframe['close']>dataframe['sma_9'])& 203 | (dataframe['close'] > (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset_2.value)) & 204 | (dataframe['rsi']>50)& 205 | (dataframe['volume'] > 0)& 206 | (dataframe['rsi_fast']>dataframe['rsi_slow']) 207 | ) 208 | | 209 | ( 210 | (dataframe['close'] (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) & 212 | (dataframe['volume'] > 0)& 213 | (dataframe['rsi_fast']>dataframe['rsi_slow']) 214 | ) 215 | 216 | ) 217 | 218 | if conditions: 219 | dataframe.loc[ 220 | reduce(lambda x, y: x | y, conditions), 221 | 'sell' 222 | ]=1 223 | 224 | return dataframe 225 | -------------------------------------------------------------------------------- /NotAnotherSMAOffSetStrategy_V2.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | import talib.abstract as ta 9 | import numpy as np 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | import datetime 12 | from technical.util import resample_to_interval, resampled_merge 13 | from datetime import datetime, timedelta 14 | from freqtrade.persistence import Trade 15 | from freqtrade.strategy import stoploss_from_open, merge_informative_pair, DecimalParameter, IntParameter, CategoricalParameter 16 | import technical.indicators as ftt 17 | 18 | # @Rallipanos 19 | 20 | 21 | 22 | ######################################################################################################################### 23 | ## Do not run backtesting over servicebreaks. It gives bad result. Test timeranges that does not have servicebreaks!!!! 24 | ######################################################################################################################### 25 | 26 | 27 | # Buy hyperspace params: 28 | buy_params = { 29 | "base_nb_candles_buy": 14, 30 | "ewo_high": 2.327, 31 | "ewo_high_2": -2.327, 32 | "ewo_low": -20.988, 33 | "low_offset": 0.975, 34 | "low_offset_2": 0.955, 35 | "rsi_buy": 69 36 | } 37 | 38 | # Sell hyperspace params: 39 | sell_params = { 40 | "base_nb_candles_sell": 24, 41 | "high_offset": 0.998, 42 | "high_offset_2": 1 43 | } 44 | 45 | def EWO(dataframe, ema_length=5, ema2_length=35): 46 | df = dataframe.copy() 47 | ema1 = ta.EMA(df, timeperiod=ema_length) 48 | ema2 = ta.EMA(df, timeperiod=ema2_length) 49 | emadif = (ema1 - ema2) / df['low'] * 100 50 | return emadif 51 | 52 | 53 | class NotAnotherSMAOffSetStrategy_V2(IStrategy): 54 | INTERFACE_VERSION = 2 55 | 56 | # ROI table: 57 | minimal_roi = { 58 | "0": 0.215, 59 | "40": 0.032, 60 | "87": 0.016, 61 | "201": 0 62 | } 63 | 64 | # Stoploss: 65 | stoploss = -0.35 66 | 67 | # SMAOffset 68 | base_nb_candles_buy = IntParameter( 69 | 5, 80, default=buy_params['base_nb_candles_buy'], space='buy', optimize=True) 70 | base_nb_candles_sell = IntParameter( 71 | 5, 80, default=sell_params['base_nb_candles_sell'], space='sell', optimize=True) 72 | low_offset = DecimalParameter( 73 | 0.9, 0.99, default=buy_params['low_offset'], space='buy', optimize=True) 74 | low_offset_2 = DecimalParameter( 75 | 0.9, 0.99, default=buy_params['low_offset_2'], space='buy', optimize=True) 76 | high_offset = DecimalParameter( 77 | 0.95, 1.1, default=sell_params['high_offset'], space='sell', optimize=True) 78 | high_offset_2 = DecimalParameter( 79 | 0.99, 1.5, default=sell_params['high_offset_2'], space='sell', optimize=True) 80 | 81 | # Protection 82 | fast_ewo = 50 83 | slow_ewo = 200 84 | ewo_low = DecimalParameter(-20.0, -8.0, 85 | default=buy_params['ewo_low'], space='buy', optimize=True) 86 | ewo_high = DecimalParameter( 87 | 2.0, 12.0, default=buy_params['ewo_high'], space='buy', optimize=True) 88 | 89 | ewo_high_2 = DecimalParameter( 90 | -6.0, 12.0, default=buy_params['ewo_high_2'], space='buy', optimize=True) 91 | 92 | rsi_buy = IntParameter(30, 70, default=buy_params['rsi_buy'], space='buy', optimize=True) 93 | 94 | # Trailing stop: 95 | trailing_stop = True 96 | trailing_stop_positive = 0.005 97 | trailing_stop_positive_offset = 0.025 98 | trailing_only_offset_is_reached = True 99 | 100 | # Sell signal 101 | use_sell_signal = True 102 | sell_profit_only = False 103 | sell_profit_offset = 0.01 104 | ignore_roi_if_buy_signal = False 105 | 106 | ## Optional order time in force. 107 | order_time_in_force = { 108 | 'buy': 'gtc', 109 | 'sell': 'gtc' 110 | } 111 | 112 | # Optimal timeframe for the strategy 113 | timeframe = '5m' 114 | inf_1h = '1h' 115 | 116 | process_only_new_candles = True 117 | startup_candle_count = 200 118 | 119 | plot_config = { 120 | 'main_plot': { 121 | 'ma_buy': {'color': 'orange'}, 122 | 'ma_sell': {'color': 'orange'}, 123 | }, 124 | } 125 | def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, 126 | rate: float, time_in_force: str, sell_reason: str, 127 | current_time: datetime, **kwargs) -> bool: 128 | 129 | dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) 130 | last_candle = dataframe.iloc[-1] 131 | 132 | 133 | if (last_candle is not None): 134 | if (sell_reason in ['sell_signal']): 135 | if (last_candle['hma_50'] > last_candle['ema_100']) and (last_candle['rsi'] < 45): #*1.2 136 | return False 137 | 138 | if (last_candle is not None): 139 | if (sell_reason in ['sell_signal']): 140 | if (last_candle['hma_50']*1.149 > last_candle['ema_100']) and (last_candle['close'] < last_candle['ema_100']*0.951): #*1.2 141 | return False 142 | 143 | return True 144 | 145 | 146 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 147 | 148 | # Calculate all ma_buy values 149 | for val in self.base_nb_candles_buy.range: 150 | dataframe[f'ma_buy_{val}'] = ta.EMA(dataframe, timeperiod=val) 151 | 152 | # Calculate all ma_sell values 153 | for val in self.base_nb_candles_sell.range: 154 | dataframe[f'ma_sell_{val}'] = ta.EMA(dataframe, timeperiod=val) 155 | 156 | dataframe['hma_50'] = qtpylib.hull_moving_average(dataframe['close'], window=50) 157 | dataframe['ema_100'] = ta.EMA(dataframe, timeperiod=100) 158 | 159 | dataframe['sma_9'] = ta.SMA(dataframe, timeperiod=9) 160 | # Elliot 161 | dataframe['EWO'] = EWO(dataframe, self.fast_ewo, self.slow_ewo) 162 | 163 | # RSI 164 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 165 | dataframe['rsi_fast'] = ta.RSI(dataframe, timeperiod=4) 166 | dataframe['rsi_slow'] = ta.RSI(dataframe, timeperiod=20) 167 | dataframe['vol_7_max'] = dataframe['volume'].rolling(window=20).max() 168 | dataframe['vol_14_max'] = dataframe['volume'].rolling(window=14).max() 169 | dataframe['vol_7_min'] = dataframe['volume'].rolling(window=20).min() 170 | dataframe['vol_14_min'] = dataframe['volume'].rolling(window=14).min() 171 | dataframe['roll_7'] = 100*((dataframe['volume']-dataframe['vol_7_max'])/(dataframe['vol_7_max']-dataframe['vol_7_min'])) 172 | dataframe['vol_base']=ta.SMA(dataframe['roll_7'], timeperiod=5) 173 | dataframe['vol_ma_26'] = ta.SMA(dataframe['volume'], timeperiod=26) 174 | dataframe['vol_ma_200'] = ta.SMA(dataframe['volume'], timeperiod=100) 175 | 176 | 177 | return dataframe 178 | 179 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 180 | 181 | dataframe.loc[ 182 | ( 183 | (dataframe['vol_base']>-96)& 184 | (dataframe['vol_base']<-77)& 185 | (dataframe['rsi_fast'] <35)& 186 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 187 | (dataframe['EWO'] > self.ewo_high.value) & 188 | (dataframe['rsi'] < self.rsi_buy.value) & 189 | (dataframe['volume'] > 0)& 190 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 191 | ), 192 | ['buy', 'buy_tag']] = (1, 'ewo1') 193 | 194 | dataframe.loc[ 195 | ( 196 | (dataframe['vol_base']>-96)& 197 | (dataframe['vol_base']> -20)& 198 | (dataframe['rsi_fast'] <35)& 199 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 200 | (dataframe['EWO'] > self.ewo_high.value) & 201 | (dataframe['rsi'] < self.rsi_buy.value) & 202 | (dataframe['volume'] > 0)& 203 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 204 | ), 205 | ['buy', 'buy_tag']] = (1, 'ewo3') 206 | 207 | 208 | dataframe.loc[ 209 | ( (dataframe['vol_base']>-96)& 210 | (dataframe['vol_base']<-77)& 211 | (dataframe['rsi_fast'] <35)& 212 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset_2.value)) & 213 | (dataframe['EWO'] > self.ewo_high_2.value) & 214 | (dataframe['rsi'] < self.rsi_buy.value) & 215 | (dataframe['volume'] > 0)& 216 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value))& 217 | (dataframe['rsi']<25) 218 | ), 219 | ['buy', 'buy_tag']] = (1, 'ewo2') 220 | 221 | 222 | dataframe.loc[ 223 | ( 224 | (dataframe['vol_base']>-96)& 225 | (dataframe['vol_base']<-77)& 226 | (dataframe['rsi_fast'] < 35)& 227 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 228 | (dataframe['EWO'] < self.ewo_low.value) & 229 | (dataframe['volume'] > 0)& 230 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 231 | ), 232 | ['buy', 'buy_tag']] = (1, 'ewolow') 233 | 234 | return dataframe 235 | 236 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 237 | conditions = [] 238 | 239 | conditions.append( 240 | ( (dataframe['close']>dataframe['sma_9'])& 241 | (dataframe['close'] > (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset_2.value)) & 242 | (dataframe['rsi']>50)& 243 | (dataframe['volume'] > 0)& 244 | (dataframe['rsi_fast']>dataframe['rsi_slow']) 245 | ) 246 | | 247 | ( 248 | (dataframe['close'] (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) & 250 | (dataframe['volume'] > 0)& 251 | (dataframe['rsi_fast']>dataframe['rsi_slow']) 252 | ) 253 | 254 | ) 255 | 256 | if conditions: 257 | dataframe.loc[ 258 | reduce(lambda x, y: x | y, conditions), 259 | 'sell' 260 | ]=1 261 | 262 | return dataframe 263 | -------------------------------------------------------------------------------- /RalliV1.py: -------------------------------------------------------------------------------- 1 | # --- Do not remove these libs --- 2 | # --- Do not remove these libs --- 3 | from freqtrade.strategy.interface import IStrategy 4 | from typing import Dict, List 5 | from functools import reduce 6 | from pandas import DataFrame 7 | # -------------------------------- 8 | import talib.abstract as ta 9 | import numpy as np 10 | import freqtrade.vendor.qtpylib.indicators as qtpylib 11 | import datetime 12 | from technical.util import resample_to_interval, resampled_merge 13 | from datetime import datetime, timedelta 14 | from freqtrade.persistence import Trade 15 | from freqtrade.strategy import stoploss_from_open, merge_informative_pair, DecimalParameter, IntParameter, CategoricalParameter 16 | import technical.indicators as ftt 17 | 18 | # @Rallipanos 19 | 20 | # Buy hyperspace params: 21 | buy_params = { 22 | "base_nb_candles_buy": 14, 23 | "ewo_high": 2.327, 24 | "ewo_high_2": -2.327, 25 | "ewo_low": -20.988, 26 | "low_offset": 0.975, 27 | "low_offset_2": 0.955, 28 | "rsi_buy": 60, 29 | "rsi_buy_2": 45 30 | } 31 | 32 | # Sell hyperspace params: 33 | sell_params = { 34 | "base_nb_candles_sell": 24, 35 | "high_offset": 0.991, 36 | "high_offset_2": 0.997 37 | } 38 | 39 | def EWO(dataframe, ema_length=5, ema2_length=35): 40 | df = dataframe.copy() 41 | ema1 = ta.EMA(df, timeperiod=ema_length) 42 | ema2 = ta.EMA(df, timeperiod=ema2_length) 43 | emadif = (ema1 - ema2) / df['low'] * 100 44 | return emadif 45 | 46 | 47 | 48 | class RalliV1(IStrategy): 49 | INTERFACE_VERSION = 2 50 | 51 | # ROI table: 52 | minimal_roi = { 53 | "0": 0.04, 54 | "40": 0.032, 55 | "87": 0.018, 56 | "201": 0 57 | } 58 | 59 | # Stoploss: 60 | stoploss = -0.3 61 | 62 | # SMAOffset 63 | base_nb_candles_buy = IntParameter( 64 | 5, 80, default=buy_params['base_nb_candles_buy'], space='buy', optimize=True) 65 | base_nb_candles_sell = IntParameter( 66 | 5, 80, default=sell_params['base_nb_candles_sell'], space='sell', optimize=True) 67 | low_offset = DecimalParameter( 68 | 0.9, 0.99, default=buy_params['low_offset'], space='buy', optimize=True) 69 | low_offset_2 = DecimalParameter( 70 | 0.9, 0.99, default=buy_params['low_offset_2'], space='buy', optimize=True) 71 | high_offset = DecimalParameter( 72 | 0.95, 1.1, default=sell_params['high_offset'], space='sell', optimize=True) 73 | high_offset_2 = DecimalParameter( 74 | 0.99, 1.5, default=sell_params['high_offset_2'], space='sell', optimize=True) 75 | 76 | # Protection 77 | fast_ewo = 50 78 | slow_ewo = 200 79 | ewo_low = DecimalParameter(-20.0, -8.0, 80 | default=buy_params['ewo_low'], space='buy', optimize=True) 81 | ewo_high = DecimalParameter( 82 | 2.0, 12.0, default=buy_params['ewo_high'], space='buy', optimize=True) 83 | 84 | ewo_high_2 = DecimalParameter( 85 | -6.0, 12.0, default=buy_params['ewo_high_2'], space='buy', optimize=True) 86 | 87 | rsi_buy = IntParameter(30, 70, default=buy_params['rsi_buy'], space='buy', optimize=True) 88 | rsi_buy_2 = IntParameter(30, 70, default=buy_params['rsi_buy_2'], space='buy', optimize=True) 89 | 90 | # Trailing stop: 91 | trailing_stop = False 92 | trailing_stop_positive = 0.005 93 | trailing_stop_positive_offset = 0.03 94 | trailing_only_offset_is_reached = True 95 | 96 | # Sell signal 97 | use_sell_signal = True 98 | sell_profit_only = False 99 | sell_profit_offset = 0.01 100 | ignore_roi_if_buy_signal = False 101 | 102 | ## Optional order time in force. 103 | order_time_in_force = { 104 | 'buy': 'gtc', 105 | 'sell': 'gtc' 106 | } 107 | 108 | # Optimal timeframe for the strategy 109 | timeframe = '5m' 110 | inf_1h = '1h' 111 | 112 | process_only_new_candles = True 113 | startup_candle_count = 200 114 | 115 | plot_config = { 116 | 'main_plot': { 117 | 'ma_buy': {'color': 'orange'}, 118 | 'ma_sell': {'color': 'orange'}, 119 | }, 120 | } 121 | def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, 122 | rate: float, time_in_force: str, sell_reason: str, 123 | current_time: datetime, **kwargs) -> bool: 124 | 125 | dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) 126 | last_candle = dataframe.iloc[-1] 127 | 128 | 129 | if (last_candle is not None): 130 | if (sell_reason in ['sell_signal']): 131 | if (last_candle['rsi'] < 45 ) and (last_candle['hma_50'] > last_candle['ema_100']): #*1.2 132 | return False 133 | return True 134 | 135 | use_custom_stoploss = True 136 | 137 | def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, 138 | current_profit: float, **kwargs) -> float: 139 | df, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) 140 | candle = df.iloc[-1].squeeze() 141 | 142 | if current_profit < 0.001 and current_time - timedelta(minutes=140) > trade.open_date_utc: 143 | return -0.005 144 | 145 | return 1 146 | 147 | 148 | def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 149 | 150 | # Calculate all ma_buy values 151 | for val in self.base_nb_candles_buy.range: 152 | dataframe[f'ma_buy_{val}'] = ta.EMA(dataframe, timeperiod=val) 153 | 154 | # Calculate all ma_sell values 155 | for val in self.base_nb_candles_sell.range: 156 | dataframe[f'ma_sell_{val}'] = ta.EMA(dataframe, timeperiod=val) 157 | 158 | dataframe['hma_50'] = qtpylib.hull_moving_average(dataframe['close'], window=50) 159 | dataframe['hma_9'] = qtpylib.hull_moving_average(dataframe['close'], window=9) 160 | dataframe['ema_100'] = ta.EMA(dataframe, timeperiod=100) 161 | dataframe['ema_14'] = ta.EMA(dataframe, timeperiod=14) 162 | dataframe['sma_9'] = ta.SMA(dataframe, timeperiod=9) 163 | dataframe['ema_9'] = ta.EMA(dataframe, timeperiod=9) 164 | # Elliot 165 | dataframe['EWO'] = EWO(dataframe, self.fast_ewo, self.slow_ewo) 166 | 167 | # RSI 168 | dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) 169 | dataframe['rsi_fast'] = ta.RSI(dataframe, timeperiod=4) 170 | dataframe['rsi_slow'] = ta.RSI(dataframe, timeperiod=20) 171 | 172 | 173 | return dataframe 174 | 175 | def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 176 | conditions = [] 177 | 178 | conditions.append( 179 | ( 180 | (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] < dataframe['ema_100'])& 181 | (dataframe['sma_9'] < dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'])& 182 | (dataframe['rsi_fast'] <35)& 183 | (dataframe['rsi_fast'] >4)& 184 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 185 | (dataframe['EWO'] > self.ewo_high.value) & 186 | (dataframe['rsi'] < self.rsi_buy_2.value) & 187 | (dataframe['volume'] > 0)& 188 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 189 | ) 190 | ) 191 | 192 | conditions.append( 193 | ( 194 | (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] < dataframe['ema_100'])& 195 | (dataframe['sma_9'] < dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'])& 196 | (dataframe['rsi_fast'] <35)& 197 | (dataframe['rsi_fast'] >4)& 198 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset_2.value)) & 199 | (dataframe['EWO'] > self.ewo_high_2.value) & 200 | (dataframe['rsi'] < self.rsi_buy_2.value) & 201 | (dataframe['volume'] > 0)& 202 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value))& 203 | (dataframe['rsi']<25) 204 | ) 205 | ) 206 | 207 | conditions.append( 208 | ( 209 | (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] < dataframe['ema_100'])& 210 | (dataframe['sma_9'] < dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'])& 211 | (dataframe['rsi_fast'] < 35)& 212 | (dataframe['rsi_fast'] >4)& 213 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 214 | (dataframe['EWO'] < self.ewo_low.value) & 215 | (dataframe['volume'] > 0)& 216 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 217 | ) 218 | ) 219 | 220 | 221 | conditions.append( 222 | ( 223 | (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] > dataframe['ema_100'])& 224 | (dataframe['rsi_fast'] <35)& 225 | (dataframe['rsi_fast'] >4)& 226 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 227 | (dataframe['EWO'] > self.ewo_high.value) & 228 | (dataframe['rsi'] < self.rsi_buy.value) & 229 | (dataframe['volume'] > 0)& 230 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 231 | ) 232 | ) 233 | 234 | conditions.append( 235 | ( 236 | (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] > dataframe['ema_100'])& 237 | (dataframe['rsi_fast'] <35)& 238 | (dataframe['rsi_fast'] >4)& 239 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset_2.value)) & 240 | (dataframe['EWO'] > self.ewo_high_2.value) & 241 | (dataframe['rsi'] < self.rsi_buy.value) & 242 | (dataframe['volume'] > 0)& 243 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value))& 244 | (dataframe['rsi']<25) 245 | ) 246 | ) 247 | 248 | conditions.append( 249 | ( (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] > dataframe['ema_100'])& 250 | (dataframe['rsi_fast'] < 35)& 251 | (dataframe['rsi_fast'] >4)& 252 | (dataframe['close'] < (dataframe[f'ma_buy_{self.base_nb_candles_buy.value}'] * self.low_offset.value)) & 253 | (dataframe['EWO'] < self.ewo_low.value) & 254 | (dataframe['volume'] > 0)& 255 | (dataframe['close'] < (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) 256 | ) 257 | ) 258 | if conditions: 259 | dataframe.loc[ 260 | reduce(lambda x, y: x | y, conditions), 261 | 'buy' 262 | ]=1 263 | 264 | return dataframe 265 | 266 | def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: 267 | conditions = [] 268 | 269 | conditions.append( 270 | ( (dataframe['hma_50']>dataframe['ema_100'])& 271 | (dataframe['close']>dataframe['sma_9'])& 272 | (dataframe['close'] > (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset_2.value)) & 273 | (dataframe['volume'] > 0)& 274 | (dataframe['rsi_fast']>dataframe['rsi_slow']) 275 | ) 276 | | 277 | ( 278 | (dataframe['close'] (dataframe[f'ma_sell_{self.base_nb_candles_sell.value}'] * self.high_offset.value)) & 280 | (dataframe['volume'] > 0)& 281 | (dataframe['rsi_fast']>dataframe['rsi_slow']) 282 | ) 283 | 284 | ) 285 | 286 | if conditions: 287 | dataframe.loc[ 288 | reduce(lambda x, y: x | y, conditions), 289 | 'sell' 290 | ]=1 291 | 292 | return dataframe 293 | --------------------------------------------------------------------------------